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
http.server.BaseHTTPRequestHandler send_response_only doesn't check the type and value of the code. #61521
Comments
def send_response_only(self, code, message=None):
http://hg.python.org/cpython/file/3.3/Lib/http/server.py#l448 There is no type checking on code or if the code is appropriate. Let's take ============================================== #!/usr/bin/env python3.3
import http.server
class HTTPHandler(http.server.BaseHTTPRequestHandler):
"A very simple server"
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(bytes('Response body\n\n', 'latin1'))
if __name__ == '__main__':
addr = ('', 9000)
http.server.HTTPServer(addr, HTTPHandler).serve_forever() ===================================================== A request is working well. ========================================= Response body ========================================= And the server log is 127.0.0.1 - - [27/Feb/2013 23:00:44] "GET / HTTP/1.1" 200 - Then let's try ========================================= #!/usr/bin/env python3.3
import http.server
class HTTPHandler(http.server.BaseHTTPRequestHandler):
"A very simple server"
def do_GET(self):
self.send_response(999)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(bytes('Response body\n\n', 'latin1'))
if __name__ == '__main__':
addr = ('', 9000)
http.server.HTTPServer(addr, HTTPHandler).serve_forever() ========================================= The response is ========================================= Response body ========================================= and the log server is 127.0.0.1 - - [27/Feb/2013 22:55:12] "GET / HTTP/1.1" 999 - And finally ========================================= #!/usr/bin/env python3.3
import http.server
class HTTPHandler(http.server.BaseHTTPRequestHandler):
"A very simple server"
def do_GET(self):
self.send_response('foobar')
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(bytes('Response body\n\n', 'latin1'))
if __name__ == '__main__':
addr = ('', 9000)
http.server.HTTPServer(addr, HTTPHandler).serve_forever() ========================================= The response is then ========================================= and the server log is 127.0.0.1 - - [27/Feb/2013 22:56:39] "GET / HTTP/1.1" foobar - Exception happened during processing of request from ('127.0.0.1', 53917)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 306, in _handle_request_noblock
self.process_request(request, client_address)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 332, in process_request
self.finish_request(request, client_address)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 345, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 666, in __init__
self.handle()
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/server.py", line 400, in handle
self.handle_one_request()
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/server.py", line 388, in handle_one_request
method()
File "../25/server.py", line 8, in do_GET
self.send_response('foobar')
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/server.py", line 444, in send_response
self.send_response_only(code, message)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/server.py", line 459, in send_response_only
(self.protocol_version, code, message)).encode(
TypeError: %d format: a number is required, not str Both error messages and server logs are not very helpful. I guess there should be test cases too? |
Attached patch for checking status code based at RFC 2616 [1]. |
Where this is defined in the new RFC. http://tools.ietf.org/html/rfc7230#section-3.1.2
Things to enforce
Response status code are now defined in HTTP status codes are extensible. HTTP clients are not required to For example, if an unrecognized status code of 471 is received by a That should help. The full registry of status code is defined here @dmi.baranov In the patch Maybe there is a missing check where the len(str(code)) == 3 |
The proposed patch changes the code to 500 if the code is invalid (rather than raising an exception as I initially assumed). I would be inclined to leave send_response() without any extra error checking or handling, unless this is a common problem and there is a real need for it. Although I reckon it might be nice to have a generic (higher-level) exception handler for the HTTP server that responds with “500 Internal server error” if possible. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: