process headers only when application is processed
An application can modify the headers after start_response have been processed. So we have to store the references of the headers list. And write them to the client only when the application have been processed but before we iter the body. wsgiref and weboob already does the same thing.
This commit is contained in:
@@ -85,3 +85,12 @@ def test_encoding_errors():
|
||||
response, content = http.request(
|
||||
'http://some_hopefully_nonexistant_domain/boom/baz',
|
||||
headers={'Accept': u'application/\u2603'})
|
||||
|
||||
|
||||
def test_post_status_headers():
|
||||
with InstalledApp(wsgi_app.post_status_headers_app, host=HOST) as app:
|
||||
http = httplib2.Http()
|
||||
resp, content = http.request(
|
||||
'http://some_hopefully_nonexistant_domain/', 'GET')
|
||||
assert app.success()
|
||||
assert resp.get('content-type') == 'text/plain'
|
||||
|
||||
@@ -23,5 +23,12 @@ def more_interesting_app(environ, start_response):
|
||||
return [pformat(environ).encode('utf-8')]
|
||||
|
||||
|
||||
def post_status_headers_app(environ, start_response):
|
||||
headers = []
|
||||
start_response('200 OK', headers)
|
||||
headers.append(('Content-type', 'text/plain'))
|
||||
return [b'WSGI intercept successful!\n']
|
||||
|
||||
|
||||
def raises_app(environ, start_response):
|
||||
raise TypeError("bah")
|
||||
|
||||
@@ -375,25 +375,15 @@ class wsgi_fake_socket:
|
||||
|
||||
# dynamically construct the start_response function for no good reason.
|
||||
|
||||
self.headers = []
|
||||
|
||||
def start_response(status, headers, exc_info=None):
|
||||
# construct the HTTP request.
|
||||
self.output.write(b"HTTP/1.0 " + status.encode('utf-8') + b"\n")
|
||||
|
||||
for k, v in headers:
|
||||
try:
|
||||
k = k.encode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
v = v.encode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
self.output.write(k + b': ' + v + b"\n")
|
||||
self.output.write(b'\n')
|
||||
|
||||
def write_fn(s):
|
||||
self.write_results.append(s)
|
||||
return write_fn
|
||||
# Keep the reference of the headers list to write them only
|
||||
# when the whole application have been processed
|
||||
self.headers = headers
|
||||
return self.write_results.append
|
||||
|
||||
# construct the wsgi.input file from everything that's been
|
||||
# written to this "socket".
|
||||
@@ -411,6 +401,20 @@ class wsgi_fake_socket:
|
||||
raise WSGIAppError(error, sys.exc_info())
|
||||
self.result = iter(app_result)
|
||||
|
||||
# send the headers
|
||||
|
||||
for k, v in self.headers:
|
||||
try:
|
||||
k = k.encode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
v = v.encode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
self.output.write(k + b': ' + v + b"\n")
|
||||
self.output.write(b'\n')
|
||||
|
||||
###
|
||||
|
||||
# read all of the results. the trick here is to get the *first*
|
||||
|
||||
Reference in New Issue
Block a user