def received(self, data):
     """
     Receives the HTTP stream for one request.
     Returns the number of bytes consumed.
     Sets the completed flag once both the header and the
     body have been received.
     """
     if self.completed:
         return 0  # Can't consume any more.
     datalen = len(data)
     br = self.body_rcv
     if br is None:
         # In header.
         s = self.header_plus + data
         index = find_double_newline(s)
         if index >= 0:
             # Header finished.
             header_plus = s[:index]
             consumed = len(data) - (len(s) - index)
             self.in_header = 0
             # Remove preceeding blank lines.
             header_plus = header_plus.lstrip()
             if not header_plus:
                 self.empty = 1
                 self.completed = 1
             else:
                 self.parse_header(header_plus)
                 if self.body_rcv is None:
                     self.completed = 1
             return consumed
         else:
             # Header not finished yet.
             self.header_plus = s
             return datalen
     else:
         # In body.
         consumed = br.received(data)
         if br.completed:
             self.completed = 1
         return consumed
 def received(self, data):
     """
     Receives the HTTP stream for one request.
     Returns the number of bytes consumed.
     Sets the completed flag once both the header and the
     body have been received.
     """
     if self.completed:
         return 0  # Can't consume any more.
     datalen = len(data)
     br = self.body_rcv
     if br is None:
         # In header.
         s = self.header_plus + data
         index = find_double_newline(s)
         if index >= 0:
             # Header finished.
             header_plus = s[:index]
             consumed = len(data) - (len(s) - index)
             self.in_header = 0
             # Remove preceeding blank lines.
             header_plus = header_plus.lstrip()
             if not header_plus:
                 self.empty = 1
                 self.completed = 1
             else:
                 self.parse_header(header_plus)
                 if self.body_rcv is None:
                     self.completed = 1
             return consumed
         else:
             # Header not finished yet.
             self.header_plus = s
             return datalen
     else:
         # In body.
         consumed = br.received(data)
         if br.completed:
             self.completed = 1
         return consumed
 def test_find_double_newline_twice(self):
     s = b"abc\n\r\ndef\n\ngef"
     x = utilities.find_double_newline(s)
     self.assertEqual(x, 6)
Exemple #4
0
 def received(self, s):
     # Returns the number of bytes consumed.
     if self.completed:
         return 0
     orig_size = len(s)
     while s:
         rm = self.chunk_remainder
         if rm > 0:
             # Receive the remainder of a chunk.
             to_write = s[:rm]
             self.buf.append(to_write)
             written = len(to_write)
             s = s[written:]
             self.chunk_remainder -= written
         elif not self.all_chunks_received:
             # Receive a control line.
             s = self.control_line + s
             pos = s.find(b'\n')
             if pos < 0:
                 # Control line not finished.
                 self.control_line = s
                 s = b''
             else:
                 # Control line finished.
                 line = s[:pos]
                 s = s[pos + 1:]
                 self.control_line = b''
                 line = line.strip()
                 if line:
                     # Begin a new chunk.
                     semi = line.find(b';')
                     if semi >= 0:
                         # discard extension info.
                         line = line[:semi]
                     sz = int(line.strip(), 16)  # hexadecimal
                     if sz > 0:
                         # Start a new chunk.
                         self.chunk_remainder = sz
                     else:
                         # Finished chunks.
                         self.all_chunks_received = 1
                 # else expect a control line.
         else:
             # Receive the trailer.
             trailer = self.trailer + s
             if trailer.startswith(b'\r\n'):
                 # No trailer.
                 self.completed = 1
                 return orig_size - (len(trailer) - 2)
             if trailer.startswith(b'\n'):
                 # No trailer.
                 self.completed = 1
                 return orig_size - (len(trailer) - 1)
             pos = find_double_newline(trailer)
             if pos < 0:
                 # Trailer not finished.
                 self.trailer = trailer
                 s = b''
             else:
                 # Finished the trailer.
                 self.completed = 1
                 self.trailer = trailer[:pos]
                 return orig_size - (len(trailer) - pos)
     return orig_size