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