From 2ec11a5616a7884e367fb46eee82df6647ce6bc4 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Thu, 21 May 2020 00:11:14 +0800 Subject: [PATCH] make WSGIRequestHandler can use an easy way to replace the ServerHandler --- Doc/library/wsgiref.rst | 8 ++++++++ Lib/test/test_wsgiref.py | 18 ++++++++++++++++++ Lib/wsgiref/simple_server.py | 10 ++++++++-- .../2020-05-21-00-18-03.bpo-40700.o88Tsp.rst | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-21-00-18-03.bpo-40700.o88Tsp.rst diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 1e30aa4a898..59ab7192fe5 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -347,6 +347,14 @@ request. (E.g., using the :func:`shift_path_info` function from :func:`make_server` function. Some possibly relevant methods for overriding in subclasses: + :class:`WSGIRequestHandler` has the following class variables: + + .. attribute:: server_handler + + .. versionadded:: 3.9 + + The handler class to handle the request. This value should be the subclass + :class:`wsgiref.handlers.BaseHandler` .. method:: WSGIRequestHandler.get_environ() diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 4bf5d39e619..4710ecc250e 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -46,6 +46,9 @@ class MockHandler(WSGIRequestHandler): def finish(self): pass +class MockExceptionHandler(MockHandler): + server_handler = dict + def hello_app(environ,start_response): start_response("200 OK", [ @@ -80,6 +83,18 @@ def run_amock(app=hello_app, data=b"GET / HTTP/1.0\n\n"): return out.getvalue(), err.getvalue() +def run_amock_handler_with_incorrect_server_handler(app=hello_app, data=b"GET / HTTP/1.0\n\n"): + server = make_server("", 80, app, MockServer, MockExceptionHandler) + inp = BufferedReader(BytesIO(data)) + out = BytesIO() + olderr = sys.stderr + err = sys.stderr = StringIO() + + try: + server.finish_request((inp, out), ("127.0.0.1",8888)) + finally: + sys.stderr = olderr + def compare_generic_iter(make_it,match): """Utility to compare a generic 2.1/2.2+ iterator with an iterable @@ -131,6 +146,9 @@ class IntegrationTests(TestCase): "\r\n" "Hello, world!").encode("iso-8859-1") ) + def test_run_with_incorrect_server_handler(self): + with self.assertRaises(ValueError): + run_amock_handler_with_incorrect_server_handler() def test_plain_hello(self): out, err = run_amock() diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py index 93d01a863ad..884917d9951 100644 --- a/Lib/wsgiref/simple_server.py +++ b/Lib/wsgiref/simple_server.py @@ -13,7 +13,7 @@ module. See also the BaseHTTPServer module docs for other API information. from http.server import BaseHTTPRequestHandler, HTTPServer import sys import urllib.parse -from wsgiref.handlers import SimpleHandler +from wsgiref.handlers import BaseHandler, SimpleHandler from platform import python_implementation __version__ = "0.2" @@ -71,6 +71,12 @@ class WSGIServer(HTTPServer): class WSGIRequestHandler(BaseHTTPRequestHandler): server_version = "WSGIServer/" + __version__ + server_handler = ServerHandler + + def __init__(self, *args, **kwargs): + if not issubclass(self.server_handler, BaseHandler): + raise ValueError("the server_handler should be the subclass of BaseHandler") + super().__init__(*args, **kwargs) def get_environ(self): env = self.server.base_environ.copy() @@ -126,7 +132,7 @@ class WSGIRequestHandler(BaseHTTPRequestHandler): if not self.parse_request(): # An error code has been sent, just exit return - handler = ServerHandler( + handler = self.server_handler( self.rfile, self.wfile, self.get_stderr(), self.get_environ(), multithread=False, ) diff --git a/Misc/NEWS.d/next/Library/2020-05-21-00-18-03.bpo-40700.o88Tsp.rst b/Misc/NEWS.d/next/Library/2020-05-21-00-18-03.bpo-40700.o88Tsp.rst new file mode 100644 index 00000000000..0176a22264c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-21-00-18-03.bpo-40700.o88Tsp.rst @@ -0,0 +1 @@ +make WSGIRequestHandler can use an easy way to replace the ServerHandler