Add scheme to the request
This commit is contained in:
@@ -123,7 +123,8 @@ class Microdot(BaseMicrodot):
|
|||||||
headers,
|
headers,
|
||||||
body=body,
|
body=body,
|
||||||
stream=stream,
|
stream=stream,
|
||||||
sock=(receive, send))
|
sock=(receive, send),
|
||||||
|
scheme=scope.get('scheme'))
|
||||||
req.asgi_scope = scope
|
req.asgi_scope = scope
|
||||||
|
|
||||||
res = await self.dispatch_request(req)
|
res = await self.dispatch_request(req)
|
||||||
|
|||||||
@@ -321,14 +321,17 @@ class Request:
|
|||||||
|
|
||||||
def __init__(self, app, client_addr, method, url, http_version, headers,
|
def __init__(self, app, client_addr, method, url, http_version, headers,
|
||||||
body=None, stream=None, sock=None, url_prefix='',
|
body=None, stream=None, sock=None, url_prefix='',
|
||||||
subapp=None):
|
subapp=None, scheme=None):
|
||||||
#: The application instance to which this request belongs.
|
#: The application instance to which this request belongs.
|
||||||
self.app = app
|
self.app = app
|
||||||
#: The address of the client, as a tuple (host, port).
|
#: The address of the client, as a tuple (host, port).
|
||||||
self.client_addr = client_addr
|
self.client_addr = client_addr
|
||||||
#: The HTTP method of the request.
|
#: The HTTP method of the request.
|
||||||
self.method = method
|
self.method = method
|
||||||
#: The request URL, including the path and query string.
|
#: The scheme of the request, either `http` or `https`.
|
||||||
|
self.scheme = scheme or 'http'
|
||||||
|
#: The request URL, including the path and query string, but not the
|
||||||
|
#: scheme or the host, which is available in the ``Host`` header.
|
||||||
self.url = url
|
self.url = url
|
||||||
#: The URL prefix, if the endpoint comes from a mounted
|
#: The URL prefix, if the endpoint comes from a mounted
|
||||||
#: sub-application, or else ''.
|
#: sub-application, or else ''.
|
||||||
@@ -379,7 +382,8 @@ class Request:
|
|||||||
self.after_request_handlers = []
|
self.after_request_handlers = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def create(app, client_reader, client_writer, client_addr):
|
async def create(app, client_reader, client_writer, client_addr,
|
||||||
|
scheme=None):
|
||||||
"""Create a request object.
|
"""Create a request object.
|
||||||
|
|
||||||
:param app: The Microdot application instance.
|
:param app: The Microdot application instance.
|
||||||
@@ -388,6 +392,7 @@ class Request:
|
|||||||
:param client_writer: An output stream where the response data can be
|
:param client_writer: An output stream where the response data can be
|
||||||
written.
|
written.
|
||||||
:param client_addr: The address of the client, as a tuple.
|
:param client_addr: The address of the client, as a tuple.
|
||||||
|
:param scheme: The scheme of the request, either 'http' or 'https'.
|
||||||
|
|
||||||
This method is a coroutine. It returns a newly created ``Request``
|
This method is a coroutine. It returns a newly created ``Request``
|
||||||
object.
|
object.
|
||||||
@@ -424,7 +429,7 @@ class Request:
|
|||||||
|
|
||||||
return Request(app, client_addr, method, url, http_version, headers,
|
return Request(app, client_addr, method, url, http_version, headers,
|
||||||
body=body, stream=stream,
|
body=body, stream=stream,
|
||||||
sock=(client_reader, client_writer))
|
sock=(client_reader, client_writer), scheme=scheme)
|
||||||
|
|
||||||
def _parse_urlencoded(self, urlencoded):
|
def _parse_urlencoded(self, urlencoded):
|
||||||
data = MultiDict()
|
data = MultiDict()
|
||||||
@@ -949,6 +954,7 @@ class Microdot:
|
|||||||
self.after_error_request_handlers = []
|
self.after_error_request_handlers = []
|
||||||
self.error_handlers = {}
|
self.error_handlers = {}
|
||||||
self.options_handler = self.default_options_handler
|
self.options_handler = self.default_options_handler
|
||||||
|
self.ssl = False
|
||||||
self.debug = False
|
self.debug = False
|
||||||
self.server = None
|
self.server = None
|
||||||
|
|
||||||
@@ -1242,6 +1248,7 @@ class Microdot:
|
|||||||
|
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
"""
|
"""
|
||||||
|
self.ssl = ssl
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
|
||||||
async def serve(reader, writer):
|
async def serve(reader, writer):
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ class TestClient:
|
|||||||
:param app: The Microdot application instance.
|
:param app: The Microdot application instance.
|
||||||
:param cookies: A dictionary of cookies to use when sending requests to the
|
:param cookies: A dictionary of cookies to use when sending requests to the
|
||||||
application.
|
application.
|
||||||
|
:param scheme: The scheme to use for requests, either 'http' or 'https'.
|
||||||
|
:param host: The host to use for requests.
|
||||||
|
|
||||||
The following example shows how to create a test client for an application
|
The following example shows how to create a test client for an application
|
||||||
and send a test request::
|
and send a test request::
|
||||||
@@ -137,9 +139,11 @@ class TestClient:
|
|||||||
"""
|
"""
|
||||||
__test__ = False # remove this class from pytest's test collection
|
__test__ = False # remove this class from pytest's test collection
|
||||||
|
|
||||||
def __init__(self, app, cookies=None):
|
def __init__(self, app, cookies=None, scheme=None, host=None):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.cookies = cookies or {}
|
self.cookies = cookies or {}
|
||||||
|
self.scheme = scheme
|
||||||
|
self.host = host or 'example.com:1234'
|
||||||
|
|
||||||
def _process_body(self, body, headers):
|
def _process_body(self, body, headers):
|
||||||
if body is None:
|
if body is None:
|
||||||
@@ -152,8 +156,6 @@ class TestClient:
|
|||||||
body = body.encode()
|
body = body.encode()
|
||||||
if body and 'Content-Length' not in headers:
|
if body and 'Content-Length' not in headers:
|
||||||
headers['Content-Length'] = str(len(body))
|
headers['Content-Length'] = str(len(body))
|
||||||
if 'Host' not in headers: # pragma: no branch
|
|
||||||
headers['Host'] = 'example.com:1234'
|
|
||||||
return body, headers
|
return body, headers
|
||||||
|
|
||||||
def _process_cookies(self, path, headers):
|
def _process_cookies(self, path, headers):
|
||||||
@@ -176,6 +178,8 @@ class TestClient:
|
|||||||
def _render_request(self, method, path, headers, body):
|
def _render_request(self, method, path, headers, body):
|
||||||
request_bytes = '{method} {path} HTTP/1.0\n'.format(
|
request_bytes = '{method} {path} HTTP/1.0\n'.format(
|
||||||
method=method, path=path)
|
method=method, path=path)
|
||||||
|
if 'Host' not in headers: # pragma: no branch
|
||||||
|
request_bytes += 'Host: {host}\n'.format(host=self.host)
|
||||||
for header, value in headers.items():
|
for header, value in headers.items():
|
||||||
request_bytes += '{header}: {value}\n'.format(
|
request_bytes += '{header}: {value}\n'.format(
|
||||||
header=header, value=value)
|
header=header, value=value)
|
||||||
@@ -236,7 +240,7 @@ class TestClient:
|
|||||||
writer = AsyncBytesIO(b'')
|
writer = AsyncBytesIO(b'')
|
||||||
|
|
||||||
req = await Request.create(self.app, reader, writer,
|
req = await Request.create(self.app, reader, writer,
|
||||||
('127.0.0.1', 1234))
|
('127.0.0.1', 1234), scheme=self.scheme)
|
||||||
res = await self.app.dispatch_request(req)
|
res = await self.app.dispatch_request(req)
|
||||||
if res == Response.already_handled:
|
if res == Response.already_handled:
|
||||||
return TestResponse()
|
return TestResponse()
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ class Microdot(BaseMicrodot):
|
|||||||
headers,
|
headers,
|
||||||
body=body,
|
body=body,
|
||||||
stream=stream,
|
stream=stream,
|
||||||
sock=sock)
|
sock=sock,
|
||||||
|
scheme=environ.get('wsgi.url_scheme'))
|
||||||
req.environ = environ
|
req.environ = environ
|
||||||
|
|
||||||
res = self.loop.run_until_complete(self.dispatch_request(req))
|
res = self.loop.run_until_complete(self.dispatch_request(req))
|
||||||
|
|||||||
@@ -180,6 +180,30 @@ class TestMicrodot(unittest.TestCase):
|
|||||||
'text/plain; charset=UTF-8')
|
'text/plain; charset=UTF-8')
|
||||||
self.assertEqual(res.text, method)
|
self.assertEqual(res.text, method)
|
||||||
|
|
||||||
|
def test_http_host(self):
|
||||||
|
app = Microdot()
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index(req):
|
||||||
|
return req.scheme + "://" + req.headers['Host']
|
||||||
|
|
||||||
|
client = TestClient(app, host='foo.com')
|
||||||
|
res = self._run(client.get('/'))
|
||||||
|
self.assertEqual(res.status_code, 200)
|
||||||
|
self.assertEqual(res.text, 'http://foo.com')
|
||||||
|
|
||||||
|
def test_https_host(self):
|
||||||
|
app = Microdot()
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index(req):
|
||||||
|
return req.scheme + "://" + req.headers['Host']
|
||||||
|
|
||||||
|
client = TestClient(app, scheme='https', host='foo.com')
|
||||||
|
res = self._run(client.get('/'))
|
||||||
|
self.assertEqual(res.status_code, 200)
|
||||||
|
self.assertEqual(res.text, 'https://foo.com')
|
||||||
|
|
||||||
def test_headers(self):
|
def test_headers(self):
|
||||||
app = Microdot()
|
app = Microdot()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user