aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/tests/util/httpd.py
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/tests/util/httpd.py')
-rw-r--r--sources/pyside2/tests/util/httpd.py177
1 files changed, 177 insertions, 0 deletions
diff --git a/sources/pyside2/tests/util/httpd.py b/sources/pyside2/tests/util/httpd.py
new file mode 100644
index 000000000..8214cf033
--- /dev/null
+++ b/sources/pyside2/tests/util/httpd.py
@@ -0,0 +1,177 @@
+#############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of PySide2.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import threading
+import select
+import random
+import py3kcompat as py3k
+
+if py3k.IS_PY3K:
+ import socketserver as SocketServer
+ import http.server as BaseHTTPServer
+else:
+ import SocketServer
+ import BaseHTTPServer
+
+class TestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ DATA = "PySide Server"
+ allow_reuse_address = True
+
+ def do_GET(self):
+ self.send_head()
+ self.wfile.write(TestHandler.DATA)
+
+ def do_HEAD(self):
+ self.send_head()
+
+ def send_head(self):
+ self.send_response(200)
+ self.send_header("Content-type", "text/plain")
+ self.send_header("Content-Length", str(len(TestHandler.DATA)))
+ self.end_headers()
+
+class TestSecureHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ DATA = "PySide"
+ allow_reuse_address = True
+
+ def do_GET(self):
+ self.send_head()
+ self.wfile.write(py3k.b(TestHandler.DATA))
+
+ def do_HEAD(self):
+ self.send_head()
+
+ def send_head(self):
+ try:
+ handler = self.marshall_handler()
+ handler.do_request(self)
+ except:
+ self.send_response(401)
+ self.send_header("WWW-Authenticate", "Basic realm='Secure Area'")
+ self.send_header("Content-type", "text/plain")
+ self.send_header("Content-Length", str(len(TestHandler.DATA)))
+ self.end_headers()
+
+# Workaround for the missing shutdown method in python2.5
+class CompatTCPServer(SocketServer.TCPServer):
+ def __init__(self, server_address, RequestHandlerClass):
+ SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
+
+ self.isPy25 = sys.version_info[0] == 2 and sys.version_info[1] == 5
+ if self.isPy25:
+ self.__is_shut_down = threading.Event()
+ self.__serving = False
+
+ def serve_forever(self, poll_interval=0.5):
+ """Handle one request at a time until shutdown.
+
+ Polls for shutdown every poll_interval seconds. Ignores
+ self.timeout. If you need to do periodic tasks, do them in
+ another thread.
+ """
+ if self.isPy25:
+ self.__serving = True
+ self.__is_shut_down.clear()
+ while self.__serving:
+ # XXX: Consider using another file descriptor or
+ # connecting to the socket to wake this up instead of
+ # polling. Polling reduces our responsiveness to a
+ # shutdown request and wastes cpu at all other times.
+ r, w, e = select.select([self], [], [], poll_interval)
+ if r:
+ self.py25_handle_request_noblock()
+ self.__is_shut_down.set()
+ else:
+ SocketServer.TCPServer.serve_forever(self, poll_interval)
+
+ def py25_handle_request_noblock(self):
+ """Handle one request, without blocking.
+
+ I assume that select.select has returned that the socket is
+ readable before this function was called, so there should be
+ no risk of blocking in get_request().
+ """
+ if self.isPy25:
+ try:
+ request, client_address = self.get_request()
+ except socket.error:
+ return
+ if self.verify_request(request, client_address):
+ try:
+ self.process_request(request, client_address)
+ except:
+ self.handle_error(request, client_address)
+ self.close_request(request)
+
+ def shutdown(self):
+ """Stops the serve_forever loop.
+
+ Blocks until the loop has finished. This must be called while
+ serve_forever() is running in another thread, or it will
+ deadlock.
+ """
+ if self.isPy25:
+ self.__serving = False
+ if not self.__is_shut_down:
+ self.__is_shut_down.wait()
+ else:
+ SocketServer.TCPServer.shutdown(self)
+
+
+class TestServer(threading.Thread):
+
+ def __init__(self, secure=False):
+ threading.Thread.__init__(self)
+
+ self._port = int(os.getenv("PYSIDE_TESTSERVER_PORT") or 12321)
+ self.keep_running = True
+
+ if secure:
+ handle = TestSecureHandler
+ else:
+ handle = TestHandler
+
+ while True:
+ try:
+ self.httpd = CompatTCPServer(('' , self._port), handle)
+ break
+ except:
+ self._port = self._port + random.randint(1, 100)
+
+ def port(self):
+ return self._port
+
+ def run(self):
+ self.httpd.serve_forever()
+
+ def shutdown(self):
+ self.httpd.shutdown()
+ self.join()
+