Changeset 1565
- Timestamp:
- 12/24/06 22:09:17
- Files:
-
- trunk/cherrypy/_cprequest.py (modified) (1 diff)
- trunk/cherrypy/test/test_conn.py (modified) (1 diff)
- trunk/cherrypy/wsgiserver.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cprequest.py
r1470 r1565 538 538 if dict.get(headers, 'Content-Length') is None: 539 539 dict.pop(headers, 'Content-Length', None) 540 elif code < 200 or code in (204, 304):540 elif code < 200 or code in (204, 205, 304): 541 541 # "All 1xx (informational), 204 (no content), 542 542 # and 304 (not modified) responses MUST NOT trunk/cherrypy/test/test_conn.py
r1550 r1565 100 100 101 101 def _streaming(self, set_cl): 102 if cherrypy.server.protocol_version != "HTTP/1.1": 103 print "skipped ", 104 return 105 106 self.PROTOCOL = "HTTP/1.1" 107 108 self.persistent = True 109 110 # Make the first request and assert there's no "Connection: close". 111 self.getPage("/") 112 self.assertStatus('200 OK') 113 self.assertBody(pov) 114 self.assertNoHeader("Connection") 115 116 # Make another, streamed request on the same connection. 117 if set_cl: 118 # When a Content-Length is provided, the content should stream 119 # without closing the connection. 120 self.getPage("/stream?set_cl=Yes") 121 self.assertHeader("Content-Length") 122 self.assertNoHeader("Connection", "close") 123 self.assertNoHeader("Transfer-Encoding") 102 if cherrypy.server.protocol_version == "HTTP/1.1": 103 self.PROTOCOL = "HTTP/1.1" 104 105 self.persistent = True 106 107 # Make the first request and assert there's no "Connection: close". 108 self.getPage("/") 109 self.assertStatus('200 OK') 110 self.assertBody(pov) 111 self.assertNoHeader("Connection") 112 113 # Make another, streamed request on the same connection. 114 if set_cl: 115 # When a Content-Length is provided, the content should stream 116 # without closing the connection. 117 self.getPage("/stream?set_cl=Yes") 118 self.assertHeader("Content-Length") 119 self.assertNoHeader("Connection", "close") 120 self.assertNoHeader("Transfer-Encoding") 121 122 self.assertStatus('200 OK') 123 self.assertBody('0123456789') 124 else: 125 # When no Content-Length response header is provided, 126 # streamed output will either close the connection, or use 127 # chunked encoding, to determine transfer-length. 128 self.getPage("/stream") 129 self.assertNoHeader("Content-Length") 130 self.assertStatus('200 OK') 131 self.assertBody('0123456789') 132 133 chunked_response = False 134 for k, v in self.headers: 135 if k.lower() == "transfer-encoding": 136 if str(v) == "chunked": 137 chunked_response = True 138 139 if chunked_response: 140 self.assertNoHeader("Connection", "close") 141 else: 142 self.assertHeader("Connection", "close") 143 144 # Make another request on the same connection, which should error. 145 self.assertRaises(httplib.NotConnected, self.getPage, "/") 124 146 else: 125 # When no Content-Length response header is provided, 126 # streamed output will either close the connection, or use 127 # chunked encoding, to determine transfer-length. 128 self.getPage("/stream") 129 self.assertNoHeader("Content-Length") 130 131 chunked_response = False 132 for k, v in self.headers: 133 if k.lower() == "transfer-encoding": 134 if str(v) == "chunked": 135 chunked_response = True 136 137 if chunked_response: 138 self.assertNoHeader("Connection", "close") 147 self.PROTOCOL = "HTTP/1.0" 148 149 self.persistent = True 150 151 # Make the first request and assert Keep-Alive. 152 self.getPage("/", headers=[("Connection", "Keep-Alive")]) 153 self.assertStatus('200 OK') 154 self.assertBody(pov) 155 self.assertHeader("Connection", "Keep-Alive") 156 157 # Make another, streamed request on the same connection. 158 if set_cl: 159 # When a Content-Length is provided, the content should 160 # stream without closing the connection. 161 self.getPage("/stream?set_cl=Yes", 162 headers=[("Connection", "Keep-Alive")]) 163 self.assertHeader("Content-Length") 164 self.assertHeader("Connection", "Keep-Alive") 165 self.assertNoHeader("Transfer-Encoding") 166 self.assertStatus('200 OK') 167 self.assertBody('0123456789') 139 168 else: 140 self.assertHeader("Connection", "close") 169 # When a Content-Length is not provided, 170 # the server should close the connection. 171 self.getPage("/stream", headers=[("Connection", "Keep-Alive")]) 172 self.assertStatus('200 OK') 173 self.assertBody('0123456789') 174 175 self.assertNoHeader("Content-Length") 176 self.assertNoHeader("Connection", "Keep-Alive") 177 self.assertNoHeader("Transfer-Encoding") 141 178 142 179 # Make another request on the same connection, which should error. 143 180 self.assertRaises(httplib.NotConnected, self.getPage, "/") 144 145 self.assertStatus('200 OK')146 self.assertBody('0123456789')147 181 148 182 def test_HTTP11_Timeout(self): trunk/cherrypy/wsgiserver.py
r1564 r1565 237 237 if environ.get("HTTP_CONNECTION", "") == "close": 238 238 self.close_connection = True 239 self.outheaders.append(("Connection", "close"))240 239 else: 241 240 # HTTP/1.0 242 if environ.get("HTTP_CONNECTION", "") == "Keep-Alive": 243 if self.close_connection == False: 244 self.outheaders.append(("Connection", "Keep-Alive")) 245 else: 241 if environ.get("HTTP_CONNECTION", "") != "Keep-Alive": 246 242 self.close_connection = True 247 243 248 244 # Transfer-Encoding support 249 te = environ.get("HTTP_TRANSFER_ENCODING", "") 250 te = [x.strip() for x in te.split(",") if x.strip()] 245 te = None 246 if self.response_protocol == "HTTP/1.1": 247 te = environ.get("HTTP_TRANSFER_ENCODING") 248 if te: 249 te = [x.strip().lower() for x in te.split(",") if x.strip()] 250 251 read_chunked = False 252 251 253 if te: 252 while te: 253 enc = te.pop() 254 if enc.lower() == "chunked": 255 if not self.decode_chunked(): 256 return 254 for enc in te: 255 if enc == "chunked": 256 read_chunked = True 257 257 else: 258 # Note that, even if we see "chunked", we must reject 259 # if there is an extension we don't recognize. 258 260 self.simple_response("501 Unimplemented") 259 261 self.close_connection = True 260 262 return 263 264 if read_chunked: 265 if not self.decode_chunked(): 266 return 261 267 else: 262 268 cl = environ.get("CONTENT_LENGTH") … … 421 427 status = int(self.status[:3]) 422 428 423 if s elf.response_protocol == 'HTTP/1.1':424 if status == 413:425 # Request Entity Too Large. Close conn to avoid garbage.426 self.close_connection = True427 elif "content-length" not in hkeys:428 # "All 1xx (informational), 204 (no content),429 # and 304 (not modified) responses MUST NOT430 # include a message-body." So no point chunking.431 if status < 200 or status in (204, 205, 304):432 pass433 else:429 if status == 413: 430 # Request Entity Too Large. Close conn to avoid garbage. 431 self.close_connection = True 432 elif "content-length" not in hkeys: 433 # "All 1xx (informational), 204 (no content), 434 # and 304 (not modified) responses MUST NOT 435 # include a message-body." So no point chunking. 436 if status < 200 or status in (204, 205, 304): 437 pass 438 else: 439 if self.response_protocol == 'HTTP/1.1': 434 440 # Use the chunked transfer-coding 435 441 self.chunked_write = True 436 442 self.outheaders.append(("Transfer-Encoding", "chunked")) 437 438 if self.close_connection and "connection" not in hkeys: 439 self.outheaders.append(("Connection", "close")) 443 else: 444 # Closing the conn is the only way to determine len. 445 self.close_connection = True 446 447 if "connection" not in hkeys: 448 if self.response_protocol == 'HTTP/1.1': 449 if self.close_connection: 450 self.outheaders.append(("Connection", "close")) 451 else: 452 if not self.close_connection: 453 self.outheaders.append(("Connection", "Keep-Alive")) 440 454 441 455 if "date" not in hkeys:

