使用 nginx 防止大文件上傳
我正在使用 Nginx 作為 Web 伺服器為我的網站提供服務。我向我的使用者提供上傳功能(他們被允許送出高達 5Mb 的圖片),所以我有指令:
client_max_body_size 5M;
在我的伺服器配置中。我注意到的是,如果我嘗試上傳任何文件,網路伺服器不會阻止上傳更大的文件。舉個例子,假設我嘗試上傳一個 700Mb 的非常大的影片(一部電影)。伺服器不會立即拒絕上傳,但它會緩衝整個數據(花費很長時間並減慢伺服器的速度),並且僅在上傳結束時才會返回413 Request entity too large
錯誤。
client_max_body_size
所以問題是:當傳輸的數據開始超過我的限制時,有沒有辦法正確配置 Nginx 來阻止大文件上傳?我認為使用我的實際設置進行生產真的很不安全,而且我在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 進行了某種預防性檢查,但它不會停止/分塊上傳請求……我還嘗試通過在處理上傳的頁面上發出 a 來驗證 php 是否獲得了上傳的控制權,
echo 'something'; die();
但它沒有列印出任何內容,也沒有停止上傳請求。所以應該是nginx或者一些php內部讓整個上傳一直持續到完全傳輸…另一個編輯:
top
當大文件上傳正在進行時(nginx 過載),這是我的(監控 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。
如果是這樣,那隻是瀏覽器問題,不會影響(超載)我的 Web 伺服器。似乎在抱怨我的記憶體檢查顯示 nginx 和 php-fastcgi 在上傳大型(700mb)文件時並沒有真正超載。
我可以通過多種方式解決瀏覽器問題,例如:
<input type="hidden" name="MAX_FILE_SIZE" value="5242880" />
在我的表格中添加一個- 使用自定義 413 nginx 錯誤頁面