7

我有一个 PHP 脚本,它按字节范围提供 PDF 文件的部分内容。

如果收到 HTTP HEAD 请求,它应该发回标头(包括 PDF 文件大小),而不是实际的文件内容。我试过这个:

header('HTTP/1.1 200 OK');
header('Content-Type: application/pdf');
header('Accept-Ranges: bytes');
header('Content-Length: '.filesize($Pathname));
die;

问题是某些东西(我假设 Web 服务器 == LiteSpeed)用Content-Length: 0- 替换了 Content-Length 标头,这违背了整个目的。

谁能建议我应该做什么?谢谢

4

3 回答 3

6

来自 w3c 超文本传输​​协议——HTTP/1.1:

当在允许消息体的消息中给出 Content-Length 时,其字段值必须与消息体中的八位字节数完全匹配。HTTP/1.1 用户代理必须在收到和检测到无效长度时通知用户。

和:

Content-Length entity-header 字段指示发送给接收者的实体主体的大小,以十进制的八进制数表示,或者在 HEAD 方法的情况下,将发送的实体主体的大小具有请求是 GET。

所以,我想,如果您向服务器发送真正的 HEAD 请求,您的代码将正常工作。

于 2017-01-04T12:25:13.773 回答
0

正如 Lurii 提到的,内容长度受您的请求类型的影响。

对于 GET 请求,不匹配的内容长度可能会导致客户端挂起,因此 LiteSpeed 将在将标头发送到客户端之前验证内容长度。

使用 HEAD 请求应按预期返回内容长度。

于 2017-01-04T19:53:55.840 回答
0

这是网络服务器的工作,不是你的。

就我而言,我将所有内容都留给了 Apache 网络服务器,除了解析请求的方式之外,我的 php 代码没有任何变化

例如像这样的事情

if($_SERVER['REQUEST_METHOD'] === "GET"){
     //ok
}else{
     //send 400 Bad Request
}

改为

if($_SERVER['REQUEST_METHOD'] === "GET" || $_SERVER['REQUEST_METHOD'] === "HEAD"){
     //ok
}else{
     //send 400 Bad Request
}

Apache 完成了所有繁重的工作(对响应正文进行了条纹处理)。

(不要尝试ob_clean()die("")或类似的事情)。

相关资源:

http://hc.apache.org/httpclient-3.x/methods/head.html

https://security.stackexchange.com/questions/62811/should-i-disable-http-head-requests

Apache 2.2.2 对 HEAD 请求的响应

于 2018-08-08T02:50:10.823 回答