ОБНОВЛЕНИЕ : Похоже, это связано с ошибкой: https://github.com/mopemope/meinheld/pull/102
Минимальные файлы:
У меня есть следующее веб-приложение Flask:
# hello.py
from flask import Flask, request
app = Flask(__name__)
data = {}
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'PUT'])
def f(path):
if request.method == 'PUT':
app.logger.info(f'---PUT---\npath: {path}')
data[path] = request.data
return f"Saved to /{path}\n", 201, {'location': f'/{path}'}
else:
app.logger.info(f'---GET---\npath: {path}')
try:
return data[path]
except KeyError:
return f"Not found (/{path})\n", 404
И следующий test.html
файл:
<h1>Test upload</h1>
Работает:
Когда я запускаю его с помощью сервера разработки Flask, он работает:
Серверокно:
$ FLASK_APP=hello.py flask run --port 5001
* Serving Flask app "hello.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5001/ (Press CTRL+C to quit)
Клиент:
$ curl -v localhost:5001/test.html
* About to connect() to localhost port 5001 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5001 (#0)
> GET /test.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5001
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 404 NOT FOUND
< Content-Type: text/html; charset=utf-8
< Content-Length: 23
< Server: Werkzeug/0.16.0 Python/3.7.1
< Date: Thu, 31 Oct 2019 17:15:31 GMT
<
Not found (/test.html)
* Closing connection 0
Сервер:
127.0.0.1 - - [31/Oct/2019 10:15:31] "GET /test.html HTTP/1.1" 404 -
Клиент:
$ curl -v -T test.html localhost:5001
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* About to connect() to localhost port 5001 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5001 (#0)
> PUT /test.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5001
> Accept: */*
> Content-Length: 20
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
} [data not shown]
* We are completely uploaded and fine
* HTTP 1.0, assume close after body
< HTTP/1.0 201 CREATED
< Location: http://localhost:5001/test.html
< Content-Type: text/html; charset=utf-8
< Content-Length: 20
< Server: Werkzeug/0.16.0 Python/3.7.1
< Date: Thu, 31 Oct 2019 17:15:39 GMT
<
{ [data not shown]
Saved to /test.html
100 40 100 20 100 20 4477 4477 --:--:-- --:--:-- --:--:-- 5000
* Closing connection 0
Сервер:
127.0.0.1 - - [31/Oct/2019 10:15:39] "PUT /test.html HTTP/1.1" 201 -
Клиент:
$ curl -v localhost:5001/test.html
* About to connect() to localhost port 5001 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5001 (#0)
> GET /test.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5001
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 20
< Server: Werkzeug/0.16.0 Python/3.7.1
< Date: Thu, 31 Oct 2019 17:15:43 GMT
<
<h1>Test upload</h1>
* Closing connection 0
Сервер:
127.0.0.1 - - [31/Oct/2019 10:15:43] "GET /test.html HTTP/1.1" 200 -
Не работает:
Однако, как говорится в документации Flask, сервер Flask не должен бытьиспользуется в производстве. Я обычно использую Gunicorn вместе с рабочими мейнхельдов;но в этом случае meinheld, похоже, не обрабатывает запрос PUT
должным образом.
Если добавить файл hello-mh.py
:
from meinheld import server
from hello import app
if __name__ == '__main__':
server.listen(("0.0.0.0", 5001))
server.run(app)
и запустить сервер:
$ python3 hello-mh.py
Клиент:
$ curl -v localhost:5001/test.html
* About to connect() to localhost port 5001 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5001 (#0)
> GET /test.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5001
> Accept: */*
>
< HTTP/1.1 404 NOT FOUND
< Server: meinheld/1.0.1
< Date: Thu, 31 Oct 2019 17:16:04 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 23
< Connection: close
<
Not found (/test.html)
* Closing connection 0
Сервер:
"127.0.0.1 - - [31/Oct/2019:10:16:04 -0900] "GET /test.html HTTP/1.1" 404 23 "-" "curl/7.29.0"
Клиент:
$ curl -v -T test.html localhost:5001
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* About to connect() to localhost port 5001 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5001 (#0)
> PUT /test.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5001
> Accept: */*
> Content-Length: 20
> Expect: 100-continue
>
* Done waiting for 100-continue
0 20 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0} [data not shown]
* We are completely uploaded and fine
< HTTP/1.1 417 Expectation Failed
< Content-Type: text/html
< Server: meinheld/1.0.1
* no chunk, no close, no size. Assume close to signal end
<
{ [data not shown]
100 118 0 98 100 20 97 19 0:00:01 0:00:01 --:--:-- 97
* Closing connection 0
<html><head><title>Expectation Failed</title></head><body><p>Expectation Failed.</p></body></html>
Сервер:
"127.0.0.1 - - [31/Oct/2019:10:16:08 -0900] "PUT /test.html HTTP/1.1" 417 98 "-" "curl/7.29.0"