nginx 업로드 client_max_body_size 문제


117

nginx / ruby-on-rails를 실행 중이며 파일을 업로드하는 간단한 멀티 파트 양식이 있습니다. 업로드하려는 파일의 최대 크기를 제한하기 전까지는 모든 것이 잘 작동합니다. 이를 위해 nginx client_max_body_size1m (1MB) 로 설정하고 해당 규칙이 위반 될 때 응답으로 HTTP 413 (Request Entity Too Large) 상태를 예상합니다.

문제 는 1.2MB 파일을 업로드 할 때 HTTP 413 오류 페이지를 표시하는 대신 브라우저가 약간 멈춘 다음 "페이지를로드하는 동안 연결이 재설정되었습니다"라는 메시지와 함께 죽는다는 것입니다.

나는 nginx가 제공하는 모든 옵션을 시도했지만 아무것도 작동하지 않는 것 같습니다. 누구든지 이것에 대한 아이디어가 있습니까?

내 nginx.conf는 다음과 같습니다.

worker_processes  1;
timer_resolution  1000ms;
events {
    worker_connections  1024;
}

http {
    passenger_root /the_passenger_root;
    passenger_ruby /the_ruby;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile           on;
    keepalive_timeout  65;

    server {
      listen 80;
      server_name www.x.com;
      client_max_body_size 1M;
      passenger_use_global_queue on;
      root /the_root;
      passenger_enabled on;

      error_page 404 /404.html;
      error_page 413 /413.html;    
    }    
}

감사.


**Edit**

환경 / UA : Windows XP / Firefox 3.6.13

답변:


128

nginx는 클라이언트가 client_max_body_size413 응답을 보내고 연결을 닫음으로써 보다 큰 본문을 보낼 것이라고 알릴 때 "빠르게 실패"합니다 .

대부분의 클라이언트는 전체 요청 본문이 전송 될 때까지 응답을 읽지 않습니다. nginx가 연결을 닫기 때문에 클라이언트는 닫힌 소켓으로 데이터를 보내 TCP RST를 발생시킵니다.

HTTP 클라이언트가이를 지원하는 경우이를 처리하는 가장 좋은 방법은 Expect: 100-Continue헤더 를 보내는 것 입니다. Nginx에 제대로 1.2.7 현재 동을 지원하고, 회신 것 413 Request Entity Too Large보다는 응답 100 Continue하는 경우 Content-Length최대 몸 크기를 초과합니다.


1
아, 나는이 대답은 클라이언트가 전송되어 있다고 가정 지적한다 Content-Length보다는 일을 Transfer-Encoding: chunked.
Joe Shaw

2
다음의 nginx 작성자는 메일 링리스트에이 문제를 해결하는 패치 게시 nginx.2469901.n2.nabble.com/...되지 는 1.2.x를 안정 지점에 추가할지 여부를 어떤 단어를, 비록합니다.
Joe Shaw

감사합니다. 실제로 많은 것을 설명합니다. 분명히 Expect큰 요청을하는 방법입니다.
krukid

이전에 언급 한 패치가 커밋되고 1.2.7 릴리스에 통합되었음을 알리기 위해 답변을 업데이트했습니다.
Joe Shaw

: 그냥 (I 지출 등) 멋진 구문을 찾는 시간을 절약하기 request.setHeader(HttpHeaders.EXPECT, CONTINUE);import org.apache.http.HttpHeaders;하고import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.CONTINUE;
Erez 코헨

48

업로드가 끝날 때 죽습니까? 충돌하기 전에 99 %? nginx는 들어오는 데이터를 버퍼링해야하므로 클라이언트 본문과 버퍼가 핵심입니다. 본문 구성 (요청 본문의 데이터)은 nginx가 다중 파트 양식 클라이언트에서 앱 논리로의 바이너리 데이터 대량 흐름을 처리하는 방법을 지정합니다.

clean설정은 nginx가 들어오는 버퍼를 파일에 저장하고 나중에이 파일을 삭제하여 디스크에서 정리하도록 지시하여 메모리 및 소비 제한을 해제합니다.

