reject URLs with a userinfo component

This commit is contained in:
Michael Lazar 2020-06-20 01:42:17 -04:00
parent 1b07b0a594
commit 0b8446c58f
3 changed files with 10 additions and 10 deletions

View File

@ -2,13 +2,9 @@
### Unreleased ### Unreleased
#### Static Fileserver - URLs with a userinfo component will now be rejected with a status of 59.
- Error stack traces are no longer shown when the client prematurely closes - Error stack traces are no longer shown when the client prematurely closes
the connection. the connection.
#### Internal Framework
- The status code definitions have been updated to match the recent changes - The status code definitions have been updated to match the recent changes
to the gemini spec: to the gemini spec:
- 21 ``SUCCESS_END_OF_SESSION`` -> (removed) - 21 ``SUCCESS_END_OF_SESSION`` -> (removed)
@ -17,8 +13,8 @@
- 63 ``CERTIFICATE_NOT_ACCEPTED`` -> (removed) - 63 ``CERTIFICATE_NOT_ACCEPTED`` -> (removed)
- 64 ``FUTURE_CERTIFICATE_REJECTED`` -> (removed) - 64 ``FUTURE_CERTIFICATE_REJECTED`` -> (removed)
- 65 ``EXPIRED_CERTIFICATE_REJECTED`` -> (removed) - 65 ``EXPIRED_CERTIFICATE_REJECTED`` -> (removed)
- If a gemini response returns a twisted.Deferred object, the errback will - If an application response handler returns a twisted.Deferred object, the
now be invoked when the TCP connection is closed. errback will now be invoked when the TCP connection is closed.
- Added a new example that demonstrates streaming data to client connections - Added a new example that demonstrates streaming data to client connections
(examples/chatroom.py). (examples/chatroom.py).

View File

@ -49,7 +49,7 @@ class Request:
url_parts = urlparse(self.url) url_parts = urlparse(self.url)
if not url_parts.hostname: if not url_parts.hostname:
raise ValueError("URL must contain a `hostname` part") raise ValueError("Missing hostname component")
if not url_parts.scheme: if not url_parts.scheme:
# If scheme is missing, infer it to be gemini:// # If scheme is missing, infer it to be gemini://
@ -57,6 +57,10 @@ class Request:
else: else:
self.scheme = url_parts.scheme self.scheme = url_parts.scheme
# gemini://username@host/... is forbidden by the specification
if self.scheme == "gemini" and url_parts.username:
raise ValueError("Invalid userinfo component")
self.hostname = url_parts.hostname self.hostname = url_parts.hostname
self.port = url_parts.port self.port = url_parts.port
@ -140,7 +144,7 @@ class JetforceApplication:
try: try:
request = Request(environ) request = Request(environ)
except Exception: except Exception:
send_status(Status.BAD_REQUEST, "Unrecognized URL format") send_status(Status.BAD_REQUEST, "Invalid URL")
return return
for route_pattern, callback in self.routes[::-1]: for route_pattern, callback in self.routes[::-1]:

View File

@ -34,7 +34,7 @@ class CompositeApplication:
try: try:
request = Request(environ) request = Request(environ)
except Exception: except Exception:
send_status(Status.BAD_REQUEST, "Unrecognized URL format") send_status(Status.BAD_REQUEST, "Invalid URL")
return return
if request.hostname in self.application_map: if request.hostname in self.application_map: