[Python-checkins] python/dist/src/Lib httplib.py,1.42.10.7,1.42.10.8

mwh@users.sourceforge.net mwh@users.sourceforge.net
Wed, 25 Sep 2002 09:53:20 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv19426

Modified Files:
      Tag: release22-maint
	httplib.py 
Log Message:
Dump trunk version of httplib.py onto branch.



Index: httplib.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v
retrieving revision 1.42.10.7
retrieving revision 1.42.10.8
diff -C2 -d -r1.42.10.7 -r1.42.10.8
*** httplib.py	12 Jul 2002 14:23:38 -0000	1.42.10.7
--- httplib.py	25 Sep 2002 16:53:17 -0000	1.42.10.8
***************
*** 204,208 ****
      # strict: If true, raise BadStatusLine if the status line can't be
      # parsed as a valid HTTP/1.0 or 1.1 status line.  By default it is
!     # false because it prvents clients from talking to HTTP/0.9
      # servers.  Note that a response with a sufficiently corrupted
      # status line will look like an HTTP/0.9 response.
--- 204,208 ----
      # strict: If true, raise BadStatusLine if the status line can't be
      # parsed as a valid HTTP/1.0 or 1.1 status line.  By default it is
!     # false because it prevents clients from talking to HTTP/0.9
      # servers.  Note that a response with a sufficiently corrupted
      # status line will look like an HTTP/0.9 response.
***************
*** 277,281 ****
                  if self.debuglevel > 0:
                      print "header:", skip
!             
          self.status = status
          self.reason = reason.strip()
--- 277,281 ----
                  if self.debuglevel > 0:
                      print "header:", skip
! 
          self.status = status
          self.reason = reason.strip()
***************
*** 305,311 ****
          # are we using the chunked-style of transfer encoding?
          tr_enc = self.msg.getheader('transfer-encoding')
!         if tr_enc:
!             if tr_enc.lower() != 'chunked':
!                 raise UnknownTransferEncoding()
              self.chunked = 1
              self.chunk_left = None
--- 305,309 ----
          # are we using the chunked-style of transfer encoding?
          tr_enc = self.msg.getheader('transfer-encoding')
!         if tr_enc and tr_enc.lower() == "chunked":
              self.chunked = 1
              self.chunk_left = None
***************
*** 373,420 ****
  
          if self.chunked:
!             assert self.chunked != _UNKNOWN
!             chunk_left = self.chunk_left
!             value = ''
!             while 1:
!                 if chunk_left is None:
!                     line = self.fp.readline()
!                     i = line.find(';')
!                     if i >= 0:
!                         line = line[:i] # strip chunk-extensions
!                     chunk_left = int(line, 16)
!                     if chunk_left == 0:
!                         break
!                 if amt is None:
!                     value = value + self._safe_read(chunk_left)
!                 elif amt < chunk_left:
!                     value = value + self._safe_read(amt)
!                     self.chunk_left = chunk_left - amt
!                     return value
!                 elif amt == chunk_left:
!                     value = value + self._safe_read(amt)
!                     self._safe_read(2)  # toss the CRLF at the end of the chunk
!                     self.chunk_left = None
!                     return value
!                 else:
!                     value = value + self._safe_read(chunk_left)
!                     amt = amt - chunk_left
! 
!                 # we read the whole chunk, get another
!                 self._safe_read(2)      # toss the CRLF at the end of the chunk
!                 chunk_left = None
! 
!             # read and discard trailer up to the CRLF terminator
!             ### note: we shouldn't have any trailers!
!             while 1:
!                 line = self.fp.readline()
!                 if line == '\r\n':
!                     break
! 
!             # we read everything; close the "file"
!             self.close()
! 
!             return value
! 
!         elif amt is None:
              # unbounded read
              if self.will_close:
--- 371,377 ----
  
          if self.chunked:
!             return self._read_chunked(amt)
!         
!         if amt is None:
              # unbounded read
              if self.will_close:
***************
*** 429,433 ****
                  # clip the read to the "end of response"
                  amt = self.length
!             self.length = self.length - amt
  
          # we do not use _safe_read() here because this may be a .will_close
--- 386,390 ----
                  # clip the read to the "end of response"
                  amt = self.length
!             self.length -= amt
  
          # we do not use _safe_read() here because this may be a .will_close
***************
*** 438,441 ****
--- 395,446 ----
          return s
  
