通過通常沒有權限的使用者的符號連結訪問 PHP 中的文件
我有這個網站,如果使用者送出表單,python 腳本會通過 php 頁面執行,python 腳本會創建一個 zip 文件,並應通過連結將其提供給使用者以供下載。該文件可能很大(幾 GB)。
當我在大學伺服器上工作時,我嚴格遵守他們的伺服器規則和功能。這是問題所在:
該網站儲存在
/data/mywebsite
磁碟空間有限的 中。當然,它歸我所有,www-data
因為它主要由我的 Apache 伺服器訪問。我在 中提供 1 TB 儲存空間
/experimentdata/
,只有單個特定使用者才能訪問,例如theuser
。這是因為此文件夾是一個 samba 掛載,可由單個特定使用者 ID 訪問。要在其中創建文件
/experimentdata
,我使用了一個命令,該命令將以使用者身份sudo -u theuser
創建文件。現在我的問題是:如何通過 Apache 下載連結提供此文件?/experimentdata/downloadme.zip``theuser
我想使用我放入的符號連結,例如
/data/mywebsite/download/downloadme.zip
. 問題在於使用者www-data
絕對沒有讀取文件的權限!如何讓
/experimentdata/downloadme.zip
使用者www-data
通過使用者下載文件theuser
?我想明確地說,參與
sudo -u theuser
是絕對好的。但我不知道如何將其連結到我的網站文件夾之外的某個地方。PS:如果您需要任何其他資訊,請詢問。
我認為要做的事情是讓您的
php
/python
直接返回數據而不是apache
. 你的程式碼可以做同樣的事情apache
。以我的經驗,這比打開另一個目錄和/或使用sudo
,或更改文件權限apache
等要好得多。如果程序生成大文件的速度比 Internet 連接快,那麼您可以直接從程序中流式傳輸數據,這樣就消除了額外的數據文件和管理它的程式碼以及記住它的機制。
Stack Overflow 上的這個答案顯示了程式碼在
php
. https://stackoverflow.com/a/4357904/5484716。對於將以這種方式呼叫的程序,請消除所有
stderr
流輸出,並確保 Python 程序的返回碼準確反映程序的成功或失敗。下面的範例顯示了
popen()
您將在 stackoverflow 的上述範例場景中使用的呼叫。我已經預先添加exec 2>/dev/null;
到 shell 命令。這確保了沒有輸出進入標準錯誤,即使是來自 shell 本身,因為兩者都有數據,stderr
並且stdout
可能是popen()
.如果您想將磁碟文件下載給您的使用者:
$fp = popen('exec 2>/dev/null; sudo -u theuser cat yourfile.zip', 'r');
如果要從活動程序中下載數據:
$fp = popen('exec 2>/dev/null; sudo yourpythonscript arg argN', 'r');
這些命令行是shell 命令,需要為 shell 元字元適當地引用。
在第二種方法中,伺服器將立即開始發送數據。當使用者成功送出表單時,他們會立即從瀏覽器中看到“另存為”對話框。一旦使用者選擇了輸出文件,您的
php
腳本就會直接通過線路將數據傳輸到遠端文件中。該
python
腳本應僅在標準輸出上列印 zip 數據,並返回準確表示 zip 過程成功或失敗的退出程式碼。在python
腳本中應該寫上輸出sys.stdout
,例如zf = ZipFile(sys.stdout, ...
。
pclose()
呼叫並檢查返回值至關重要,因為這是您知道 zip 是否成功的唯一方法。如果pclose()
返回 0 以外的任何值,則說明有問題。客戶端如何處理文件取決於這些
response headers
和其他的設置:content-type:
、content-encoding:
和content-disposition:
參見:http ://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html ,查看response-header
和entity-header
資訊。