[New-bugs-announce] [issue17319] http.server.BaseHTTPRequestHandler send_response_only doesn't check the type and value of the code.

karl report at bugs.python.org
Thu Feb 28 05:12:05 CET 2013


New submission from karl:

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.

=========================================
→ http GET localhost:9000
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.3.0
Date: Thu, 28 Feb 2013 04:00:44 GMT
Content-type: text/plain

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

=========================================
→ http GET localhost:9000
HTTP/1.0 999 
Server: BaseHTTP/0.6 Python/3.3.0
Date: Thu, 28 Feb 2013 03:55:54 GMT
Content-type: text/plain

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

=========================================
→ http GET localhost:9000
HTTPConnectionPool(host='localhost', port=9000): Max retries exceeded with url: /
=========================================

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. 
Shall we fix it? 
What others think?

I guess there should be test cases too?
I'm happy to make unit test cases for it though I might need a bit of guidance as I'm not comfortable with unit test cases mocking connections.

----------
components: Library (Lib)
messages: 183201
nosy: karlcow, orsenthil
priority: normal
severity: normal
status: open
title: http.server.BaseHTTPRequestHandler send_response_only doesn't check the type and value of the code.
type: enhancement
versions: Python 3.3

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue17319>
_______________________________________


More information about the New-bugs-announce mailing list