+     def _read_chunked(self, amt):
+         assert self.chunked != _UNKNOWN
+         chunk_left = self.chunk_left
+         value = ''
+ 
+         # XXX This accumulates chunks by repeated string concatenation,
+         # which is not efficient as the number or size of chunks gets big.
+         while 1:
+             if chunk_left is None:
+                 line = self.fp.readline()
+                 i = line.find(';')
+                 if i >= 0:
+                     line = line[:i] # strip chunk-extensions
+                 chunk_left = int(line, 16)
+                 if chunk_left == 0:
+                     break
+             if amt is None:
+                 value += self._safe_read(chunk_left)
+             elif amt < chunk_left:
+                 value += self._safe_read(amt)
+                 self.chunk_left = chunk_left - amt
+                 return value
+             elif amt == chunk_left:
+                 value += self._safe_read(amt)
+                 self._safe_read(2)  # toss the CRLF at the end of the chunk
+                 self.chunk_left = None
+                 return value
+             else:
+                 value += self._safe_read(chunk_left)
+                 amt -= chunk_left
+ 
+             # we read the whole chunk, get another
+             self._safe_read(2)      # toss the CRLF at the end of the chunk
+             chunk_left = None
+ 
+         # read and discard trailer up to the CRLF terminator
+         ### note: we shouldn't have any trailers!
+         while 1:
+             line = self.fp.readline()
+             if line == '\r\n':
+                 break
+ 
+         # we read everything; close the "file"
+         # XXX Shouldn't the client close the file?
+         self.close()
+ 
+         return value
+     
      def _safe_read(self, amt):
          """Read the number of bytes requested, compensating for partial reads.
***************
*** 480,486 ****
      def __init__(self, host, port=None, strict=None):
          self.sock = None
          self.__response = None
          self.__state = _CS_IDLE
!         
          self._set_hostport(host, port)
          if strict is not None:
--- 485,492 ----
      def __init__(self, host, port=None, strict=None):
          self.sock = None
+         self._buffer = []
          self.__response = None
          self.__state = _CS_IDLE
! 
          self._set_hostport(host, port)
          if strict is not None:
***************
*** 558,561 ****
--- 564,584 ----
              raise
  
+     def _output(self, s):
+         """Add a line of output to the current request buffer.
+ 
+         Assumes that the line does *not* end with \\r\\n.
+         """
+         self._buffer.append(s)
+ 
+     def _send_output(self):
+         """Send the currently buffered request and clear the buffer.
+ 
+         Appends an extra \\r\\n to the buffer.
+         """
+         self._buffer.extend(("", ""))
+         msg = "\r\n".join(self._buffer)
+         del self._buffer[:]
+         self.send(msg)
+ 
      def putrequest(self, method, url, skip_host=0):
          """Send a request to the server.
***************
*** 566,569 ****
--- 589,593 ----
  
          # check if a prior response has been completed
+         # XXX What if it hasn't?
          if self.__response and self.__response.isclosed():
              self.__response = None
***************
*** 595,608 ****
          if not url:
              url = '/'
!         str = '%s %s %s\r\n' % (method, url, self._http_vsn_str)
  
!         try:
!             self.send(str)
!         except socket.error, v:
!             # trap 'Broken pipe' if we're allowed to automatically reconnect
!             if v[0] != 32 or not self.auto_open:
!                 raise
!             # try one more time (the socket was closed; this will reopen)
!             self.send(str)
  
          if self._http_vsn == 11:
--- 619,625 ----
          if not url:
              url = '/'
!         str = '%s %s %s' % (method, url, self._http_vsn_str)
  
!         self._output(str)
  
          if self._http_vsn == 11:
***************
*** 665,670 ****
              raise CannotSendHeader()
  
!         str = '%s: %s\r\n' % (header, value)
!         self.send(str)
  
      def endheaders(self):
--- 682,687 ----
              raise CannotSendHeader()
  
!         str = '%s: %s' % (header, value)
!         self._output(str)
  
      def endheaders(self):
***************
*** 676,680 ****
              raise CannotSendHeader()
  
!         self.send('\r\n')
  
      def request(self, method, url, body=None, headers={}):
--- 693,697 ----
              raise CannotSendHeader()
  
!         self._send_output()
  
      def request(self, method, url, body=None, headers={}):
***************
*** 804,808 ****
  
      BUFSIZE = 8192
!     
      def __init__(self, sock, ssl, bufsize=None):
          SharedSocketClient.__init__(self, sock)
--- 821,825 ----
  
      BUFSIZE = 8192
! 
      def __init__(self, sock, ssl, bufsize=None):
          SharedSocketClient.__init__(self, sock)
***************
*** 1128,1132 ****
                  return s + self._file.read()
              else:
!                 return s + self._file.read(amt - len(s))                
          else:
              assert amt <= self._line_left
--- 1145,1149 ----
                  return s + self._file.read()
              else:
!                 return s + self._file.read(amt - len(s))
          else:
              assert amt <= self._line_left
***************
*** 1139,1143 ****
                  self._done()
              return s
!         
      def readline(self):
          s = self._line[self._line_offset:]
--- 1156,1160 ----
                  self._done()
              return s
! 
      def readline(self):
          s = self._line[self._line_offset:]
***************
*** 1196,1200 ****
  
      if hasattr(socket, 'ssl'):
!         
          for host, selector in (('sourceforge.net', '/projects/python'),
                                 ('dbserv2.theopalgroup.com', '/mediumfile'),
--- 1213,1217 ----
  
      if hasattr(socket, 'ssl'):
! 
          for host, selector in (('sourceforge.net', '/projects/python'),
                                 ('dbserv2.theopalgroup.com', '/mediumfile'),
***************
*** 1203,1206 ****
--- 1220,1224 ----
              print "https://%s%s" % (host, selector)
              hs = HTTPS()
+             hs.set_debuglevel(dl)
              hs.connect(host)
              hs.putrequest('GET', selector)
***************
*** 1214,1219 ****
                  for header in headers.headers: print header.strip()
              print
- 
-     return
  
      # Test a buggy server -- returns garbled status line.
--- 1232,1235 ----