Changeset 1264
- Timestamp:
- 08/21/06 18:18:39
- Files:
-
- trunk/cherrypy/_cpwsgiserver.py (modified) (2 diffs)
- trunk/cherrypy/test/test_conn.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cpwsgiserver.py
r1263 r1264 139 139 self.environ.update(self.parse_headers(headers)) 140 140 141 cl = headers.getheader("Content-length")142 if method in ("POST", "PUT") and cl is None:143 # No Content-Length header supplied. This will hang144 # cgi.FieldStorage, since it cannot determine when to145 # stop reading from the socket. Until we handle chunked146 # encoding, always respond with 411 Length Required.147 # See http://www.cherrypy.org/ticket/493.148 self.simple_response("411 Length Required")149 return150 151 141 # Persistent connection support 152 142 if self.response_protocol == "HTTP/1.1": … … 164 154 te = headers.getheader("Transfer-Encoding", "") 165 155 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 170 165 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") 174 175 return 175 176 trunk/cherrypy/test/test_conn.py
r1263 r1264 76 76 77 77 # Make another, streamed request on the same connection. 78 # Streamed output closes the connection to determine transfer-length.79 78 self.getPage("/stream") 80 79 self.assertStatus('200 OK') 81 80 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) 82 102 self.assertHeader("Connection", "close") 83 103 84 104 # Make another request on the same connection, which should error. 85 105 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")93 106 94 107 def test_HTTP11_pipelining(self): … … 190 203 191 204 # 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) 193 206 194 207 # Try a normal chunked request 195 208 body = ("8\r\nxx\r\nxxxx\r\n5\r\nyyyyy\r\n0\r\n" 196 209 "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) 203 222 self.assertStatus('200 OK') 204 223 self.assertBody("thanks for 'xx\r\nxxxxyyyyy' (application/x-json)") … … 206 225 # Try a chunked request that exceeds max_request_body_size. 207 226 # 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) 215 237 self.assertStatus(413) 216 238 self.assertBody("") … … 224 246 self.assertStatus('200 OK') 225 247 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") 227 250 228 251 # Test a keep-alive HTTP/1.0 request. … … 240 263 self.assertStatus('200 OK') 241 264 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") 243 267 244 268

