environ["SERVER_PORT"] could be "None"
CoolSpring8 opened this issue · 8 comments
The benchmark appears to be broken in my test, which reports an ValueError caused by trying to convert "None" to int.
(Also reproduced in a cleanly installed Docker container. )
The error message:
=================================== FAILURES ===================================
____________ test_convert_asgi_to_wsgi[app1-a2wsgi-ASGIMiddleware] _____________
app = <a2wsgi.asgi.ASGIMiddleware object at 0x7fced147eb80>
name = 'a2wsgi-ASGIMiddleware'
@pytest.mark.parametrize(
"app, name",
[(wsgi_echo, "pure-WSGI"), (ASGIMiddleware(asgi_echo), "a2wsgi-ASGIMiddleware")],
)
def test_convert_asgi_to_wsgi(app, name):
with httpx.Client(app=app, base_url="http://testserver") as client:
start_time = time.time_ns()
for _ in range(100):
> client.post("/", data=b"hello world")
a2wsgi/benchmark.py:99:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.8/site-packages/httpx/_client.py:992: in post
return self.request(
/usr/local/lib/python3.8/site-packages/httpx/_client.py:733: in request
return self.send(
/usr/local/lib/python3.8/site-packages/httpx/_client.py:767: in send
response = self._send_handling_auth(
/usr/local/lib/python3.8/site-packages/httpx/_client.py:805: in _send_handling_auth
response = self._send_handling_redirects(
/usr/local/lib/python3.8/site-packages/httpx/_client.py:837: in _send_handling_redirects
response = self._send_single_request(request, timeout)
/usr/local/lib/python3.8/site-packages/httpx/_client.py:861: in _send_single_request
(status_code, headers, stream, ext) = transport.request(
/usr/local/lib/python3.8/site-packages/httpx/_transports/wsgi.py:113: in request
result = _skip_leading_empty_chunks(result)
/usr/local/lib/python3.8/site-packages/httpx/_transports/wsgi.py:10: in _skip_leading_empty_chunks
for chunk in body:
a2wsgi/a2wsgi/asgi.py:160: in __call__
self.app(build_scope(environ), self.asgi_receive, self.asgi_send)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
environ = {'CONTENT_LENGTH': '11', 'HTTP_ACCEPT': '*/*', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_CONNECTION': 'keep-alive', ...}
def build_scope(environ: Environ) -> Scope:
headers = [
(
each[5:].lower().replace("_", "-").encode("latin1"),
environ[each].encode("latin1"),
)
for each in environ.keys()
if each.startswith("HTTP_")
]
if environ.get("CONTENT_TYPE"):
headers.append((b"content-type", environ["CONTENT_TYPE"].encode("latin1")))
if environ.get("CONTENT_LENGTH"):
headers.append((b"content-length", environ["CONTENT_LENGTH"].encode("latin1")))
if environ.get("REMOTE_ADDR") and environ.get("REMOTE_PORT"):
client = (environ.get("REMOTE_ADDR"), int(environ.get("REMOTE_PORT")))
else:
client = None
return {
"type": "http",
"asgi": {"version": "3.0", "spec_version": "3.0"},
"http_version": environ.get("SERVER_PROTOCOL", "http/1.0").split("/")[1],
"method": environ["REQUEST_METHOD"],
"scheme": environ.get("wsgi.url_scheme", "http"),
"path": environ["PATH_INFO"].encode("latin1").decode("utf8"),
"query_string": environ["QUERY_STRING"].encode("ascii"),
"root_path": environ.get("SCRIPT_NAME", "").encode("latin1").decode("utf8"),
"client": client,
> "server": (environ["SERVER_NAME"], int(environ["SERVER_PORT"])),
"headers": headers,
}
E ValueError: invalid literal for int() with base 10: 'None'
a2wsgi/a2wsgi/asgi.py:94: ValueError
=========================== short test summary info ============================
FAILED a2wsgi/benchmark.py::test_convert_asgi_to_wsgi[app1-a2wsgi-ASGIMiddleware]
==================== 1 failed, 5 passed in 95.47s (0:01:35) ====================
After some investigation, I found out that the port
property in httpx.URL
changed its behavior in encode/httpx@c089480#diff-c9a78eb3b5f5c4fac4e5552165fbdd5320c7e3fadf9eedabcb5461393466c090L107-R110.
So a simple fix might be adding conditional statements for SERVER_PORT
and url_scheme
.
Just noticed tests were changed in e2a7bfd... So should the line in benchmark.py
also add :80
, or to change asgi.py
like in the present PR?
https://www.python.org/dev/peps/pep-3333/#environ-variables In the WSGI standard, SERVER_PORT
is a required value.
This is a problem with the old version of httpx you are using, not a2wsgi. Please upgrade the httpx version to the latest 0.16 and run the script again.
https://www.python.org/dev/peps/pep-3333/#environ-variables In the WSGI standard,
SERVER_PORT
is a required value.This is a problem with the old version of httpx you are using, not a2wsgi. Please upgrade the httpx version to the latest 0.16 and run the script again.
Sorry, it is indeed not a bug on a2wsgi side.
But I was actually using httpx 0.16.1:
$ pip3 show httpx | grep Version
Version: 0.16.1
And I could not find in which commit httpx fixed the problem you mentioned. Could you please kindly point it out?
You can see this line https://github.com/encode/httpx/blob/0.16.1/httpx/_models.py#L121. The port should be automatically completed by another library. If httpx 0.16 does not work properly in your environment, please check the version of rfc3986.
By the way, you can try the library version specified in poetry.lock. It should be able to pass all test cases.
I'm sorry, I just tried running this script. But found the same error as you. Maybe it's that after upgrading httpx some time in the past, I never tried to run it again. This is a problem with httpx. I will submit a PR for httpx to fix this error. Thanks for your feedback.
encode/httpx#1469 Done.
Awesome!