激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

云服務器|WEB服務器|FTP服務器|郵件服務器|虛擬主機|服務器安全|DNS服務器|服務器知識|Nginx|IIS|Tomcat|

服務器之家 - 服務器技術 - Nginx - 在Nginx中使用X-Sendfile頭提升PHP文件下載的性能(針對大文件下載)

在Nginx中使用X-Sendfile頭提升PHP文件下載的性能(針對大文件下載)

2019-10-21 14:34junjie Nginx

這篇文章主要介紹了在Nginx中使用X-Sendfile頭提升PHP文件下載的性能,可以用在針對大文件下載的情況,下載非網站Web目錄文件的需求,提供下載權限控制的場景,需要的朋友可以參考下

很多時候用戶需要從網站下載文件,如果文件是可以通過一個固定鏈接公開獲取的,那么我們只需將文件存放到 webroot下的目錄里就好。但大多數情況下,我們需要做權限控制,例如下載 PDF 賬單,又例如下載網盤里的檔案。這時,我們通常借助于腳本代碼來實現,而這無疑會增加服務器的負擔。

例如下面的代碼:

<?php
  // 用戶身份認證,若驗證失敗跳轉
  authenticate();
  // 獲取需要下載的文件,若文件不存在跳轉
  $file = determine_file();
  // 讀取文件內容
  $content=file_get_contents($file);
  // 發送合適的 HTTP 頭
  header("Content-type: application/octet-stream");
  header('Content-Disposition: attachment; filename="' . basename($file) . '"');
  header("Content-Length: ". filesize($file));
  echo $content; // 或者 readfile($file);
?>

一、這樣做有什么問題?

這樣做意味著我們的程序需要將文件內容從磁盤經過一個固定的 buffer 去循環讀取到內存,再發送給前端 web 服務器,最后才到達用戶。當需要下載的文件很大的時候,這種方式將消耗大量內存,甚至引發 php 進程超時或崩潰。Cache 也很頭疼,更不用說中斷重連的情況了。
一個理想的解決方式應該是,由 php 程序進行權限檢查等邏輯判斷,一切通過后,讓前臺的 web 服務器直接將文件發送給用戶——像 Nginx 這樣的前臺更善于處理靜態文件。這樣一來 php 腳本就不會被 I/O 阻塞了。

二、什么是 X-Sendfile?

X-Sendfile 是一種將文件下載請求由后端應用轉交給前端 web 服務器處理的機制,它可以消除后端程序既要讀文件又要處理發送的壓力,從而顯著提高服務器效率,特別是處理大文件下載的情形下。

X-Sendfile 通過一個特定的 HTTP header 來實現:在 X-Sendfile 頭中指定一個文件的地址來通告前端 web 服務器。當 web 服務器檢測到后端發送的這個 header 后,它將忽略后端的其他輸出,而使用自身的組件(包括 緩存頭 和 斷點重連 等優化)機制將文件發送給用戶。

不過,在使用 X-Sendfile 之前,我們必須明白這并不是一個標準特性,在默認情況下它是被大多數 web 服務器禁用的。而不同的 web 服務器的實現也不一樣,包括規定了不同的 X-Sendfile 頭格式。如果配置失當,用戶可能下載到 0 字節的文件。

使用 X-Sendfile 將允許下載非 web 目錄中的文件(例如/root/),即使文件在 .htaccess 保護下禁止訪問,也會被下載。

不同的 web 服務器實現了不同的 HTTP 頭 

SENDFILE 頭

使用的 WEB 器

X-Sendfile

Apache, Lighttpd v1.5, Cherokee

X-LIGHTTPD-send-file

Lighttpd v1.4

X-Accel-Redirect

Nginx, Cherokee

 

使用 X-SendFile 的缺點是你失去了對文件傳輸機制的控制。例如如果你希望在完成文件下載后執行某些操作,比如只允許用戶下載文件一次,這個 X-Sendfile 是沒法做到的,因為后臺的 php 腳本并不知道下載是否成功。

三、怎樣使用?

Apache 請參考mod_xsendfile模塊。下面我介紹 Nginx 的用法。

Nginx 默認支持該特性,不需要加載額外的模塊。只是實現有些不同,需要發送的 HTTP 頭為 X-Accel-Redirect。另外,需要在配置文件中做以下設定

location /protected/ {
 internal;
 root  /some/path;
}

表示這個路徑只能在 Nginx 內部訪問,不能用瀏覽器直接訪問防止未授權的下載。


于是 PHP 發送 X-Accel-Redirect 給 Nginx:

]<?php
  $filePath = '/protected/iso.img';
  header('Content-type: application/octet-stream');
  header('Content-Disposition: attachment; filename="' . basename($file) . '"');
  //讓Xsendfile發送文件
  header('X-Accel-Redirect: '.$filePath);
?>

這樣用戶就會下載到 /some/path/protected/iso.img 這個路徑下的文件。
如果你想發送的是 /some/path/iso.img 文件,那么 Nginx 配置應該是

location /protected/ {
 internal;
 alias  /some/path/; # 注意最後的斜杠
}

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 禁漫天堂久久久久久久久久 | 欧美大逼网 | 色污视频在线观看 | 日韩精品中文字幕一区 | 欧美亚洲国产一区二区三区 | 日韩在线观看视频网站 | 亚洲国产精品高潮呻吟久久 | 激情毛片 | 夜夜夜精品视频 | 国产精品18久久久久久久久 | 久久国产精品系列 | 欧美一级毛片大片免费播放 | 草免费视频 | 9999精品 | 亚洲精品在线观看免费 | 精品国产一区二区三区在线 | 黄网站色成年大片免费高 | 久久久久九九九女人毛片 | 精品国产一区二区三区久久久 | 成人午夜在线免费观看 | 久久久久久久黄色片 | 久久久久久久久久性 | 亚洲成人中文字幕在线 | 日本一级特级 | 暴力肉体进入hdxxxx0 | 精品国产一区二 | 情侣啪啪网站 | 91精品国产刺激国语对白 | 日韩电影一区二区 | 91成人影库 | 午夜精品在线视频 | 久久福利电影网 | 成人在线视频一区 | 亚洲国产精品一区二区三区 | 国产精品久久在线观看 | 国产91久久精品一区二区 | av色在线观看 | 精品一区二区亚洲 | 久久久久成人精品免费播放 | 久久精品一二三区白丝高潮 | 精品国产一区二区三区久久久狼牙 |