5

unicode_literals を有効にしてヘッダーを追加すると、Nginx、uWSGI、およびシンプルな Flask アプリで失敗するようです:

# -*- 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)

このアプリは、デバッグ目的で直接利用するか、Nginx -> uWSGI -> Flask から利用でき、うまく機能します。

  • ブラウザーを使用してアプリに直接接続すると、ログイン ダイアログが表示され、 WWW-Authenticateヘッダーは正しく表示されます。
  • Nginx を通過する同じリクエストは、ヘッダーを返し、ヘッダーTransfert-Encoding: chunkedを破棄しWWW-Authenticateます。

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 aPython インタープリターのbytestring ( coding` 宣言の強制。Python 2.7.3、Nginx 1.4.2、および uWSGI 1.3 を使用しています。

Nginx または uWSGI、Flask、および unicode_literals の間に既知の非互換性はありますか? ありがとう!

編集: 問題は uWSGI ( https://github.com/unbit/uwsgi/blob/master/plugins/python/wsgi_headers.c#L116 )から発生しているようです。私はこのコードを正しく理解しています。

編集: Armin Ronacher は 5 か月前に同様のバグ ( https://github.com/mitsuhiko/flask/issues/758 ) を修正しましたが、まだ werkzeug git ログでコミットを見つけられませんでした。redirect()修正の範囲が関数に限定されているのか、それともヘッダー処理に広く適用されているのかはわかりません。Werkzeug 0.9.4 と Flask 0.10.1 を使用しています。

4

1 に答える 1

1

この問題は実際にはWerkzeugのバグによるものです。お気付きのように、これは 2013 年 6 月 4 日以降に修正されています (関連するGithubのコミットを参照)。0.9.4の代わりにバージョン0.9.5を使用すると、バグのないバージョンの Werkzeug を使用できます。

さらに、問題をトラブルシューティングするためにapp.debug = True、Flask アプリケーションの初期化の直後に追加しました。これにより、uWSGI ログで次のエラーを取得できます。

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

これは、Github で見つけたバグに記載されているエラーに対応しています。

したがって、次の回避策を使用して、Flask/Werkzeugを で動作させることができunicode_literalsます。

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

または:

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

ただし、できれば Werkzeug のバージョンを >=0.9.5 に更新することをお勧めします。

headersまた、 Flask/Werkzeug 応答の属性は辞書のように動作しますが、実際にはHeadersオブジェクトであることに注意してください( Werkzeug ソース コードを参照)。したがって、次のように使用することをお勧めします。

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

関数のFlask ドキュメントで、これに関するいくつかの例を見ることができますmake_response

于 2015-03-30T09:22:00.943 に答える