4

nginx、uwsgi、およびフラスコでチャンク転送エンコーディングを使用すると、Content-Length常にTransfer-Encoding: chunked. ただし、HTTP 1.1 ではこの動作が禁止されています。nginx と uwsgi を構成して目的の動作を実現しようとしましたが (Content-Lengthヘッダーにない場合Transfer-Encoding: chunked)、成功しませんでした。まず、サーバーとクライアントのコードがあります。

サーバーコード ( server.py):

from flask import Flask
from flask import request

application = Flask(__name__)

@application.route('/', methods=['PUT'])
def hello():
    print(request.headers)
    print(request.environ.get('SERVER_PROTOCOL'))
    return "Hello World!"

if __name__ == "__main__":
    application.run(host='0.0.0.0')

クライアント コード ( client.py):

import requests

def get_data():
    yield b'This is test file.'
    yield b'This is test file.'

r = requests.request(
    method='PUT',
    url='http://127.0.0.1:5000/',
    data=get_data(),
    headers={
        'Content-type': 'text/plain',
        'X-Accel-Buffering': 'no',
    }
)
print('Response: ', r.text)

サーバーを実行し、クライアントでサーバーに接続しようとすると、次の出力が得られます。サーバー出力:

* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Host: 127.0.0.1:5000
User-Agent: python-requests/2.18.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Type: text/plain
X-Accel-Buffering: no
Transfer-Encoding: chunked


HTTP/1.1
[pid: 18455|app: 0|req: 1/1] 127.0.0.1 () {34 vars in 412 bytes} [Wed Jan 17 08:24:53 2018] PUT / => generated 12 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0)

クライアント出力:

Response:  Hello World!

今のところ、すべて問題ないようです。ヘッダーには、Transfer-EncodingなしがありContent-Lengthます。ここで、uwsgi ( uwsgi.py) を組み込んでみます:

from server import application

if __name__ == "__main__":
    application.run()

次のコマンドを実行します。

$ uwsgi --http-socket localhost:5000 -w wsgi

出力は、前の試行と同じです。したがって、まだ予想どおりです。では、nginx をデプロイしてみます。私の uwsgi 設定 ( uwsgi.ini):

[uwsgi]
module = wsgi

master = true
processes = 5

socket = /tmp/flask.sock
chmod-socket = 777
vacuum = true

die-on-term = true

私のnginx構成(/etc/nginx/nginx.conf):

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen 5000;
        server_name 127.0.0.1;

        location / {
            include uwsgi_params;
            uwsgi_pass unix:/tmp/flask.sock;
            proxy_request_buffering off;
            proxy_buffering off;
            proxy_http_version 1.1;
            chunked_transfer_encoding on;
        }
        proxy_request_buffering off;
        proxy_buffering off;
        proxy_http_version 1.1;
        chunked_transfer_encoding on;
    }
}

nginx を起動してから実行します。

$ uwsgi --ini uwsgi.ini --wsgi-manage-chunked-input --http-raw-body --http-auto-chunked --http-chunked-input

現在、出力には次が含まれていますContent-Length

Content-Type: text/plain
Content-Length: 36
Host: 127.0.0.1:5000
User-Agent: python-requests/2.18.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
X-Accel-Buffering: no
Transfer-Encoding: chunked

HTTP/1.1
[pid: 20220|app: 0|req: 1/1] 127.0.0.1 () {42 vars in 525 bytes} [Wed Jan 17 08:31:39 2018] PUT / => generated 12 bytes in 1 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0)

nginx: proxy_request_bufferingproxy_bufferingproxy_http_versionおよびとのコンテキストでさまざまな設定を試してみましたが、成功しませんでしたchunked_transfer_encoding。ヘッダーに追加しましたが、問題は解決しませんでした。また、目的の動作を達成せずに uwsgi: 、、のさまざまなオプションを試しました (のヘッダーにはまだ存在します)。serverlocationX-Accel-Buffering: nowsgi-manage-chunked-inputhttp-raw-bodyhttp-auto-chunkedhttp-chunked-inputContent-LengthTransfer-Encoding: chunked

次のバージョンのフラスコ、uwsgi、nginx を使用しています。

Flask==0.12.2
uWSGI===2.1-dev-f74553db
nginx 1.12.2-2

何が間違っている可能性がありますか?ありがとう。

4

1 に答える 1