NginxをWebサーバーとして使用してWebサイトにサービスを提供しています。私はユーザーにアップロード機能を提供しているので(ユーザーは最大5Mbの写真を送信できます)、サーバー構成に_client_max_body_size 5M;
_というディレクティブがあります。私が気付いたのは、ファイルをアップロードしようとしても、Webサーバーが大きなファイルのアップロードを妨げないということです。例として、700Mbの非常に大きなビデオ(映画)をアップロードしようとしたとします。サーバーはアップロードを即座に拒否しませんが、データ全体をバッファリングし(非常に時間がかかり、サーバーの速度が低下します)、アップロードの最後にのみ_413 Request entity too large
_エラーを返します。
したがって、問題は、送信されたデータが私の_client_max_body_size
_制限を超え始めたときに、大きなファイルのアップロードをブロックするようにNginxを適切に構成する方法はありますか?
私の実際の設定で本番環境に移行するのは本当に安全ではないと思います。グーグルで役立つものを見つけることができませんでした。
編集:
バックエンドとして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はある種の予防的チェックを行いますが、アップロード要求を停止/チャンクしません...
また、アップロードを処理するページでecho 'something'; die();
を発行して、phpがアップロードを制御できるかどうかを確認しようとしましたが、何も出力されず、アップロード要求が停止しませんでした。したがって、完全に送信されるまでアップロード全体を継続させるのは、nginxまたはいくつかのphp内部である必要があります...
別の編集:大きなファイルのアップロードが進行中(nginxが過負荷になる)のときの私のtop
(nginxとphpの監視)のビューは次のとおりです。
編集:これが私の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を引き起こします。
もしそうなら、それは私のウェブサーバーに影響を与えない(オーバーロードする)ブラウザの問題だけです。大きな(700mb)ファイルをアップロードするときにnginxとphp-fastcgiの両方が本当に過負荷になっていないことを示した私のメモリ検査に不満があるようです。
ブラウザの問題には、次のようないくつかの方法で対処できます。
<input type="hidden" name="MAX_FILE_SIZE" value="5242880" />
を追加しますアップロードする前にサイズを確認する必要があるため、phpまたはRailsなど)を使用していますか?.
set post_max_sizeおよびpload_max_filesizefile: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');