我在基于Werkzeug的应用程序中设置了一个中间件,为我做一些JSON转义和操作(尤其是为基于Angular的REST客户端添加转义字符串JSON前缀)。
我想将整个逻辑保留在中间件层中,不要在我的基本视图类或我的基本应用程序中添加任何技巧。
因为我的中间件操纵内容我从标题中删除Content-Length标题,但我想成为一名好网友并向客户提供该信息。
不幸的是,在我操纵内容时,似乎无法再调整标题。我是否必须在管道中进一步做到这一点?在它周围包裹第二个中间件?
以下是中间件的代码:
class ContentManipulatingMiddle(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
app = self.app
def start_unpack_data(status, response_headers, exc_info=None):
# we need to strip content-length
response_headers = [ (name, value)
for name, value in response_headers
if name.lower() != 'content-length' ]
return start_response(status, response_headers, exc_info)
app_iter = app(environ, start_unpack_data)
data = []
for item in app_iter:
# do some content manipulation
data.append(manipulate_content(item))
# content length has changed, i should reset the content-length header
# but at this point, how?
return data
答案 0 :(得分:0)
您不必担心删除/添加/更改内容长度标头,服务器在发送响应时会自动处理。发送错误的长度标题可能会给您的网站查看者/互联网浏览器带来问题。
您可以在此处测试内容长度标题 - http://www.dekho-ji.com/website-diagnostics-curl-http-request-response-headers-online
答案 1 :(得分:0)
能够通过不允许将内部应用更改为start_response
来更改标头,而是为其提供了收集器伪函数:
class MyMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
inner_status = None
inner_headers = []
inner_exc_info = None
def start_response_collector(status, headers, exc_info=None):
# Just collects the inner response headers, to be modified before sending to client
nonlocal inner_status, inner_headers, inner_exc_info
inner_status = status
inner_headers = headers
inner_exc_info = exc_info
# Not calling start_response(), as we will modify the headers first.
return None
# populates the inner_* vars, as triggers inner call of the collector closure
response_iter = self.app(environ, start_response_collector)
# removes the content-length, if exists
headers = [(k, v) for k, v in inner_headers if k.lower() != 'content-length']
inner_body = b"".join(response_iter)
### MANIPULATE YOUR `inner_body` HERE ###
# E.g. producing a final_body
final_body = b'DEADBEEF'
final_body_length = len(final_body)
headers.append(('Content-Length', str(final_body_length)))
# Remember to send the modified headers!
start_response(inner_status, headers, inner_exc_info)
return final_body