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