PHP response to HEAD request

3.6k views Asked by At

I have a PHP script that serves portions of a PDF file by byte ranges.

If an HTTP HEAD request is received, it should send back headers (including the PDF file size) but not the actual file contents. I have tried this:

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

The problem is that something (I assume the web server == LiteSpeed) replaces the Content-Length header with Content-Length: 0 - which defeats the whole purpose.

Can anyone suggest what I should be doing? Thanks

3

There are 3 answers

4
Iurii Drozdov On BEST ANSWER

From w3c Hypertext Transfer Protocol -- HTTP/1.1:

When a Content-Length is given in a message where a message-body is allowed, its field value MUST exactly match the number of OCTETs in the message-body. HTTP/1.1 user agents MUST notify the user when an invalid length is received and detected.

And:

The Content-Length entity-header field indicates the size of the entity-body, in decimal number of OCTETs, sent to the recipient or, in the case of the HEAD method, the size of the entity-body that would have been sent had the request been a GET.

So, I suppose, your code will properly work if you send real HEAD request to your server.

0
Kevin Fwu On

As Lurii mentioned, the content length is affected by your request type.

With GET requests, a non-matching content length may result in a hanging client, so LiteSpeed will verify the content length before sending the header to the client.

Using a HEAD request should return the content length as expected.

0
Accountant م On

It's the webserver job, not yours.

In my case I left everything to the Apache webserver and nothing changed in my php code except of how the requests is being parsed

For example things like

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

are changed to

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

and Apache did all the heavy lifting (striped the response body).

(don't try to ob_clean() or die("") or things like this).

related resources:

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 response on HEAD requests