Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1264

Show
Ignore:
Timestamp:
08/21/06 18:18:39
Author:
fumanchu
Message:

Minor chunked encoding fix, plus test suite fixes for cpmodpy.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/_cpwsgiserver.py

    r1263 r1264  
    139139        self.environ.update(self.parse_headers(headers)) 
    140140         
    141         cl = headers.getheader("Content-length") 
    142         if method in ("POST", "PUT") and cl is None: 
    143             # No Content-Length header supplied. This will hang 
    144             # cgi.FieldStorage, since it cannot determine when to 
    145             # stop reading from the socket. Until we handle chunked 
    146             # encoding, always respond with 411 Length Required. 
    147             # See http://www.cherrypy.org/ticket/493. 
    148             self.simple_response("411 Length Required") 
    149             return 
    150          
    151141        # Persistent connection support 
    152142        if self.response_protocol == "HTTP/1.1": 
     
    164154        te = headers.getheader("Transfer-Encoding", "") 
    165155        te = [x.strip() for x in te.split(",") if x.strip()] 
    166         while te: 
    167             enc = te.pop() 
    168             if enc.lower() == "chunked": 
    169                 if not self.decode_chunked(): 
     156        if te: 
     157            while te: 
     158                enc = te.pop() 
     159                if enc.lower() == "chunked": 
     160                    if not self.decode_chunked(): 
     161                        return 
     162                else: 
     163                    self.simple_response("501 Unimplemented") 
     164                    self.close_connection = True 
    170165                    return 
    171             else: 
    172                 self.simple_response("501 Unimplemented") 
    173                 self.close_connection = True 
     166        else: 
     167            cl = headers.getheader("Content-length") 
     168            if method in ("POST", "PUT") and cl is None: 
     169                # No Content-Length header supplied. This will hang 
     170                # cgi.FieldStorage, since it cannot determine when to 
     171                # stop reading from the socket. Until we handle chunked 
     172                # encoding, always respond with 411 Length Required. 
     173                # See http://www.cherrypy.org/ticket/493. 
     174                self.simple_response("411 Length Required") 
    174175                return 
    175176         
  • trunk/cherrypy/test/test_conn.py

    r1263 r1264  
    7676         
    7777        # Make another, streamed request on the same connection. 
    78         # Streamed output closes the connection to determine transfer-length. 
    7978        self.getPage("/stream") 
    8079        self.assertStatus('200 OK') 
    8180        self.assertBody('0123456789') 
     81        self.assertNoHeader("Content-Length") 
     82        # Streamed output will either close the connection, or use 
     83        # chunked encoding, to determine transfer-length. 
     84        chunked_response = False 
     85        for k, v in self.headers: 
     86            if k.lower() == "transfer-encoding": 
     87                if str(v) == "chunked": 
     88                    chunked_response = True 
     89        if not chunked_response: 
     90            self.assertHeader("Connection", "close") 
     91             
     92            # Make another request on the same connection, which should error. 
     93            self.assertRaises(httplib.NotConnected, self.getPage, "/") 
     94         
     95        # Test client-side close. 
     96        self.HTTP_CONN = httplib.HTTPConnection(self.HOST, self.PORT) 
     97        self.HTTP_CONN.auto_open = False 
     98        self.HTTP_CONN.connect() 
     99        self.getPage("/page2", headers=[("Connection", "close")]) 
     100        self.assertStatus('200 OK') 
     101        self.assertBody(pov) 
    82102        self.assertHeader("Connection", "close") 
    83103         
    84104        # Make another request on the same connection, which should error. 
    85105        self.assertRaises(httplib.NotConnected, self.getPage, "/") 
    86          
    87         # Test client-side close. 
    88         self.HTTP_CONN = httplib.HTTPConnection(self.HOST, self.PORT) 
    89         self.getPage("/page2", headers=[("Connection", "close")]) 
    90         self.assertStatus('200 OK') 
    91         self.assertBody(pov) 
    92         self.assertHeader("Connection", "close") 
    93106     
    94107    def test_HTTP11_pipelining(self): 
     
    190203         
    191204        # Set our HTTP_CONN to an instance so it persists between requests. 
    192         self.HTTP_CONN = httplib.HTTPConnection(self.HOST, self.PORT) 
     205        conn = httplib.HTTPConnection(self.HOST, self.PORT) 
    193206         
    194207        # Try a normal chunked request 
    195208        body = ("8\r\nxx\r\nxxxx\r\n5\r\nyyyyy\r\n0\r\n" 
    196209                "Content-Type: application/x-json\r\n\r\n") 
    197         self.getPage("/upload", 
    198                      headers=[("Transfer-Encoding", "chunked"), 
    199                               ("Trailer", "Content-Type"), 
    200                               ("Content-Length", len(body)), 
    201                               ], 
    202                      body=body, method="POST") 
     210        conn.putrequest("POST", "/upload", skip_host=True) 
     211        conn.putheader("Host", self.HOST) 
     212        conn.putheader("Transfer-Encoding", "chunked") 
     213        conn.putheader("Trailer", "Content-Type") 
     214        # Note that this is somewhat malformed: 
     215        # we shouldn't be sending Content-Length. 
     216        # RFC 2616 says the server should ignore it. 
     217        conn.putheader("Content-Length", len(body)) 
     218        conn.endheaders() 
     219        conn.send(body) 
     220        response = conn.getresponse() 
     221        self.status, self.headers, self.body = webtest.shb(response) 
    203222        self.assertStatus('200 OK') 
    204223        self.assertBody("thanks for 'xx\r\nxxxxyyyyy' (application/x-json)") 
     
    206225        # Try a chunked request that exceeds max_request_body_size. 
    207226        # Note that the delimiters and trailer are included. 
    208         body = ("5f\r\n" + ("x" * 95) + "\r\n0\r\n\r\n") 
    209         self.getPage("/upload", 
    210                      headers=[("Transfer-Encoding", "chunked"), 
    211                               ("Content-Type", "text/plain"), 
    212                               ("Content-Length", len(body)), 
    213                               ], 
    214                      body=body, method="POST") 
     227        body = "5f\r\n" + ("x" * 95) + "\r\n0\r\n\r\n" 
     228        conn.putrequest("POST", "/upload", skip_host=True) 
     229        conn.putheader("Host", self.HOST) 
     230        conn.putheader("Transfer-Encoding", "chunked") 
     231        conn.putheader("Content-Type", "text/plain") 
     232##        conn.putheader("Content-Length", len(body)) 
     233        conn.endheaders() 
     234        conn.send(body) 
     235        response = conn.getresponse() 
     236        self.status, self.headers, self.body = webtest.shb(response) 
    215237        self.assertStatus(413) 
    216238        self.assertBody("") 
     
    224246        self.assertStatus('200 OK') 
    225247        self.assertBody(pov) 
    226         self.assertNoHeader("Connection") 
     248        # Apache, for example, may emit a Connection header even for HTTP/1.0 
     249##        self.assertNoHeader("Connection") 
    227250         
    228251        # Test a keep-alive HTTP/1.0 request. 
     
    240263        self.assertStatus('200 OK') 
    241264        self.assertBody(pov) 
    242         self.assertNoHeader("Connection") 
     265        # Apache, for example, may emit a Connection header even for HTTP/1.0 
     266##        self.assertNoHeader("Connection") 
    243267 
    244268 

Hosted by WebFaction

Log in as guest/cpguest to create tickets