Я обслуживаю свой сайт, используя Nginx в качестве веб-сервера. Я предлагаю своим пользователям возможность загрузки (им разрешено отправлять изображения размером до 5 МБ), поэтому у меня есть директива: client_max_body_size 5M;
в моей конфигурации сервера. Я заметил, что если я попытаюсь загрузить какой-либо файл, веб-сервер не предотвратит загрузку файлов большего размера. В качестве примера предположим, что я пытаюсь загрузить действительно большое видео (фильм) размером 700 МБ. Сервер не отклоняет загрузку мгновенно, но буферизует все данные (это занимает так много времени и замедляет работу сервера), и только в конце загрузки он возвращает 413 Request entity too large
ошибка.
Итак, вопрос: есть ли способ правильно настроить Nginx для блокировки загрузки больших файлов, когда передаваемые данные начинают преодолевать мои client_max_body_size
предел?
Я думаю, что было бы действительно небезопасно продолжать производство с моими фактическими настройками, и я не смог найти ничего полезного в Google.
Редактировать:
Я использую php и Symfony2 как бэкэнд ...
Изменить (снова):
Вот что написано в моем error.log:
2013/01/28 11:14:11 [error] 11328#0: *37 client intended to send too large body: 725207449 bytes, client: 33.33.33.1, server: www.local.example.com, request: "POST /app_dev.php/api/image/add/byuploader HTTP/1.1", host: "local.example.com", referrer: "http://local.example.com/app_dev.php/"`
Странно то, что я слежу за своим nginx error.log
с участием tail -f error.log
и сообщение появляется сразу после начала загрузки (до ее завершения). Итак, nginx выполняет своего рода превентивную проверку, но не останавливает / не блокирует запрос на загрузку ...
Я также попытался проверить, получает ли php контроль над загрузкой, выполнив echo 'something'; die();
на странице, которая обрабатывает загрузку, но ничего не распечатала и не остановила запрос загрузки. Так что это должен быть nginx или некоторые внутренние компоненты php, которые заставят всю загрузку продолжаться, пока она не будет полностью передана ...
другое редактирование: вот вид моего top
(мониторинг nginx и php), когда идет загрузка большого файла (nginx перегружается):
изменить: вот моя конфигурация nginx
server {
listen 80;
server_name www.local.example.com local.example.com;
access_log /vagrant/logs/example.com/access.log;
error_log /vagrant/logs/example.com/error.log;
root /vagrant/example.com/web;
index app.php;
client_max_body_size 6M;
location /phpmyadmin {
root /usr/share;
index index.php;
location ~* \.php {
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Полезная информация здесь: https://stackoverflow.com/questions/4947107/nginx-upload-client-max-body-size-issue
Цитирую часть самого интересного ответа (для моего случая):
Большинство клиентов не читают ответы, пока не будет отправлено все тело запроса. Поскольку nginx закрывает соединение, клиент отправляет данные в закрытый сокет, вызывая TCP RST.
Если это так, то это проблема только браузера, которая не повлияет (не перегрузит) мой веб-сервер. Кажется, он жалуется на мою проверку памяти, которая показала, что и nginx, и php-fastcgi не были действительно перегружены при загрузке большого (700 МБ) файла.
Я мог бы решить проблему браузера несколькими способами, например:
<input type="hidden" name="MAX_FILE_SIZE" value="5242880" />
в моей формеЧто вы используете php или rails или что-то в этом роде? потому что вы должны проверить размер перед загрузкой.
устанавливать post_max_size и upload_max_filesize к соответствующему значению в файл: php.ini
изменить: попробуйте написать что-то подобное в свою загрузку
$element = new Zend_Form_Element_File('foo');
$element->setLabel('Upload a file:')
->setDestination('/var/www/upload');
// make sure its only 1 file
$element->addValidator('Count', false, 1);
// Maximal 100k
$element->addValidator('Size', false, 102400);
// only JPEG, PNG, and GIFs
$element->addValidator('Extension', false, 'jpg,png,gif');
$form->addElement($element, 'foo');