http 403错误+" readv()失败(104:通过对等方重置连接),同时读取上游"

时间:2014-09-07 18:07:32

标签: django amazon-web-services nginx amazon-ec2 gunicorn

前言:我正在使用s3boto作为默认存储后端的amazon ec2实例上运行nginx + gunicorn + django。我是免费的。 ec2安全组允许:http,ssh和& HTTPS。

我正在尝试发送包含单个元素的multipart / form-data请求:照片。尝试上传照片时,iPhone(请求来自的地方)会挂起。照片大小约为9.5 MB。

当我检查nginx-access.logs时:

“POST / myUrl / HTTP / 1.1”400 5“ - ”“....

当我检查nginx-error.logs时:

[error] 5562#0: *1 readv() failed (104: Connection reset by peer) while reading upstream, client: my.ip.addr.iphone, server: default, request: "POST /myUrl/ HTTP/1.1", upstream: "http://127.0.0.1:8000/myUrl/", host: "ec2-my-server-ip-addr.the-location-2.compute.amazonaws.com"

[info] 5562#0: *1 client my.ip.addr.iphone closed keepalive connection

我真的无法弄清楚为什么会发生这种情况......我尝试更改/ etc / nginx / sites-available / default超时设置......

server { ...

    client_max_body_size 20M;
    client_body_buffer_size 20M;


    location / {
       keepalive_timeout 300;
       proxy_read_timeout 300;
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

编辑:在谈了IRC之后,他的问题是403本身,而不是nginx错误。留下我对下面的nginx错误的评论,以防其他人有一天偶然发现它。

上周我遇到了这个问题,并花了很长时间试图弄清楚发生了什么。见这里:https://github.com/benoitc/gunicorn/issues/872

基本上,只要django看到标题,就会知道请求未经过身份验证。它不等待大型请求主体完成上传;它会立即响应,而gunicorn会立即关闭连接。 nginx继续发送数据,最终结果是gunicorn向nginx发送RST数据包。一旦发生这种情况,nginx无法恢复,而不是从gunicorn / django发送实际响应,它会发送一个502 Bad Gateway。

我最终放入了一个中间件,在django请求中激活了几个字段,这确保在Django发送响应之前下载整个请求体:

checker = re.compile(feed_url_regexp)

class AccessPostBodyMiddleware:

    def process_request(self, request):
        if checker.match(request.path.lstrip('/')) is not None:
            # just need to access the request info here
            # not sure which one of these actually does the trick.
            # This will download the entire request,
            # fixing this random issue between gunicorn and nginx
            _ = request.POST
            _ = request.REQUEST
            _ = request.body
        return None

但是,我无法控制客户端。既然你(以你的iPhone应用程序的形式),也许你可以找到一种方法来处理502坏网关。这将使您的应用不必两次发送整个请求。