在包含unicode_literals的Flask应用程序中添加标题 [英] Add headers in a Flask app with unicode_literals

查看:158
本文介绍了在包含unicode_literals的Flask应用程序中添加标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

添加启用了unicode_literals的头文件似乎与Nginx,uWSGI和一个简单的Flask应用程序失败:

 # -  *  -  coding :utf-8  -  *  -  
from __future__ import unicode_literals $ b $ from flask flask烧瓶,make_response

app =烧瓶('test')

@ app.route('/')
def index():
response = make_response()
response.status_code = 401
response.headers = {'WWW-Authenticate': 'Basic realm ='test''}#失败
#response.headers = {b'WWW-Authenticate':b'Basic realm =test'}#成功
返回响应

if __name__ =='__main__':
app.run(debug = True)

该应用程序可直接用于调试目的,也可以通过Nginx - > uWSGI - > Flask运行。


  • 当我使用浏览器直接连接到应用程序,我有一个登录对话框,
    WWW-Authenticate 标头是正确的。

  • <李>同样的请求通过Nginx返回一个头 Transfert-Encoding:chunked
    丢弃 WWW-Authenticate 头。


强制字符串( b'...')格式添加标题使应用程序按预期工作在这两种情况下。
文件以UTF-8编码,Python解释器有一个
编码声明。
我们使用Python 2.7.3,Nginx 1.4.2和uWSGI 1.3。

Nginx或uWSGI,Flask和unicode_literals之间是否存在任何已知的不兼容性?
Thanks!


编辑:
问题似乎来自uWSGI(
https://github.com/unbit/uwsgi/blob/master/plugins/python/wsgi_headers.c# L116 ),因为它只检查PyString而不检查Python2的PyUnicode,如果我理解这个代码正确。



编辑:
Armin Ronacher has修复了类似的错误( https://github.com/mitsuhiko/flask/issues/758)5个月前,但我没有在werkzeug git log中找到提交。我不知道该修补程序的作用域是 redirect()函数还是更广泛地处理标题。我使用的是Werkzeug 0.9.4和Flask 0.10.1。

解决方案

这个问题确实是由于 WERKZEUG 即可。正如您注意到的,自2013年6月4日起,现已更正(参见相关的提交在Github上)。您可以使用 0.9.5 而不是 0.9.4 的版本获得Werkzeug的免费版本。

<此外,为了解决您的问题,我在Flask应用程序的初始化之后添加了 app.debug = True 。这允许我在uWSGI日志中得到以下错误:
$ b $ pre $ code Traceback最近一次调用最后一次
文件 /home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/flask/app.py,第1836行,在__call__
中返回self.wsgi_app(environ,start_response)
文件/home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/flask/app.py,行1821,在wsgi_app
返回响应(environ,start_response)
文件/home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/werkzeug/wrappers.py,行1201,在__call__
start_response(status,headers)
TypeError:http头键必须是字符串

这对应于您在Github上找到的bug



因此,您可以使用以下解决方法获取 Flask / Werkzeug unicode_literals
$ $ p $ response.headers = {b'WWW-Authenticate':'Basic realm =test'}

或者:

  response.headers = {str('WWW-Authenticate'):'Basic realm =test'} 

但是我建议只要更新你的Werkzeug版本到> = 0.9.5就可以了。



另外请注意,虽然<$ c Flask / Werkzeug响应的$ c> headers 属性的行为类似于字典,实际上它是一个 Headers 对象(请参阅 Werkzeug源代码)。因此,我建议你如下使用它:

  response.headers ['WWW-Authenticate'] ='Basic realm = test'

你可以在 Flask文档 make_response p>

Adding headers with unicode_literals enabled seems to fail with Nginx, uWSGI and a simple Flask app:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from flask import Flask, make_response

app = Flask('test')

@app.route('/')
def index():
    response = make_response()
    response.status_code = 401
    response.headers = {'WWW-Authenticate': 'Basic realm="test"'} # Fail
    # response.headers = {b'WWW-Authenticate': b'Basic realm="test"'} # Succeed
    return response

if __name__ == '__main__':
    app.run(debug=True)

The app is available directly for debug purpose or through Nginx -> uWSGI -> Flask and works well.

  • When I use a browser to connect directly to the app, I've got a login dialog and the WWW-Authenticate header is correct.
  • The same request going through Nginx returns a header Transfert-Encoding: chunked and discard the WWW-Authenticate header.

Forcing bytestring (b'...') format to add the header make the app works as expected in both cases. The file is encoded in UTF-8 and there's acoding` declaration for the Python interpreter. We're using Python 2.7.3, Nginx 1.4.2 and uWSGI 1.3.

Is there any known incompatibility between Nginx or uWSGI, Flask and unicode_literals? Thanks!

edit: The problem seems to come from uWSGI ( https://github.com/unbit/uwsgi/blob/master/plugins/python/wsgi_headers.c#L116), since it only checks for PyString and not PyUnicode for Python2, if I understand this code correctly.

edit: Armin Ronacher has fixed a similar bug (https://github.com/mitsuhiko/flask/issues/758) 5 months ago, but I didn't find the commit in werkzeug git log yet. I don't know if the fix is scoped to the redirect() function or more broadly on headers handling. I'm using Werkzeug 0.9.4 and Flask 0.10.1.

解决方案

This problem is indeed due to a bug in Werkzeug. As you noticed, this is now corrected since Jun 4, 2013 (cf. the related commit on Github). You can have a bug free version of Werkzeug by using the version 0.9.5 instead of the 0.9.4.

Moreover, to troubleshoot your problem, I added app.debug = True just after the initialization of your Flask application. This allows me to got the following error in uWSGI logs:

Traceback (most recent call last):
  File "/home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/flask/app.py", line 1821, in wsgi_app
    return response(environ, start_response)
  File "/home/afigura/.virtualenvs/stack-python2/lib/python2.7/site-packages/werkzeug/wrappers.py", line 1201, in __call__
    start_response(status, headers)
TypeError: http header key must be a string

This corresponds to the error mentioned in the bug you found on Github.

So, you can use the following workaround to get Flask/Werkzeug working with unicode_literals:

response.headers = {b'WWW-Authenticate': 'Basic realm="test"'}

Or:

response.headers = {str('WWW-Authenticate'): 'Basic realm="test"'}

But I recommend to simply update your Werkzeug version to >=0.9.5 if you can.

Also, please note that although the headers attribute of a Flask/Werkzeug response behaves like a dictionary, it is in fact a Headers object (see Werkzeug source code). Hence, I advise you to use it as follows:

response.headers['WWW-Authenticate'] = 'Basic realm="test"'

You can see some examples about this on the Flask documentation of the function make_response.

这篇关于在包含unicode_literals的Flask应用程序中添加标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