wsgi: simplified send logic
This commit is contained in:
@@ -181,9 +181,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
header_dict = {}
|
header_dict = {}
|
||||||
|
|
||||||
wfile = self.wfile
|
wfile = self.wfile
|
||||||
num_blocks = None
|
|
||||||
result = None
|
result = None
|
||||||
use_chunked = False
|
use_chunked = [False]
|
||||||
length = [0]
|
length = [0]
|
||||||
status_code = [200]
|
status_code = [200]
|
||||||
|
|
||||||
@@ -203,17 +202,15 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
# send Date header?
|
# send Date header?
|
||||||
if 'date' not in header_dict:
|
if 'date' not in header_dict:
|
||||||
towrite.append('Date: %s\r\n' % (format_date_time(time.time()),))
|
towrite.append('Date: %s\r\n' % (format_date_time(time.time()),))
|
||||||
if num_blocks is not None:
|
if self.request_version == 'HTTP/1.0':
|
||||||
if 'content-length' not in header_dict:
|
|
||||||
towrite.append('Content-Length: %s\r\n' % (len(''.join(result)),))
|
|
||||||
elif use_chunked:
|
|
||||||
towrite.append('Transfer-Encoding: chunked\r\n')
|
|
||||||
else:
|
|
||||||
towrite.append('Connection: close\r\n')
|
towrite.append('Connection: close\r\n')
|
||||||
self.close_connection = 1
|
self.close_connection = 1
|
||||||
|
elif 'content-length' not in header_dict:
|
||||||
|
use_chunked[0] = True
|
||||||
|
towrite.append('Transfer-Encoding: chunked\r\n')
|
||||||
towrite.append('\r\n')
|
towrite.append('\r\n')
|
||||||
|
|
||||||
if use_chunked:
|
if use_chunked[0]:
|
||||||
## Write the chunked encoding
|
## Write the chunked encoding
|
||||||
towrite.append("%x\r\n%s\r\n" % (len(data), data))
|
towrite.append("%x\r\n%s\r\n" % (len(data), data))
|
||||||
else:
|
else:
|
||||||
@@ -258,37 +255,25 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
||||||
write(exc)
|
write(exc)
|
||||||
return
|
return
|
||||||
try:
|
if not headers_sent and hasattr(result, '__len__'):
|
||||||
num_blocks = len(result)
|
headers_set[1].append(('content-length', str(sum(map(len, result)))))
|
||||||
except (TypeError, AttributeError, NotImplementedError):
|
|
||||||
if self.request_version == 'HTTP/1.1':
|
|
||||||
use_chunked = True
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
towrite = []
|
towrite = []
|
||||||
try:
|
for data in result:
|
||||||
for data in result:
|
if data:
|
||||||
if data:
|
write(data)
|
||||||
towrite.append(data)
|
|
||||||
if use_chunked and sum(map(len, towrite)) > self.minimum_chunk_size:
|
|
||||||
write(''.join(towrite))
|
|
||||||
del towrite[:]
|
|
||||||
except Exception, e:
|
|
||||||
exc = traceback.format_exc()
|
|
||||||
print exc
|
|
||||||
if not headers_set:
|
|
||||||
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
|
||||||
write(exc)
|
|
||||||
return
|
|
||||||
|
|
||||||
if towrite:
|
|
||||||
write(''.join(towrite))
|
|
||||||
if not headers_sent:
|
if not headers_sent:
|
||||||
write('')
|
write('')
|
||||||
if use_chunked:
|
if use_chunked[0]:
|
||||||
wfile.write('0\r\n\r\n')
|
wfile.write('0\r\n\r\n')
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
traceback.print_exc()
|
exc = traceback.format_exc()
|
||||||
|
print exc
|
||||||
|
if not headers_set:
|
||||||
|
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
||||||
|
write(exc)
|
||||||
|
return
|
||||||
finally:
|
finally:
|
||||||
if hasattr(result, 'close'):
|
if hasattr(result, 'close'):
|
||||||
result.close()
|
result.close()
|
||||||
|
@@ -57,6 +57,16 @@ def big_chunks(env, start_response):
|
|||||||
for x in range(10):
|
for x in range(10):
|
||||||
yield line
|
yield line
|
||||||
|
|
||||||
|
def use_write(env, start_response):
|
||||||
|
if env['PATH_INFO'] == '/a':
|
||||||
|
write = start_response('200 OK', [('Content-type', 'text/plain'),
|
||||||
|
('Content-Length', '5')])
|
||||||
|
write('abcde')
|
||||||
|
if env['PATH_INFO'] == '/b':
|
||||||
|
write = start_response('200 OK', [('Content-type', 'text/plain')])
|
||||||
|
write('abcde')
|
||||||
|
return []
|
||||||
|
|
||||||
def chunked_post(env, start_response):
|
def chunked_post(env, start_response):
|
||||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||||
if env['PATH_INFO'] == '/a':
|
if env['PATH_INFO'] == '/a':
|
||||||
@@ -328,5 +338,20 @@ class TestHttpd(TestCase):
|
|||||||
response = fd.read(8192)
|
response = fd.read(8192)
|
||||||
self.assert_(response == 'oh hai', 'invalid response %s' % response)
|
self.assert_(response == 'oh hai', 'invalid response %s' % response)
|
||||||
|
|
||||||
|
def test_015_write(self):
|
||||||
|
self.site.application = use_write
|
||||||
|
sock = api.connect_tcp(('127.0.0.1', 12346))
|
||||||
|
fd = sock.makeGreenFile()
|
||||||
|
fd.write('GET /a HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
|
||||||
|
response_line, headers, body = read_http(sock)
|
||||||
|
self.assert_('content-length' in headers)
|
||||||
|
|
||||||
|
sock = api.connect_tcp(('127.0.0.1', 12346))
|
||||||
|
fd = sock.makeGreenFile()
|
||||||
|
fd.write('GET /b HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
|
||||||
|
response_line, headers, body = read_http(sock)
|
||||||
|
self.assert_('transfer-encoding' in headers)
|
||||||
|
self.assert_(headers['transfer-encoding'] == 'chunked')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
Reference in New Issue
Block a user