Open
Changes from all commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Failed to load files.
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,24 +47,28 @@ async def request_raw(method, url):
proto, dummy, host = url.split("/", 2)
path = ""

# Although we use HTTP protocol version 1.0, we still explicitly
# set the header "Connection: close", even though this should be
# default for 1.0, but some servers misbehave w/o it.
hdrs = {'Connection': "close", 'User-Agent': "compat"}
if "@" in host:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this "@" notation to specify the auth standard/used elsewhere?

An alternative would be to pass the auth info as a separate argument to this function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I'm getting this right, but the de-facto indication of whether HTTP Basic Auth is about to be used, is, adding (at least) a username in form of http://USERNAME@HOST:PORT/PATH.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was my question, whether http://USERNAME@HOST:PORT/PATH is the standard way to add a username/password.

This format is specified in the RFC for URLs: https://datatracker.ietf.org/doc/html/rfc1738

So, let's keep this as you have it.

# split off potential login creds from host
auth, host = host.split("@", 1)
from binascii import b2a_base64
#usr, pwd = auth.split(":", 1)
hdrs['Authorization'] = "Basic " + b2a_base64(auth).decode()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use str(..., "utf-8") instead of .decode().


if ":" in host:
host, port = host.split(":")
host, port = host.rsplit(":", 1)
port = int(port)
else:
port = 80

if proto != "http:":
raise ValueError("Unsupported protocol: " + proto)
reader, writer = await asyncio.open_connection(host, port)
# Use protocol 1.0, because 1.1 always allows to use chunked
# transfer-encoding But explicitly set Connection: close, even
# though this should be default for 1.0, because some servers
# misbehave w/o it.
query = "%s /%s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\nUser-Agent: compat\r\n\r\n" % (
method,
path,
host,
)
# Use protocol 1.0, because 1.1 always allows to use chunked transfer-encoding
query = "%s /%s HTTP/1.0\r\nHost: %s\r\n%s\r\n\r\n" % (method, path, host, "\r\n".join("%s: %s" % (k,v) for k,v in hdrs.items()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating a very long string here, I suggest writing out the headers one-by-one, eg:

await write.awrite(bytes(query, "utf-8"))
for k in hdrs:
    await writer.awrite(k)
    await writer.awrite(b": ")
    await writer.awrite(hdrs[k])
    await writer.awrite(b"\r\n")

await writer.awrite(query.encode("latin-1"))
return reader

Expand Down
Loading