通过通常没有权限的用户的符号链接访问 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信息。

相关内容