Fix a bug where eventlet.wsgi was sending chunked encoding to http/1.0 clients, which isn't legal. Also, tests for chunked encoding, and the absence of chunked encoding in http/1.0
This commit is contained in:
		@@ -23,7 +23,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import cgi
 | 
			
		||||
import errno
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
@@ -202,7 +201,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
 | 
			
		||||
        try:
 | 
			
		||||
            num_blocks = len(result)
 | 
			
		||||
        except (TypeError, AttributeError, NotImplementedError):
 | 
			
		||||
            if self.protocol_version == 'HTTP/1.1':
 | 
			
		||||
            if self.request_version == 'HTTP/1.1':
 | 
			
		||||
                use_chunked = True
 | 
			
		||||
        try:
 | 
			
		||||
            try:
 | 
			
		||||
@@ -211,7 +210,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
 | 
			
		||||
                    for data in result:
 | 
			
		||||
                        if data:
 | 
			
		||||
                            towrite.append(data)
 | 
			
		||||
                            if sum([len(x) for x in towrite]) > 4096:
 | 
			
		||||
                            if use_chunked and sum(map(len, towrite)) > 4096:
 | 
			
		||||
                                write(''.join(towrite))
 | 
			
		||||
                                del towrite[:]
 | 
			
		||||
                except Exception, e:
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,20 @@ def hello_world(env, start_response):
 | 
			
		||||
    return ["hello world"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def chunked_app(env, start_response):
 | 
			
		||||
    start_response('200 OK', [('Content-type', 'text/plain')])
 | 
			
		||||
    yield "this"
 | 
			
		||||
    yield "is"
 | 
			
		||||
    yield "chunked"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def big_chunks(env, start_response):
 | 
			
		||||
    start_response('200 OK', [('Content-type', 'text/plain')])
 | 
			
		||||
    line = 'a' * 8192
 | 
			
		||||
    for x in range(10):
 | 
			
		||||
        yield line
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Site(object):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.application = hello_world
 | 
			
		||||
@@ -217,6 +231,41 @@ class TestHttpd(tests.TestCase):
 | 
			
		||||
        self.assertEqual(response_line_200,response_line_test)
 | 
			
		||||
        fd.close()
 | 
			
		||||
 | 
			
		||||
    def test_009_chunked_response(self):
 | 
			
		||||
        self.site.application = chunked_app
 | 
			
		||||
        sock = api.connect_tcp(
 | 
			
		||||
            ('127.0.0.1', 12346))
 | 
			
		||||
        
 | 
			
		||||
        fd = sock.makefile()
 | 
			
		||||
        fd.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
 | 
			
		||||
        self.assert_('Transfer-Encoding: chunked' in fd.read())
 | 
			
		||||
 | 
			
		||||
    def test_010_no_chunked_http_1_0(self):
 | 
			
		||||
        self.site.application = chunked_app
 | 
			
		||||
        sock = api.connect_tcp(
 | 
			
		||||
            ('127.0.0.1', 12346))
 | 
			
		||||
        
 | 
			
		||||
        fd = sock.makefile()
 | 
			
		||||
        fd.write('GET / HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n')
 | 
			
		||||
        self.assert_('Transfer-Encoding: chunked' not in fd.read())
 | 
			
		||||
 | 
			
		||||
    def test_011_multiple_chunks(self):
 | 
			
		||||
        self.site.application = big_chunks
 | 
			
		||||
        sock = api.connect_tcp(
 | 
			
		||||
            ('127.0.0.1', 12346))
 | 
			
		||||
        
 | 
			
		||||
        fd = sock.makefile()
 | 
			
		||||
        fd.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
 | 
			
		||||
        headers = fd.readuntil('\r\n\r\n')
 | 
			
		||||
        self.assert_('Transfer-Encoding: chunked' in headers)
 | 
			
		||||
        chunks = 0
 | 
			
		||||
        chunklen = int(fd.readline(), 16)
 | 
			
		||||
        while chunklen:
 | 
			
		||||
            chunks += 1
 | 
			
		||||
            chunk = fd.read(chunklen)
 | 
			
		||||
            fd.readline()
 | 
			
		||||
            chunklen = int(fd.readline(), 16)
 | 
			
		||||
        self.assert_(chunks > 1)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    tests.main()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user