Einer meiner Kunden versucht, eine Datei über ein POST-Formular mit XHR2-Formulardaten (und einer domänenübergreifenden Anfrage mit CORS) auf unseren Remote-Webserver nginx hochzuladen. Während des Hochladens gibt der Webserver eine 408-Fehlermeldung zurück und der Ajax-Fehlerhandler hält die Verarbeitung daraufhin an. Die Dateien liegen im Bereich zwischen 20 und 120 MB. Die Zugriffsprotokolle für einige der Datei-Uploads lauten wie folgt (er hat es mit Chrome 31 und IE11 versucht):
[24/Dec/2013:16:44:18 -0500] "OPTIONS / HTTP/1.1" 200 0 "http://www.example.com/files/upload" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"
[24/Dec/2013:16:47:50 -0500] "POST / HTTP/1.1" 408 0 "http://www.example.com/files/upload" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"
...
[27/Dec/2013:01:23:51 -0500] "OPTIONS / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
[27/Dec/2013:01:33:11 -0500] "POST / HTTP/1.1" 408 0 "http://www.example.com/files/upload" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
Manchmal funktioniert das Hochladen von Dateien bei ihm mit Chrome problemlos statt mit Internet Explorer und manchmal umgekehrt, aber meistens funktioniert keiner der beiden Browser bei ihm.
Ich habe das Nginx-Wiki gelesen und die einzigen beiden Einstellungen, die mit 408-Fehlern korrelieren, sind client_body_timeout
und client_header_timeout
. Ich habe Schwierigkeiten, die Bedeutung dieser beiden Anweisungen zu verstehen. Ich habe beide auf 180 Sekunden erhöht, aber das Problem besteht weiterhin. Ich habe ihn gefragt, ob er eine langsame Verbindung hat, und er sagte, dass er 2,5 MBit/s hat, was schnell genug sein sollte, um den Anforderungsheader vollständig zu empfangen (aber wir sind uns wieder nicht sicher, was diese beiden Anweisungen laut derWiki, z. B. was ein „Readstep“ ist). Wir haben bereits von anderen Kunden erfolgreich Uploads von 1 GB auf unseren Server empfangen, die normalerweise etwa eine Stunde dauern.
Bei den problematischen Dateien, die wir schließlich erfolgreich von unserem Kunden erhalten haben, haben wir versucht, die gleiche Datei in verschiedenen Browsern hochzuladen, und es hat perfekt funktioniert.
Ich habe gelesen, dass die Verwendung von SSL zu Zeitüberschreitungen führen könnte, aber auf dem Server ist SSL nicht aktiviert und wir verwenden nur http.
Unsere nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 5000;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 25;
# Increase client/head body_timeout to prevent 408's for slow Internet connections??
client_header_timeout 180;
client_body_timeout 180;
types_hash_max_size 2048;
server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
application/atom+xml
text/javascript
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
# Increase FastCGI buffers
fastcgi_read_timeout 1500;
fastcgi_buffers 8 16K;
fastcgi_buffer_size 32K;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Unsere Upload-Server-Konfiguration:
server {
listen 80;
server_name upload.example.com;
root /var/www/releases/latest/_UPLOAD/public;
# remove trailing slash, that throws ZF router
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
# 1.2G upload limit + 10M for post data (which is extremely liberal)
client_max_body_size 1210M;
client_body_buffer_size 4M;
proxy_max_temp_file_size 0;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location = /apple-touch-icon.png {
access_log off;
log_not_found off;
}
location / {
# This is for AJAX file uploads... need to set CORS headers
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin '$scheme://www.example.com';
add_header Access-Control-Allow-Methods 'POST, OPTIONS';
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type, Content-Range, Content-Disposition';
return 200;
}
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/releases/latest/_UPLOAD/public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV production;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
error_page 403 =404 /404.html;
error_page 404 /404.html;
location = /404.html {
root /var/www/releases/latest/_UPLOAD/public;
internal;
}
error_page 500 502 503 504 = /50x.html;
location = /50x.html {
root /var/www/releases/latest/_UPLOAD/public;
internal;
}
}
Gibt es irgendetwas in der Konfiguration, das erfolgreiche Uploads behindern und diese lästigen 408-Fehler verursachen könnte? In den Fehlerprotokollen wird zu diesem Problem nichts erwähnt.
HINWEIS: Wir haben es nur verwendet reload
, wenn wir Änderungen an der Nginx-Konfiguration vornehmen. Wir versuchen, dies zu vermeiden, restart
aber wenn dies erforderlich ist, damit unsere Konfigurationsänderungen vollständig wirksam werden, werden wir es tun.