9

I am writing a simple SocketServer.TCPServer request handler (StreamRequestHandler) that will capture the request, along with the headers and the message body. This is for faking out an HTTP server that we can use for testing.

I have no trouble grabbing the request line or the headers.

If I try to grab more from the rfile than exists, the code blocks. How can I grab all of the request body without knowing its size? In other words, I don't have a Content-Size header.

Here's a snippet of what I have now:

def _read_request_line(self):
    server.request_line = self.rfile.readline().rstrip('\r\n')

def _read_headers(self):
    headers = []
    for line in self.rfile:
        line = line.rstrip('\r\n')
        if not line:
            break
        parts = line.split(':', 1)
        header = (parts[0].strip(), parts[0].strip())
        headers.append(header)
    server.request_headers = headers

def _read_content(self):
    server.request_content = self.rfile.read()  # blocks
Travis Parks
  • 8,435
  • 12
  • 52
  • 85
  • See the section about [non-blocking sockets](http://docs.python.org/howto/sockets.html#non-blocking-sockets). – Some programmer dude Sep 27 '12 at 16:59
  • 3
    WIth HTTP the choices are either use the Content-Length header (if there is a body), or use chunked transfer encoding. A properly written client MUST send this header. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 – Keith Sep 27 '12 at 17:04
  • Why don't you use the SimpleHTTPServer module? – Keith Sep 27 '12 at 17:08
  • 1
    I don't use the SimpleHTTPServer because it takes on too much responsibility. I need to control *extactly* what headers get returned. – Travis Parks Sep 27 '12 at 19:12
  • I decided the best thing to do was to look for `content-length` and to default the value to zero if it isn't provided. Like @Keith mentioned, valid clients should provide this value. – Travis Parks Sep 27 '12 at 19:14

1 Answers1

8

Keith's comment is correct. Here's what it looks like

     length = int(self.headers.getheader('content-length'))
     data = self.rfile.read(length)
Jim Carroll
  • 2,320
  • 17
  • 23