wsgi: simplified send logic
This commit is contained in:
@@ -181,9 +181,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
header_dict = {}
|
||||
|
||||
wfile = self.wfile
|
||||
num_blocks = None
|
||||
result = None
|
||||
use_chunked = False
|
||||
use_chunked = [False]
|
||||
length = [0]
|
||||
status_code = [200]
|
||||
|
||||
@@ -203,17 +202,15 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
# send Date header?
|
||||
if 'date' not in header_dict:
|
||||
towrite.append('Date: %s\r\n' % (format_date_time(time.time()),))
|
||||
if num_blocks is not None:
|
||||
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:
|
||||
if self.request_version == 'HTTP/1.0':
|
||||
towrite.append('Connection: close\r\n')
|
||||
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')
|
||||
|
||||
if use_chunked:
|
||||
if use_chunked[0]:
|
||||
## Write the chunked encoding
|
||||
towrite.append("%x\r\n%s\r\n" % (len(data), data))
|
||||
else:
|
||||
@@ -258,37 +255,25 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
||||
write(exc)
|
||||
return
|
||||
try:
|
||||
num_blocks = len(result)
|
||||
except (TypeError, AttributeError, NotImplementedError):
|
||||
if self.request_version == 'HTTP/1.1':
|
||||
use_chunked = True
|
||||
if not headers_sent and hasattr(result, '__len__'):
|
||||
headers_set[1].append(('content-length', str(sum(map(len, result)))))
|
||||
try:
|
||||
try:
|
||||
towrite = []
|
||||
try:
|
||||
for data in result:
|
||||
if 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))
|
||||
for data in result:
|
||||
if data:
|
||||
write(data)
|
||||
if not headers_sent:
|
||||
write('')
|
||||
if use_chunked:
|
||||
if use_chunked[0]:
|
||||
wfile.write('0\r\n\r\n')
|
||||
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:
|
||||
if hasattr(result, 'close'):
|
||||
result.close()
|
||||
|
@@ -57,6 +57,16 @@ def big_chunks(env, start_response):
|
||||
for x in range(10):
|
||||
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):
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
if env['PATH_INFO'] == '/a':
|
||||
@@ -328,5 +338,20 @@ class TestHttpd(TestCase):
|
||||
response = fd.read(8192)
|
||||
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__':
|
||||
main()
|
||||
|
Reference in New Issue
Block a user