透過通常沒有權限的使用者的符號連結存取 PHP 中的文件

透過通常沒有權限的使用者的符號連結存取 PHP 中的文件

我有這個網站,如果用戶提交表單,則透過 php 頁面執行 python 腳本,並且 python 腳本創建一個 zip 檔案並應將其提供給用戶透過鏈接下載。該檔案可能很大(幾 GB)。

由於我在大學伺服器上工作,因此我嚴格遵守他們的伺服器規則和功能。問題是這樣的:

該網站儲存在/data/mywebsite,其磁碟空間有限。當然,這是由我擁有的,www-data因為它主要由我的 Apache 伺服器存取。

我在 中獲得了 1 TB 儲存空間/experimentdata/,只能由單一特定使用者(例如 )存取theuser。這是因為該資料夾是 samba 掛載,可由單一特定使用者 ID 存取。

為了在中建立文件/experimentdata,我使用一個命令以使用者身分sudo -u theuser建立文件。現在我的問題是:如何透過 Apache 下載連結提供此文件?/experimentdata/downloadme.ziptheuser

我想到使用我放入的符號鏈接,例如/data/mywebsite/download/downloadme.zip.問題是用戶www-data絕對沒有讀取該檔案的權限!

怎麼樣才能讓用戶透過用戶/experimentdata/downloadme.zip跟用戶一起下載檔案呢?www-datatheuser

我想明確地說,參與sudo -u theuser是絕對可以的。但我不知道如何將其連結到我的網站資料夾之外的某個位置。

PS:如果您需要任何其他信息,請詢問。

答案1

我認為要做的就是讓php/python直接返回數據而不是apache.您的程式碼可以做同樣的事情apache。根據我的經驗,這比打開另一個目錄和/或使用sudo或更改 的檔案權限apache等要好得多。

如果程式產生大檔案的速度比網路連線的速度快,那麼您可以直接從程式串流數據,從而消除額外的資料檔案和管理它的程式碼以及記住它的機制。

Stack Overflow 上的這個答案展示了程式碼如何在php.https://stackoverflow.com/a/4357904/5484716

對於以這種方式呼叫的程序,請消除所有stderr流輸出,並確保 python 進程的回傳程式碼準確反映進程的成功或失敗。

下面的範例顯示了popen()您在上面的 stackoverflow 範例場景中將使用的呼叫。我已添加exec 2>/dev/null;到 shell 命令前面。這可以確保不會有任何輸出進入標準錯誤,即使是來自 shell 本身,因為資料同時來自stderrstdout可能成為死鎖的根源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.stdoutzf = 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-headerentity-header資訊。

相關內容