Changeset 1257
- Timestamp:
- 08/20/06 21:54:14
- Files:
-
- trunk/cherrypy/_cpwsgi.py (modified) (1 diff)
- trunk/cherrypy/_cpwsgiserver.py (modified) (7 diffs)
- trunk/cherrypy/test/test_conn.py (modified) (4 diffs)
- trunk/cherrypy/test/webtest.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cpwsgi.py
r1253 r1257 128 128 _cpwsgiserver.HTTPRequest.parse_request(self) 129 129 except http.MaxSizeExceeded: 130 self. abort(413, "Request Entity Too Large")130 self.simple_response(413, "Request Entity Too Large") 131 131 cherrypy.log(traceback=True) 132 132 trunk/cherrypy/_cpwsgiserver.py
r1253 r1257 54 54 request_line = self.rfile.readline() 55 55 except socket.timeout: 56 self.abort("408 Request Timeout") 56 self.simple_response("408 Request Timeout") 57 return 57 58 58 59 if not request_line: … … 95 96 break 96 97 else: 97 self. abort("404 Not Found")98 self.simple_response("404 Not Found") 98 99 return 99 100 … … 117 118 sp = int(server.protocol[5]), int(server.protocol[7]) 118 119 if sp[0] != rp[0]: 119 self. abort("505 HTTP Version Not Supported")120 self.simple_response("505 HTTP Version Not Supported") 120 121 return 121 122 self.environ["SERVER_PROTOCOL"] = "HTTP/%s.%s" % min(rp, sp) … … 136 137 # encoding, always respond with 411 Length Required. 137 138 # See http://www.cherrypy.org/ticket/493. 138 self. abort("411 Length Required")139 self.simple_response("411 Length Required") 139 140 return 140 141 self.environ["CONTENT_LENGTH"] = cl or "" … … 158 159 self.close_connection = True 159 160 161 # From PEP 333: 162 # "Servers and gateways that implement HTTP 1.1 must provide 163 # transparent support for HTTP 1.1's "expect/continue" mechanism. 164 # This may be done in any of several ways: 165 # 1. Respond to requests containing an Expect: 100-continue request 166 # with an immediate "100 Continue" response, and proceed normally. 167 # 2. Proceed with the request normally, but provide the application 168 # with a wsgi.input stream that will send the "100 Continue" 169 # response if/when the application first attempts to read from 170 # the input stream. The read request must then remain blocked 171 # until the client responds. 172 # 3. Wait until the client decides that the server does not support 173 # expect/continue, and sends the request body on its own. 174 # (This is suboptimal, and is not recommended.) 175 # 176 # We used to do 3, but are now doing 1. Maybe we'll do 2 someday, 177 # but it seems like it would be a big slowdown for such a rare case. 178 if headers.getheader("Expect", "") == "100-continue": 179 self.simple_response(100) 180 160 181 self.ready = True 161 182 … … 168 189 self.terminate() 169 190 170 def abort(self, status, msg=""):171 """Write a simple error message back to the client."""191 def simple_response(self, status, msg=""): 192 """Write a simple response back to the client.""" 172 193 status = str(status) 173 194 wfile = self.connection.wfile … … 184 205 wfile.write(msg) 185 206 wfile.flush() 186 self.ready = False187 207 188 208 def start_response(self, status, headers, exc_info = None): trunk/cherrypy/test/test_conn.py
r1256 r1257 6 6 7 7 import cherrypy 8 from cherrypy.test import webtest 8 9 9 10 … … 29 30 stream.exposed = True 30 31 stream._cp_config = {'stream_response': True} 32 33 def upload(self): 34 return "thanks for the %s bytes!" % len(cherrypy.request.body.read()) 35 upload.exposed = True 31 36 32 37 cherrypy.tree.mount(Root()) … … 111 116 conn.close() 112 117 118 def test_100_Continue(self): 119 conn = httplib.HTTPConnection(self.HOST, self.PORT) 120 conn.auto_open = False 121 conn.connect() 122 123 # Try a page without an Expect request header first. 124 # Note that httplib's response.begin automatically ignores 125 # 100 Continue responses, so we must manually check for it. 126 conn.putrequest("POST", "/upload", skip_host=True) 127 conn.putheader("Host", self.HOST) 128 conn.putheader("Content-Type", "text/plain") 129 conn.putheader("Content-Length", "4") 130 conn.endheaders() 131 conn.send("d'oh") 132 response = conn.response_class(conn.sock, method="POST") 133 version, status, reason = response._read_status() 134 self.assertNotEqual(status, 100) 135 conn.close() 136 137 # Now try a page with an Expect header... 138 conn.connect() 139 conn.putrequest("POST", "/upload", skip_host=True) 140 conn.putheader("Host", self.HOST) 141 conn.putheader("Content-Type", "text/plain") 142 conn.putheader("Content-Length", "17") 143 conn.putheader("Expect", "100-continue") 144 conn.endheaders() 145 response = conn.response_class(conn.sock, method="POST") 146 147 # ...assert and then skip the 100 response 148 version, status, reason = response._read_status() 149 self.assertEqual(status, 100) 150 while True: 151 skip = response.fp.readline().strip() 152 if not skip: 153 break 154 155 # ...send the body 156 conn.send("I am a small file") 157 158 # ...get the final response 159 response.begin() 160 self.status, self.headers, self.body = webtest.shb(response) 161 self.assertStatus(200) 162 self.assertBody("thanks for the 17 bytes!") 163 113 164 def test_HTTP10(self): 114 self.PROTOCOL = "HTTP/1. 1"165 self.PROTOCOL = "HTTP/1.0" 115 166 self.HTTP_CONN = httplib.HTTPConnection 116 167 117 168 # Test a normal HTTP/1.0 request. 118 self.getPage("/page2" , protocol="HTTP/1.0")169 self.getPage("/page2") 119 170 self.assertStatus('200 OK') 120 171 self.assertBody(pov) … … 123 174 # Test a keep-alive HTTP/1.0 request. 124 175 self.HTTP_CONN = httplib.HTTPConnection(self.HOST, self.PORT) 125 self.getPage("/page3", headers=[("Connection", "Keep-Alive")], 126 protocol="HTTP/1.0") 176 self.HTTP_CONN.auto_open = False 177 self.HTTP_CONN.connect() 178 179 self.getPage("/page3", headers=[("Connection", "Keep-Alive")]) 127 180 self.assertStatus('200 OK') 128 181 self.assertBody(pov) 129 182 self.assertHeader("Connection", "Keep-Alive") 130 183 131 # Test a keep-alive HTTP/1.0 request.132 self.getPage("/page3" , protocol="HTTP/1.0")184 # Remove the keep-alive header again. 185 self.getPage("/page3") 133 186 self.assertStatus('200 OK') 134 187 self.assertBody(pov) trunk/cherrypy/test/webtest.py
r1253 r1257 356 356 357 357 358 def shb(response): 359 """Return status, headers, body the way we like from a response.""" 360 h = [] 361 key, value = None, None 362 for line in response.msg.headers: 363 if line: 364 if line[0] in " \t": 365 value += line.strip() 366 else: 367 if key and value: 368 h.append((key, value)) 369 key, value = line.split(":", 1) 370 key = key.strip() 371 value = value.strip() 372 if key and value: 373 h.append((key, value)) 374 375 return "%s %s" % (response.status, response.reason), h, response.read() 376 377 358 378 def openURL(url, headers=None, method="GET", body=None, 359 379 host="127.0.0.1", port=8000, http_conn=httplib.HTTPConnection, … … 394 414 response = conn.getresponse() 395 415 396 status = "%s %s" % (response.status, response.reason) 397 398 outheaders = [] 399 key, value = None, None 400 for line in response.msg.headers: 401 if line: 402 if line[0] in " \t": 403 value += line.strip() 404 else: 405 if key and value: 406 outheaders.append((key, value)) 407 key, value = line.split(":", 1) 408 key = key.strip() 409 value = value.strip() 410 if key and value: 411 outheaders.append((key, value)) 412 413 outbody = response.read() 416 s, h, b = shb(response) 414 417 415 418 if not hasattr(http_conn, "host"): … … 417 420 conn.close() 418 421 419 return s tatus, outheaders, outbody422 return s, h, b 420 423 except socket.error: 421 424 trial += 1

