<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -89,7 +89,7 @@ from urlparse import urlsplit, urlunsplit
 
 import push_tcp
 from common import HttpMessageParser, HttpMessageSerialiser, \
-    CLOSE, COUNTED, CHUNKED, NONE, \
+    CLOSE, COUNTED, NOBODY, \
     WAITING, HEADERS_DONE, \
     idempotent_methods, no_body_status, hop_by_hop_hdrs, \
     linesep, dummy, get_hdr
@@ -98,15 +98,14 @@ from error import ERR_URL, ERR_CONNECT, ERR_LEN_REQ, ERR_READ_TIMEOUT, ERR_HTTP_
 # TODO: proxy support
 # TODO: next-hop version cache for Expect/Continue, etc.
 
-class Client(HttpMessageParser, HttpMessageSerialiser):
+class Client(HttpMessageHandler):
     &quot;An asynchronous HTTP client.&quot;
     connect_timeout = None
     read_timeout = None
     retry_limit = 2
 
     def __init__(self, res_start_cb):
-        HttpMessageParser.__init__(self)
-        HttpMessageSerialiser.__init__(self)
+        HttpMessageHandler.__init__(self)
         self.res_start_cb = res_start_cb
         self.res_body_cb = None
         self.res_done_cb = None
@@ -120,12 +119,6 @@ class Client(HttpMessageParser, HttpMessageSerialiser):
         self._timeout_ev = None
         self._output_buffer = []
 
-    def output(self, chunk):
-        self._output_buffer.append(chunk)
-        if self._tcp_conn and self._tcp_conn.tcp_connected:
-            self._tcp_conn.write(&quot;&quot;.join(self._output_buffer))
-            self._output_buffer = []
-        
     def req_start(self, method, uri, req_hdrs, req_body_pause):
         &quot;&quot;&quot;
         Start a request to uri using method, where 
@@ -159,10 +152,10 @@ class Client(HttpMessageParser, HttpMessageSerialiser):
         self.req_hdrs.append((&quot;Connection&quot;, &quot;keep-alive&quot;))
         try:
             body_len = int(get_hdr(req_hdrs, &quot;content-length&quot;).pop(0))
-            delimit=COUNTED
+            delimit = COUNTED
         except IndexError, ValueError:
             body_len = None
-            delimit=NONE
+            delimit = NOBODY
         self._output_start(&quot;%s %s HTTP/1.1&quot; % (self.method, self.uri), self.req_hdrs, delimit)
         _idle_pool.attach(host, port, self._handle_connect, self._handle_connect_error, self.connect_timeout)
         return self.req_body, self.req_done
@@ -247,7 +240,7 @@ class Client(HttpMessageParser, HttpMessageSerialiser):
         if self._req_body_pause_cb:
             self._req_body_pause_cb(paused)
 
-    # Methods called by common.HttpRequestParser
+    # Methods called by common.HttpMessageHandler
 
     def _input_start(self, top_line, hdr_tuples, conn_tokens, transfer_codes, content_length):
         &quot;&quot;&quot;
@@ -313,6 +306,12 @@ class Client(HttpMessageParser, HttpMessageSerialiser):
         err['detail'] = detail
         self.res_done_cb(err)
 
+    def _output(self, chunk):
+        self._output_buffer.append(chunk)
+        if self._tcp_conn and self._tcp_conn.tcp_connected:
+            self._tcp_conn.write(&quot;&quot;.join(self._output_buffer))
+            self._output_buffer = []
+
     # misc
 
     def _handle_error(self, err, detail=None):</diff>
      <filename>src/client.py</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@ hdr_end = re.compile(r&quot;\r?\n\r?\n&quot;, re.M)
 linesep = &quot;\r\n&quot; 
 
 # conn_modes
-CLOSE, COUNTED, CHUNKED, NONE = 0, 1, 2, 3
+CLOSE, COUNTED, CHUNKED, NOBODY = 0, 1, 2, 3
 
 # states
 WAITING, HEADERS_DONE = 1, 2
@@ -85,66 +85,16 @@ def get_hdr(hdr_tuples, name):
                 ]
             , [])]
 
-class HttpMessageSerialiser:
-    &quot;&quot;&quot;
-    This is a base class for something that has to serialise HTTP messages,
-    request or response.
-    &quot;&quot;&quot;
-    def __init__(self):
-        self._output_state = WAITING
-        self._output_delimit = None
-        self._output_pause_cb = None
-
-    def output(self, out):
-        raise NotImplementedError
-
-    def _handle_error(err):
-        raise NotImplementedError
 
-    def _output_start(self, top_line, hdr_tuples, delimit):
-        self._output_delimit = delimit
-        out = linesep.join(
-                [top_line] +
-                [&quot;%s: %s&quot; % (k, v) for k, v in hdr_tuples] +
-                [&quot;&quot;, &quot;&quot;]
-        )
-        self.output(out)
-        self._output_state = HEADERS_DONE
-        
-    def _output_body(self, chunk):
-        if not chunk: 
-            return
-        if self._output_delimit == CHUNKED:
-            chunk = &quot;%s\r\n%s\r\n&quot; % (hex(len(chunk))[2:], chunk)
-        self.output(chunk)
-        #FIXME: body counting
-#        self._output_body_sent += len(chunk)
-#        assert self._output_body_sent &lt;= self._output_content_length, \
-#            &quot;Too many body bytes sent&quot;
-
-    def _output_end(self, err):
-        if err:
-            self.output_body_cb, self.output_done_cb = dummy, dummy
-            self._tcp_conn.close()
-            self._tcp_conn = None
-        elif self._output_delimit == NONE:
-            pass # didn't have a body at all.
-        elif self._output_delimit == CHUNKED:
-            self.output(&quot;0\r\n\r\n&quot;)
-        elif self._output_delimit == COUNTED:
-            pass # TODO: double-check the length
-        elif self._output_delimit == CLOSE:
-            self._tcp_conn.close() # FIXME: abstract out?
-        else:
-            raise AssertionError, &quot;Unknown request delimiter %s&quot; % self._output_delimit
-
-
-
-class HttpMessageParser:
+class HttpMessageHandler:
     &quot;&quot;&quot;
-    This is a base class for something that has to parse HTTP messages, request
-    or response. It expects you to override _input_start, _input_body and 
+    This is a base class for something that has to parse and/or serialise 
+    HTTP messages, request or response.
+
+    For parsing, it expects you to override _input_start, _input_body and
     _input_end, and call _handle_input when you get bytes from the network.
+
+    For serialising, it expects you to override _output.
     &quot;&quot;&quot;
 
     def __init__(self):
@@ -152,6 +102,10 @@ class HttpMessageParser:
         self._input_state = WAITING
         self._input_delimit = None
         self._input_body_left = 0
+        self._output_state = WAITING
+        self._output_delimit = None
+
+    # input-related methods
 
     def _input_start(self, top_line, hdr_tuples, conn_tokens, transfer_codes, content_length):
         &quot;&quot;&quot;
@@ -190,7 +144,7 @@ class HttpMessageParser:
             else: # partial headers; store it and wait for more
                 self._input_buffer = instr
         elif self._input_state == HEADERS_DONE:
-            if self._input_delimit == NONE: # a message without a body
+            if self._input_delimit == NOBODY: # a message without a body
                 if instr:
                     self._input_error(ERR_BODY_FORBIDDEN, instr) # FIXME: will not work with pipelining
                 else:
@@ -319,7 +273,7 @@ class HttpMessageParser:
                                 
         self._input_state = HEADERS_DONE
         if not allows_body:
-            self._input_delimit = NONE
+            self._input_delimit = NOBODY
         elif len(transfer_codes) &gt; 0:
             if 'chunked' in transfer_codes:
                 self._input_delimit = CHUNKED
@@ -332,4 +286,57 @@ class HttpMessageParser:
         else: 
             self._input_delimit = CLOSE
         return rest
