gpt4 book ai didi

php - xsendfile 期望什么编码?

转载 作者:搜寻专家 更新时间:2023-10-31 21:08:46 26 4
gpt4 key购买 nike

似乎用谷歌搜索 xsendfile 问题会产生许多相互矛盾/过时的结果。

为了全面披露,我正在考虑 xsendfile 1.0 beta,记录在 https://tn123.org/mod_xsendfile/beta/ (这个网站通常不会出现在搜索结果中,只有没有/beta 的网站才会出现)。我在 Linux 和 Windows 上将它与 apache 2.4 和 php 5.4.34 一起使用。除了是最新版本之外,我还需要使用测试版,因为只有测试版站点具有使用 VC9 为 apache 2.4 构建的 Windows 二进制文件。

我在阅读文档时犯了一个错误,标题中文件名值的描述是这样说的:

The value (file name) given by the header is assmumed to be url-encoded, i.e. unescaping/url-decoding will be performed. See XSendFileUnescape. If you happen to store files using already url-encoded file names, you must "double" encode the names... %20 -> %2520

XSendFIleUnescape 的描述是这样的:

Setting XSendFileUnescape off will restore the pre-1.0 behavior of using the raw header value, instead of trying to unescape/url-decode first.

关于相对路径的文档非常清楚地表明 X-SendFile header 上的文件名应该是完整路径名。所以我通过 php 的 urlencode 函数仔细地运行我的路径名。

对我来说,最终结果总是在 Linux 和 Windows 上出现服务器内部错误(500 状态代码)。当我在 server config 上下文中有我的 XSendFilePath 指令时,文档说这是允许的,但我的错误日志中没有更具体的内容。但是当我(最终)将该指令移动到 Directory 上下文时,我逐渐在我的错误日志中得到了这个:

(404)Unknown error: [client 127.0.0.1:20742] xsendfile: bad file name encoding

最终,出于绝望,我说“去他妈的文档”,并删除了路径名上的 urlencode。突然间它开始完美运行(Windows 和 Linux)!!!

我没有任何包含非 ASCII 字符的路径名,所以我已经准备好了。但我确实想知道应该应用哪种编码来允许非 ASCII 字符工作。如果你用谷歌搜索 xsendfile: bad file name encoding,你会在 https://github.com/nmaier/mod_xsendfile/blob/master/mod_xsendfile.c 找到以下源代码该消息字符串是通过采用以下的真实分支生成的:

   rv = ap_unescape_url(file);
if (rv != OK) {

但是我找不到ap_unescape_url() 的好的描述或源代码。除非 github 上的源代码已过时,否则该函数反对 PHP 的 urlencode() 函数执行的简单 % 编码。作为一个疯狂的猜测,我尝试调用 ap_escape_url(),但它没有在 PHP 中定义。因此,问题是应该将什么编码应用于X-SendFile header 中的路径名参数??

另一个观察/问题XSendFile 使用“apache internals”发送文件的描述可能会让您认为它会使用 mod_mime< 从文件扩展名构造一个 Content-Type header 。但实际上并非如此,示例显示了对 Content-Type 的显式 header() 调用。所以我的后续是从传递给 X-SendFile 的路径名构造该 header 的“正确”方法是什么,这样它就可以保证匹配 mod_mime如果我们不使用 X-SendFile 会怎样?我能想出的最好的办法是使用 PHP 的 fileinfo 扩展名的以下代码——但据我所知,没有特别的理由期望它在给定文件名的 url 时实际上会匹配 apache 所做的事情.

    $finfo = new finfo(FILEINFO_MIME);
$mime_info = $finfo->file($pathname);
if (! strlen($mime_info)) {
$mime_info = 'application/octet-stream; charset=binary';
}
$basename = basename($pathname);
$encoded = "$pathname";
header("Content-Type: $mime_info");
header("Content-Disposition: attachment; filename=\"$basename\"");
header("X-SendFile: $encoded");

最佳答案

我不会接受这个作为问题的答案,因为我还没有找到预期使用的“那个”编码函数。但我确实找到了这个古老的 Apache API 文档:http://pedrowa.weba.sk/docs/ApiDoc/apidoc_ap_unescape_url.html .它将 ap_unescape_url() 的返回值记录为:

Returns 0 on success, BAD_REQUEST if a bad escape sequence is found, or NOT_FOUND if %2F (/) is found.

当然,在 PHP 中,urlencode() 和 rawurlencode() 都将 '/' 编码为 %2F。

很明显,XSendFile header 中使用的任何完整路径名都必须使用这些函数中的任何一个进行 urlencoded!!

我对我使用的“最佳”解决方案的猜测:

$encoded = str_replace('%2F', '/', rawurlencode($pathname));

我必须承认,我很惊讶 XSendFile 文档没有提到这一点。更令我惊讶的是,这个问题在这里没有得到任何答案。我应该在不同的 Stack Exchange 网站上发布这个吗?

关于php - xsendfile 期望什么编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26769144/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com