-
-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bugfix/query string #39
Conversation
cheroot/server.py
Outdated
@@ -874,14 +870,14 @@ def parse_request_uri(self, uri): | |||
# If there's a scheme (and it must be http or https), then: | |||
# http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query | |||
# ]] | |||
return parsed.scheme, parsed.netloc, parsed.path | |||
return parsed.scheme, parsed.netloc, parsed.path, parsed.query |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please alter the docsrting of this method to match new behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return
at line 865 shall be updated as well, please also test this case as well as all other return
s in if clauses
I can update the docstring and the return line as requested. I will need help writing test cases for the rest of it, I don't see any unit tests for this piece of code to verify that it works as intended (unless I missed them in my grepping). I am not sure that a full on HTTP request will hit all of the points it currently attempts to support. |
Docstring and return statement added. |
@bertjwregeer possible test cases to cover are |
See https://tools.ietf.org/html/rfc7230#section-5.3 I have added the tests, but I don't believe that Edit: Wow, it does... |
I also noticed that this is false: https://github.com/bertjwregeer/cheroot/blob/791f126947bd9406fe5648a089be778106672544/cheroot/server.py#L722 Since the returned path from urlparse will have it's params stripped (at least for the last component), since it is parsed. You'll want to modify |
Actually Python recommends using urlsplit instead: https://docs.python.org/2/library/urlparse.html#urlparse.urlsplit since it will leave the path parameters alone for later processing. |
Alright. I'm done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sorry, I'm at EuroPython currently. I'll check the changes ASAP once have some free time. ETA: this week. P.S. Thank you for your efforts! You've done much more than I expected, I really appreciate this. |
@webknjaz do you still have objections? |
Sorry, I wrote a few comments and forgot to hit publish button. Yes, there are a couple of nitpicks. |
cheroot/server.py
Outdated
|
||
if scheme: | ||
self.scheme = scheme | ||
if method.upper() == 'OPTIONS' and not self.proxy: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to RFC 2616 (section 5.1.1) and its successors RFC 7230 (section 3.1.1) and RFC 7231 (section 4.1) method names are case-sensitive and uppercase. Otherwise the request line is malicious and HTTP server must return 400 Bad Request
.
Another nitpick: .upper()
is being called 3 times for the most of requests, which should be avoided.
cheroot/server.py
Outdated
"""Initialize HTTP request container instance. | ||
|
||
Args: | ||
server (HTTPServer): web server object receiving this request | ||
conn (HTTPConnection): HTTP connection object for this request | ||
|
||
Kwargs: | ||
proxy (Boolean): Whether this HTTPServer should behave as a PROXY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please use
bool
for type, because its actual builtin you refer to - Please start the description with lowercase letter, because of the style used everywhere around
- I'd vote for
proxy_mode
var name (just a nitpick)
cheroot/server.py
Outdated
Kwargs: | ||
proxy (Boolean): Whether this HTTPServer should behave as a PROXY | ||
server for certain requests. | ||
strict (Boolean): Whether we should return a 400 Bad Request when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: strict_mode
cheroot/server.py
Outdated
@@ -628,6 +635,8 @@ def __init__(self, server, conn): | |||
self.close_connection = self.__class__.close_connection | |||
self.chunked_read = False | |||
self.chunked_write = self.__class__.chunked_write | |||
self.proxy = proxy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming this attribute is_proxy
would be beneficial
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(or is_proxy_mode
etc.)
You have push permissions to the branch on my repo as a maintainer. Feel free to make those modifications and push there; or pull these changes into a local branch and fixup before pushing back to a new PR. I already maintain Waitress, I really have no want or desire to maintain or spend even more time fixing yet another Python HTTP server. |
Deal, thanks for your contribution anyway :) |
Since we go through the trouble of parsing it, might as well keep em. Especially if we want to be a "proxy" these might be important.
cheroot/server.py
Outdated
return False | ||
path = b'%2F'.join(atoms) | ||
|
||
if path[0] != b'/': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow! It turned out that path[0]
returns int
, not bytes
, which is 47
for /
, thus prepending /
unconditionally.
(just a note)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ref: PEP 358
.__getitem__(int | slice) -> int | bytes
@@ -598,12 +599,17 @@ class HTTPRequest(object): | |||
A HeaderReader instance or compatible reader. | |||
""" | |||
|
|||
def __init__(self, server, conn): | |||
def __init__(self, server, conn, proxy_mode=False, strict_mode=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of boolean parameters, especially when they represent a switch on behavior, because they often are limited in what they can describe and lead to branchy and unmaintainable code. Often it's better to use subclasses or handler functions or enumerated values to signal behavior. I'm not sure what's the best approach here without digging deeper, but I wanted to signal this potential issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point, but currently I cannot suggest cleaner solution. So for now I'm going to merge this as is.
@bertjwregeer I've cut the tag v5.8.0, it will be available @ PYPI once this build succeeds. |
JFI: merging this broke some things and integration with CherryPy, so this is going to be fixed. |
Fix URI encoding issue introduced in #39
Fix for #38