-    
\ No newline at end of file
+
+    ### output-related methods
+
+    def _output(self, out):
+        raise NotImplementedError
+
+    def _handle_error(err):
+        raise NotImplementedError
+
+    def _output_start(self, top_line, hdr_tuples, delimit):
+        &quot;&quot;&quot;
+        Start ouputting a HTTP message.
+        &quot;&quot;&quot;
+        self._output_delimit = delimit
+        out = linesep.join(
+                [top_line] +
+                [&quot;%s: %s&quot; % (k, v) for k, v in hdr_tuples] +
+                [&quot;&quot;, &quot;&quot;]
+        )
+        self._output(out)
+        self._output_state = HEADERS_DONE
+
+    def _output_body(self, chunk):
+        &quot;&quot;&quot;
+        Output a part of a HTTP message.
+        &quot;&quot;&quot;
+        if not chunk:
+            return
+        if self._output_delimit == CHUNKED:
+            chunk = &quot;%s\r\n%s\r\n&quot; % (hex(len(chunk))[2:], chunk)
+        self._output(chunk)
+        #FIXME: body counting
+#        self._output_body_sent += len(chunk)
+#        assert self._output_body_sent &lt;= self._output_content_length, \
+#            &quot;Too many body bytes sent&quot;
+
+    def _output_end(self, err):
+        &quot;&quot;&quot;
+        Finish outputting a HTTP message.
+        &quot;&quot;&quot;
+        if err:
+            self.output_body_cb, self.output_done_cb = dummy, dummy
+            self._tcp_conn.close()
+            self._tcp_conn = None
+        elif self._output_delimit == NOBODY:
+            pass # didn't have a body at all.
+        elif self._output_delimit == CHUNKED:
+            self._output(&quot;0\r\n\r\n&quot;)
+        elif self._output_delimit == COUNTED:
+            pass # TODO: double-check the length
+        elif self._output_delimit == CLOSE:
+            self._tcp_conn.close() # FIXME: abstract out?
+        else:
+            raise AssertionError, &quot;Unknown request delimiter %s&quot; % self._output_delimit</diff>
      <filename>src/common.py</filename>
    </modified>
    <modified>
      <diff>@@ -91,7 +91,7 @@ import logging
 
 import push_tcp
 from common import HttpMessageParser, HttpMessageSerialiser, \
-    CLOSE, COUNTED, CHUNKED, NONE, \
+    CLOSE, COUNTED, CHUNKED, \
     WAITING, HEADERS_DONE, \
     hop_by_hop_hdrs, \
     linesep, dummy, get_hdr
@@ -117,10 +117,10 @@ class Server:
         return conn._handle_input, conn._conn_closed, conn._res_body_pause
 
 
-class HttpServerConnection(HttpMessageParser, HttpMessageSerialiser):
+class HttpServerConnection(HttpMessageHandler):
     &quot;A handler for an HTTP server connection.&quot;
     def __init__(self, request_handler, tcp_conn):
-        HttpMessageParser.__init__(self)
+        HttpMessageHandler.__init__(self)
         HttpMessageSerialiser.__init__(self)
         self.request_handler = request_handler
         self._tcp_conn = tcp_conn
@@ -190,7 +190,7 @@ class HttpServerConnection(HttpMessageParser, HttpMessageSerialiser):
 #        self.tcp_conn.handler = None
 #        self.tcp_conn = None
 
-    # Methods called by common.HttpRequestParser
+    # Methods called by common.HttpRequestHandler
 
     def output(self, chunk):
         self._tcp_conn.write(chunk)</diff>
      <filename>src/server.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1d09b43eba89739c942338a00f634b7a917517f2</id>
    </parent>
  </parents>
  <author>
    <name>Mark Nottingham</name>
    <email>mnot@mnot.net</email>
  </author>
  <url>http://github.com/mnot/nbhttp/commit/b2341d98f3a3331c494409c6ed5b65ca4ef0ed08</url>
  <id>b2341d98f3a3331c494409c6ed5b65ca4ef0ed08</id>
  <committed-date>2009-11-03T12:16:30-08:00</committed-date>
  <authored-date>2009-11-03T12:16:30-08:00</authored-date>
  <message>refactor HttpMessage* into HttpMessageHandler</message>
  <tree>94c295e9daede10f0e07382283823a0329ceccc8</tree>
  <committer>
    <name>Mark Nottingham</name>
    <email>mnot@mnot.net</email>
  </committer>
</commit>
