PHP对HEAD请求的响应

8
我有一个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标头替换为Content-Length: 0 - 这使得整个目的都失败了。
有人能建议我该怎么做吗?谢谢。

你检查过 $Pathname 是否正确了吗? - Smort
你怎么知道它被替换了? - Bart Friederichs
@Paul,是的,$Pathname变量肯定是正确的。我还写了一个日志文件来确认filesize($Pathname)是实际文件大小。 - oomp
@BartFriederichs - 通过在Firefox中查看网络活动(按下F12键)来进行观察。 - oomp
尝试了@IuriiDrozdov - Firefox工具箱报告Dummy-Length: 1545019Dummy-Exists: 1(但也有Content-Length: 0)。 - oomp
显示剩余4条评论
3个回答

6

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

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

另外:

Content-Length实体头字段指示发送到接收者的实体正文的OCTET的十进制数,或者在HEAD方法的情况下,如果请求是GET,则将发送的实体正文的大小。

因此,我认为,如果您向服务器发送真正的HEAD请求,则您的代码将正常工作。


我看不出一个真正的HEAD请求会有什么区别,因为PHP响应独立于初始请求,不是吗? - oomp
2
“我认为真正的HEAD请求不会有任何区别。” - 我可以。这就坚定地将责任归咎于Web服务器,而不是PHP或您的代码(假设您对HEAD请求的响应具有相同的行为)。 - symcbean
@oomp 试一下吧。你可以使用curl -i -D -I -X HEAD http://yourserver.com(http://和域名之间不要有空格)或Postman。 - Iurii Drozdov
1
谢谢 - 还有 @symcbean - 你是对的。谁会相信为了响应 HEAD 请求,你需要一个 HEAD 请求呢?现在我感觉有点傻。 - oomp

2

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

在我的情况下,我把一切都留给了Apache Web服务器,除了请求的解析方式之外,我的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请求上的响应


0
如Lurii所述,内容长度受到请求类型的影响。
使用GET请求时,不匹配的内容长度可能导致客户端挂起,因此LiteSpeed会在向客户端发送标题之前验证内容长度。
使用HEAD请求应按预期返回内容长度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接