mirror of
https://github.com/kennethreitz/httpbin.git
synced 2026-06-05 14:50:17 +00:00
Merge pull request #405 from javabrett/support-chunked-340
Added support for chunked encoded requests when running gunicorn. #340
This commit is contained in:
+25
-1
@@ -15,7 +15,7 @@ import time
|
||||
import uuid
|
||||
import argparse
|
||||
|
||||
from flask import Flask, Response, request, render_template, redirect, jsonify as flask_jsonify, make_response, url_for
|
||||
from flask import Flask, Response, request, render_template, redirect, jsonify as flask_jsonify, make_response, url_for, abort
|
||||
from flask_common import Common
|
||||
from six.moves import range as xrange
|
||||
from werkzeug.datastructures import WWWAuthenticate, MultiDict
|
||||
@@ -84,6 +84,30 @@ if os.environ.get("BUGSNAG_API_KEY") is not None:
|
||||
# -----------
|
||||
# Middlewares
|
||||
# -----------
|
||||
"""
|
||||
https://github.com/kennethreitz/httpbin/issues/340
|
||||
Adds a middleware to provide chunked request encoding support running under
|
||||
gunicorn only.
|
||||
Werkzeug required environ 'wsgi.input_terminated' to be set otherwise it
|
||||
empties the input request stream.
|
||||
- gunicorn seems to support input_terminated but does not add the environ,
|
||||
so we add it here.
|
||||
- flask will hang and does not seem to properly terminate the request, so
|
||||
we explicityly deny chunked requests.
|
||||
"""
|
||||
@app.before_request
|
||||
def before_request():
|
||||
if request.environ.get('HTTP_TRANSFER_ENCODING', '').lower() == 'chunked':
|
||||
server = request.environ.get('SERVER_SOFTWARE', '')
|
||||
if server.lower().startswith('gunicorn/'):
|
||||
if 'wsgi.input_terminated' in request.environ:
|
||||
app.logger.debug("environ wsgi.input_terminated already set, keeping: %s"
|
||||
% request.environ['wsgi.input_terminated'])
|
||||
else:
|
||||
request.environ['wsgi.input_terminated'] = 1
|
||||
else:
|
||||
abort(501, "Chunked requests are not supported for server %s" % server)
|
||||
|
||||
@app.after_request
|
||||
def set_cors_headers(response):
|
||||
response.headers['Access-Control-Allow-Origin'] = request.headers.get('Origin', '*')
|
||||
|
||||
@@ -206,6 +206,25 @@ class HttpbinTestCase(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
"""
|
||||
This is currently a sort of negative-test.
|
||||
We validate that when running Flask-only server that
|
||||
Transfer-Encoding: chunked requests are unsupported and
|
||||
we return 501 Not Implemented
|
||||
"""
|
||||
def test_post_chunked(self):
|
||||
data = '{"animal":"dog"}'
|
||||
response = self.app.post(
|
||||
'/post',
|
||||
content_type='application/json',
|
||||
headers=[('Transfer-Encoding', 'chunked')],
|
||||
data=data,
|
||||
)
|
||||
self.assertEqual(response.status_code, 501)
|
||||
#self.assertEqual(response.status_code, 200)
|
||||
#self.assertEqual(json.loads(response.data.decode('utf-8'))['data'], '{"animal":"dog"}')
|
||||
#self.assertEqual(json.loads(response.data.decode('utf-8'))['json'], {"animal": "dog"})
|
||||
|
||||
def test_set_cors_headers_after_request(self):
|
||||
response = self.app.get('/get')
|
||||
self.assertEqual(
|
||||
|
||||
Reference in New Issue
Block a user