From c9df3d807f7134f58f4a84dc8b80e9dc98c62f3a Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 13:19:42 -0700 Subject: Imported Upstream version 1.10.4 --- dummyserver/handlers.py | 75 +++++++++++++++++++++++++++++++++++++------------ dummyserver/server.py | 19 +++++++++++-- dummyserver/testcase.py | 12 ++++---- 3 files changed, 80 insertions(+), 26 deletions(-) (limited to 'dummyserver') diff --git a/dummyserver/handlers.py b/dummyserver/handlers.py index 72faa1a..53fbe4a 100644 --- a/dummyserver/handlers.py +++ b/dummyserver/handlers.py @@ -9,7 +9,7 @@ import time import zlib from io import BytesIO -from tornado.wsgi import HTTPRequest +from tornado.web import RequestHandler try: from urllib.parse import urlsplit @@ -21,23 +21,34 @@ log = logging.getLogger(__name__) class Response(object): def __init__(self, body='', status='200 OK', headers=None): - if not isinstance(body, bytes): - body = body.encode('utf8') - self.body = body self.status = status self.headers = headers or [("Content-type", "text/plain")] - def __call__(self, environ, start_response): - start_response(self.status, self.headers) - return [self.body] + def __call__(self, request_handler): + status, reason = self.status.split(' ', 1) + request_handler.set_status(int(status), reason) + for header,value in self.headers: + request_handler.add_header(header,value) + + # chunked + if isinstance(self.body, list): + for item in self.body: + if not isinstance(item, bytes): + item = item.encode('utf8') + request_handler.write(item) + request_handler.flush() + else: + body = self.body + if not isinstance(body, bytes): + body = body.encode('utf8') + request_handler.write(body) -class WSGIHandler(object): - pass +RETRY_TEST_NAMES = collections.defaultdict(int) -class TestingApp(WSGIHandler): +class TestingApp(RequestHandler): """ Simple app that performs various operations, useful for testing an HTTP library. @@ -46,10 +57,25 @@ class TestingApp(WSGIHandler): it exists. Status code 200 indicates success, 400 indicates failure. Each method has its own conditions for success/failure. """ - def __call__(self, environ, start_response): - """ Call the correct method in this class based on the incoming URI """ - req = HTTPRequest(environ) + def get(self): + """ Handle GET requests """ + self._call_method() + + def post(self): + """ Handle POST requests """ + self._call_method() + def put(self): + """ Handle PUT requests """ + self._call_method() + + def options(self): + """ Handle OPTIONS requests """ + self._call_method() + + def _call_method(self): + """ Call the correct method in this class based on the incoming URI """ + req = self.request req.params = {} for k, v in req.arguments.items(): req.params[k] = next(iter(v)) @@ -60,13 +86,14 @@ class TestingApp(WSGIHandler): target = path[1:].replace('/', '_') method = getattr(self, target, self.index) + resp = method(req) if dict(resp.headers).get('Connection') == 'close': # FIXME: Can we kill the connection somehow? pass - return resp(environ, start_response) + resp(self) def index(self, _request): "Render simple message" @@ -184,15 +211,27 @@ class TestingApp(WSGIHandler): return Response("test-name header not set", status="400 Bad Request") - if not hasattr(self, 'retry_test_names'): - self.retry_test_names = collections.defaultdict(int) - self.retry_test_names[test_name] += 1 + RETRY_TEST_NAMES[test_name] += 1 - if self.retry_test_names[test_name] >= 2: + if RETRY_TEST_NAMES[test_name] >= 2: return Response("Retry successful!") else: return Response("need to keep retrying!", status="418 I'm A Teapot") + def chunked(self, request): + return Response(['123'] * 4) + + def chunked_gzip(self, request): + chunks = [] + compressor = zlib.compressobj(6, zlib.DEFLATED, 16 + zlib.MAX_WBITS) + + for uncompressed in [b'123'] * 4: + chunks.append(compressor.compress(uncompressed)) + + chunks.append(compressor.flush()) + + return Response(chunks, headers=[('Content-Encoding', 'gzip')]) + def shutdown(self, request): sys.exit() diff --git a/dummyserver/server.py b/dummyserver/server.py index 6ee9a5d..63124d3 100755 --- a/dummyserver/server.py +++ b/dummyserver/server.py @@ -13,9 +13,11 @@ import string import sys import threading import socket +import warnings + +from urllib3.exceptions import HTTPWarning from tornado.platform.auto import set_close_exec -import tornado.wsgi import tornado.httpserver import tornado.ioloop import tornado.web @@ -40,6 +42,11 @@ NO_SAN_CA = os.path.join(CERTS_PATH, 'cacert.no_san.pem') # Different types of servers we have: +class NoIPv6Warning(HTTPWarning): + "IPv6 is not available" + pass + + class SocketServerThread(threading.Thread): """ :param socket_handler: Callable which receives a socket argument for one @@ -50,13 +57,19 @@ class SocketServerThread(threading.Thread): def __init__(self, socket_handler, host='localhost', port=8081, ready_event=None): threading.Thread.__init__(self) + self.daemon = True self.socket_handler = socket_handler self.host = host self.ready_event = ready_event def _start_server(self): - sock = socket.socket(socket.AF_INET6) + if socket.has_ipv6: + sock = socket.socket(socket.AF_INET6) + else: + warnings.warn("No IPv6 support. Falling back to IPv4.", + NoIPv6Warning) + sock = socket.socket(socket.AF_INET) if sys.platform != 'win32': sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.host, 0)) @@ -192,7 +205,7 @@ if __name__ == '__main__': host = '127.0.0.1' io_loop = tornado.ioloop.IOLoop() - app = tornado.wsgi.WSGIContainer(TestingApp()) + app = tornado.web.Application([(r".*", TestingApp)]) server, port = run_tornado_app(app, io_loop, None, 'http', host) server_thread = run_loop_in_thread(io_loop) diff --git a/dummyserver/testcase.py b/dummyserver/testcase.py index 335b2f2..67e62cf 100644 --- a/dummyserver/testcase.py +++ b/dummyserver/testcase.py @@ -2,7 +2,7 @@ import unittest import socket import threading from nose.plugins.skip import SkipTest -from tornado import ioloop, web, wsgi +from tornado import ioloop, web from dummyserver.server import ( SocketServerThread, @@ -30,7 +30,9 @@ class SocketDummyServerTestCase(unittest.TestCase): ready_event=ready_event, host=cls.host) cls.server_thread.start() - ready_event.wait() + ready_event.wait(5) + if not ready_event.is_set(): + raise Exception("most likely failed to start server") cls.port = cls.server_thread.port @classmethod @@ -55,7 +57,7 @@ class HTTPDummyServerTestCase(unittest.TestCase): @classmethod def _start_server(cls): cls.io_loop = ioloop.IOLoop() - app = wsgi.WSGIContainer(TestingApp()) + app = web.Application([(r".*", TestingApp)]) cls.server, cls.port = run_tornado_app(app, cls.io_loop, cls.certs, cls.scheme, cls.host) cls.server_thread = run_loop_in_thread(cls.io_loop) @@ -97,11 +99,11 @@ class HTTPDummyProxyTestCase(unittest.TestCase): def setUpClass(cls): cls.io_loop = ioloop.IOLoop() - app = wsgi.WSGIContainer(TestingApp()) + app = web.Application([(r'.*', TestingApp)]) cls.http_server, cls.http_port = run_tornado_app( app, cls.io_loop, None, 'http', cls.http_host) - app = wsgi.WSGIContainer(TestingApp()) + app = web.Application([(r'.*', TestingApp)]) cls.https_server, cls.https_port = run_tornado_app( app, cls.io_loop, cls.https_certs, 'https', cls.http_host) -- cgit v1.2.3