summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTushar Gohad <tushar.gohad@intel.com>2014-11-05 21:25:26 -0700
committerTushar Gohad <tushar.gohad@intel.com>2014-11-06 08:19:03 -0700
commit01d5e8738b1ca22641badd35fc28b912c51f93fb (patch)
tree9e80746394c3282179a2936d8f11c55184fa6332 /tests
parent67cde41d03c0bccb12fd7d5f6d7e155d6da95e40 (diff)
downloadeventlet-01d5e8738b1ca22641badd35fc28b912c51f93fb.tar.gz
wsgi.input: Make send_hundred_continue_headers a public API
Per HTTP RFC 7231 (http://tools.ietf.org/html/rfc7231#section-6.2) a client is required to be able to process one or more 100 continue responses. -- RFC 7231 -------------------- 6.2. Informational 1xx [snip] A client MUST be able to parse one or more 1xx responses received prior to a final response, even if the client does not expect one. A user agent MAY ignore unexpected 1xx responses. ... -------------------------------- This patch adds a send_hundred_continue_headers() public API method to wsgi.input, thus allowing WSGI apps to send more than one 100- continue response. This does not change existing semantics for the first 100-continue response sent on read() or readline().
Diffstat (limited to 'tests')
-rw-r--r--tests/wsgi_test.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py
index a966038..ed48e6a 100644
--- a/tests/wsgi_test.py
+++ b/tests/wsgi_test.py
@@ -830,6 +830,160 @@ class TestHttpd(_TestBase):
fd.close()
sock.close()
+ def test_024b_expect_100_continue_with_headers_multiple_chunked(self):
+ def wsgi_app(environ, start_response):
+ environ['wsgi.input'].set_hundred_continue_response_headers(
+ [('Hundred-Continue-Header-1', 'H1'),
+ ('Hundred-Continue-Header-2', 'H2')])
+ text = environ['wsgi.input'].read()
+
+ environ['wsgi.input'].set_hundred_continue_response_headers(
+ [('Hundred-Continue-Header-3', 'H3')])
+ environ['wsgi.input'].send_hundred_continue_response()
+
+ text += environ['wsgi.input'].read()
+
+ start_response('200 OK', [('Content-Length', str(len(text)))])
+ return [text]
+ self.site.application = wsgi_app
+ sock = eventlet.connect(('localhost', self.port))
+ fd = sock.makefile('rwb')
+ fd.write(b'PUT /a HTTP/1.1\r\n'
+ b'Host: localhost\r\nConnection: close\r\n'
+ b'Transfer-Encoding: chunked\r\n'
+ b'Expect: 100-continue\r\n\r\n')
+ fd.flush()
+
+ # Expect 1st 100-continue response
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 100 Continue')
+ headers = dict((k, v) for k, v in (h.split(b': ', 1)
+ for h in header_lines[1:]))
+ assert b'Hundred-Continue-Header-1' in headers
+ assert b'Hundred-Continue-Header-2' in headers
+ self.assertEqual(b'H1', headers[b'Hundred-Continue-Header-1'])
+ self.assertEqual(b'H2', headers[b'Hundred-Continue-Header-2'])
+
+ # Send message 1
+ fd.write(b'5\r\nfirst\r\n8\r\n message\r\n0\r\n\r\n')
+ fd.flush()
+
+ # Expect a 2nd 100-continue response
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 100 Continue')
+ headers = dict((k, v) for k, v in (h.split(b': ', 1)
+ for h in header_lines[1:]))
+ assert b'Hundred-Continue-Header-3' in headers
+ self.assertEqual(b'H3', headers[b'Hundred-Continue-Header-3'])
+
+ # Send message 2
+ fd.write(b'8\r\n, second\r\n8\r\n message\r\n0\r\n\r\n')
+ fd.flush()
+
+ # Expect final 200-OK
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 200 OK')
+
+ self.assertEqual(fd.read(29), b'first message, second message')
+ fd.close()
+ sock.close()
+
+ def test_024c_expect_100_continue_with_headers_multiple_nonchunked(self):
+ def wsgi_app(environ, start_response):
+
+ environ['wsgi.input'].set_hundred_continue_response_headers(
+ [('Hundred-Continue-Header-1', 'H1'),
+ ('Hundred-Continue-Header-2', 'H2')])
+ text = environ['wsgi.input'].read(13)
+
+ environ['wsgi.input'].set_hundred_continue_response_headers(
+ [('Hundred-Continue-Header-3', 'H3')])
+ environ['wsgi.input'].send_hundred_continue_response()
+
+ text += environ['wsgi.input'].read(16)
+
+ start_response('200 OK', [('Content-Length', str(len(text)))])
+ return [text]
+
+ self.site.application = wsgi_app
+ sock = eventlet.connect(('localhost', self.port))
+ fd = sock.makefile('rwb')
+ fd.write(b'PUT /a HTTP/1.1\r\n'
+ b'Host: localhost\r\nConnection: close\r\n'
+ b'Content-Length: 29\r\n'
+ b'Expect: 100-continue\r\n\r\n')
+ fd.flush()
+
+ # Expect 1st 100-continue response
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 100 Continue')
+ headers = dict((k, v) for k, v in (h.split(b': ', 1)
+ for h in header_lines[1:]))
+ assert b'Hundred-Continue-Header-1' in headers
+ assert b'Hundred-Continue-Header-2' in headers
+ self.assertEqual(b'H1', headers[b'Hundred-Continue-Header-1'])
+ self.assertEqual(b'H2', headers[b'Hundred-Continue-Header-2'])
+
+ # Send message 1
+ fd.write(b'first message')
+ fd.flush()
+
+ # Expect a 2nd 100-continue response
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 100 Continue')
+ headers = dict((k, v) for k, v in (h.split(b': ', 1)
+ for h in header_lines[1:]))
+ assert b'Hundred-Continue-Header-3' in headers
+ self.assertEqual(b'H3', headers[b'Hundred-Continue-Header-3'])
+
+ # Send message 2
+ fd.write(b', second message\r\n')
+ fd.flush()
+
+ # Expect final 200-OK
+ header_lines = []
+ while True:
+ line = fd.readline()
+ if line == b'\r\n':
+ break
+ else:
+ header_lines.append(line.strip())
+ assert header_lines[0].startswith(b'HTTP/1.1 200 OK')
+
+ self.assertEqual(fd.read(29), b'first message, second message')
+ fd.close()
+ sock.close()
+
def test_025_accept_errors(self):
debug.hub_exceptions(True)
listener = greensocket.socket()