【发布时间】:2014-01-08 21:41:16
【问题描述】:
我已经设置了一个运行 Tornado(2.4.1 版)并由 Nginx(1.4.4 版)代理的服务器(嗯......两台服务器,但我认为这与这个问题不太相关)。
我需要通过POST 请求定期将json(基本上是文本)文件上传到其中一个文件。这些文件将极大地受益于 gzip 压缩(当我手动压缩文件时,我得到了 90% 的压缩率),但我不知道如何以一种很好的方式膨胀它们。
理想情况下,Nginx 会膨胀它并将其干净利落地传递给 Tornado ......但这不是现在发生的事情,正如你可能已经猜到的那样,否则我不会问这个问题 :-)
这些是我的nginx.conf 文件的相关部分(或我认为相关的部分,因为我对 Nginx 和 Tornado 还很陌生):
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 服务器。 main 运行在localhost:8000 上,用于网页和类似的东西。在localhost:8200 上运行的那个是用来接收那些json 文件的那个)这个设置工作正常,除了Gzip 部分。
我希望 Nginx 对到达 localhost:81 的 gzip 请求进行膨胀,并将它们转发到我在 localhost:8200 上运行的 Tornado(膨胀)
这样配置,数据到达Tornado,但是body还是被压缩了,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'}
)
我知道我总是可以在 post() Tornado 处理程序中获取请求的 body 并手动对其进行充气,但这听起来……很脏。
最后,这是我用来上传 gzip 文件的 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 压缩文件)
这是可行的吗?这听起来应该很简单,但不是......
如果这是通过 Nginx 无法实现的,那么 Tornado 中的自动化方法也可以工作(更可靠和优雅让我在 POST 请求的处理程序中间解压缩文件)喜欢。 .. 像 Django 中间件或类似的东西?
提前谢谢你!!
【问题讨论】:
标签: file-upload curl nginx tornado http-compression