설정 body_in_file_onlyclean와에 대한 버퍼를 조정합니다 client_max_body_size. 원래 질문의 구성에는 이미 sendfile이 설정되어 있으므로 시간 초과도 증가합니다. 아래 설정을 사용하여 로컬 구성, 서버 및 http 컨텍스트에서 적절하게 수정합니다.

client_body_in_file_only clean;
client_body_buffer_size 32K;

client_max_body_size 300M;

sendfile on;
send_timeout 300s;

이로 인해 nginx가 적절한 HTTP 413을 반환하더라도 UA는 여전히 전체 요청 본문을 보내 게됩니다. 그렇지 않습니까? 이 경우 @ joe-shaw가 제안한 접근 방식을 시도해 볼 가치가 있다고 생각합니다.
크루 키드

@krukid NGINX가 "빠르게 실패"하기 전에 99 % 업로드가 완료된 것 같으면 동의합니다. 이 경우 모든 신호는 요청 객체를 둘러싼 긍정적입니다. 즉, Nginx 뒤에서 실행되는 것은 무엇이든 내부 서버 애플리케이션 로직이 괜찮다는 진단입니다. 따라서 요청이 잘 구성되었을 가능성이 있지만 NGINX가 응답에 질식하는 이유를 고려해야합니다. client_max_body_size는 첫 번째 구성 옵션이어야합니다. 그런 다음 버퍼를 고려하십시오. 충분히 큰 업로드를 사용하면 올바른 솔루션은 서버가 처리 할 수있는 메모리 양에 따라 달라지기 때문입니다.
Bent Cardan 2013

@Bent Cardan. 이 접근법이 더 나은 것 같았고 나는 그것을 시도했습니다. 하지만 4MB 파일에 대해 약 20 초 후에 여전히 413 오류가 발생합니다. 내 업 스피드는 20 초에 4MB를 관리 할 수 ​​없기 때문에 데이터가 꽤 많이 흐른 후에 발생합니다. 생각?
제롬

nginx.conf 파일 _client_max_body_size 300M에 변경 사항을 추가했습니다. sendfile on; send_timeout 300 초; _ 완벽하게 작동합니다. 감사합니다
Ramesh Chand

솔루션이 나를 위해 작동합니다. openshift php7 nginx .
마를

7

에서 문서 :

브라우저는이 오류를 올바르게 표시하는 방법을 모른다는 점을 염두에 두어야합니다.

다음과 같은 도구를 사용하여 HTTP를 앞뒤로 검사하면 이것이 일어나는 일이라고 생각합니다. Firebug 또는 Live HTTP Headers (두 파이어 폭스 확장) 실제로 무슨 일이 일어나고 있는지 확인할 수 있습니다.


1
나는 여기에서도 그것을 발견 했다 : forum.nginx.org/read.php?2,2620 nginx 작성자가 사람들이 lingering_time / lingering_timeout을 변경해 볼 수 있다고 말한 곳-둘 다 내 경우에는 효과가 없었습니다. 게다가, 안정적인 5Mbps 연결로 쉽게 1MB 제한으로 1.2MB 파일을 업로드 할 때 지속적인 시간 초과 문제가 발생할 수있는 방법을 알 수 없습니다. 나는 응답을 스니핑했고 "Connection : close"헤더가있는 413 페이지를 보냈지 만 연결이 닫히지 않는 것 같습니다.
krukid

완벽하게 유효한 413 HTTP 상태가 있음에도 불구하고 브라우저에서 실행되지 않는다고 믿기 힘들 것 같습니다. 나는 사람들이 그 페이지를 지울 수없는 곳을 많이 봤는데 그것을 본 적이 없다.
krukid

승객을 비활성화하면 연결이 끊어 집니까?
Mark Rose

글쎄, 나는 승객과 함께 응답을 비교했습니다. 모든 것이 정상적으로 실행되고 1MB 제한보다 몇 배 큰 (~ 14MB) 파일을 업로드하면 413 응답을 여러 번 받고 (클라이언트가 청크를 계속 전송하기 때문에) 최종 "연결 재설정"이 시간 초과처럼 보입니다. 승객이 없으면 413 즉각적인 응답을 받고 모든 진행이 중지되지만 여전히 정적 413.html 또는 "엔티티가 너무 큼"을 암시하는 내용이 아닌 "연결 재설정"페이지가 표시됩니다
krukid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.