У меня есть сервер (ну ... два сервера, но я не думаю, что это слишком актуально для этого вопроса) работает Tornado (версия 2.4.1) и проксимируется Nginx (версия 1.4.4).Nginx + Tornado (+ curl): Inflate gzip POST-запрос
Мне нужно периодически загружать файлы json
(в основном текстовые) в один из них через запрос POST
. Этим файлам будет очень полезно сжатие gzip (я получаю коэффициент сжатия 90%, когда я сжимаю файлы вручную), но я не знаю, как надуть их красиво.
В идеале, Nginx бы надуть его и передать его почистить аккуратный Торнадо ... но это не то, что сейчас происходит, как вы уже, наверное, догадались, в противном случае я бы не стал задавать этот вопрос :-)
Эти соответствующие части моего nginx.conf
файла (или части, которые я думаю актуальны, потому что я довольно новыми для Nginx и Торнадо):
user borrajax;
worker_processes 1;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /tmp/access.log main;
error_log /tmp/error.log;
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on;
gzip_disable "msie6";
gzip_types application/json text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp;
gzip_http_version 1.1;
gzip_proxied expired no-cache no-store private auth;
upstream web {
server 127.0.0.1:8000;
}
upstream input {
server 127.0.0.1:8200;
}
server {
listen 80 default_server;
server_name localhost;
location/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://web;
}
}
server {
listen 81 default_server;
server_name input.localhost;
location/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://input;
}
}
}
Как я уже упоминал ранее, это два сервера Tornado. главный один работает на localhost:8000
для веб-страниц и подобных материалов. Тот, который работает на localhost:8200
, предназначен для приема тех файлов json
). Эта настройка работает нормально, за исключением части Gzip.
Я хотел бы, чтобы Nginx надуть с gzip'нутыми запросами, которые приходят к localhost:81
, и направить их на Tornado я работаю на localhost:8200
(завышено)
С конфигурацией, как это, данные достигает Tornado, но тело все еще сжимается, и Tornado бросает исключение:
[E 140108 15:33:42 input:1085] Uncaught exception POST
/input/log?ts=1389213222 (127.0.0.1)
HTTPRequest(
protocol='http', host='192.168.0.140:81',
method='POST', uri='/input/log?&ts=1389213222',
version='HTTP/1.0', remote_ip='127.0.0.1', body='\x1f\x8b\x08\x00\x00',
headers={'Content-Length': '1325', 'Accept-Encoding': 'deflate, gzip',
'Content-Encoding': 'gzip', 'Host': '192.168.0.140:81', 'Accept': '*/*',
'User-Agent': 'curl/7.23.1 libcurl/7.23.1 OpenSSL/1.0.1c zlib/1.2.7',
'Connection': 'close', 'X-Real-Ip': '192.168.0.94',
'Content-Type': 'application/json'}
)
Я понимаю, что я всегда могу получить запрос body
-й в обработчике post()
Торнадо и надуть его вручную, но это только кажется ... грязное.
Наконец, это curl
вызова я использую, чтобы загрузить файл сжатый:
curl --max-time 60 --silent --location --insecure \
--write-out "%{http_code}" --request POST \
--compressed \
--header "Content-Encoding:gzip" \
--header "Content-Type:application/json" \
--data-binary "$log_file_path.gz" \
"/input/log?ts=1389216192" \
--output /dev/null \
--trace-ascii "/tmp/curl_trace.log" \
--connect-timeout 30
Файл в $log_file_path.gz
генерируется с использованием gzip $log_file_path
(я имею в виду ... это обычный Gzip сжатого файла)
Это что-то выполнимое? Это звучит как-то, что должно быть довольно прямо вперед, но nopes ...
Если это что-то не выполнимо через Nginx, автоматизированный метод Tornado будет работать тоже (что-то более надежное и элегантный, что с меня разжатия файлы в середине обработчика запроса POST) Как ... что-то вроде Django middlewares или что-то в этом роде?
Благодарим вас заранее!
Спасибо за ваш ответ, но если я удалю заголовок Content-Type в вызове curl, это будет продолжаться. Даже если бы это было так, разве я не должен видеть завышенное тело в исключении? – BorrajaX
Я не сказал изменить запрос; Я сказал, чтобы изменить ваш код, чтобы распаковать данные, которые вы получаете. Поскольку json-декодирование уже находится в вашем коде вместо фреймворка (если вы получаете исключение из торнадо вместо своего собственного кода, отправьте трассировку), нет никакой пользы для декомпрессии в каком-то магическом «промежуточном программном обеспечении». –
Итак, что вы рекомендуете, это получить request.body в обработчике Tornado и раздуть его собственным кодом? Я вроде хотел этого избежать, и Nginx (или Tornado) раздувает запрос прозрачным способом. – BorrajaX