
Sending HEAD requests with ext/curl
ext/curl is the common tool of choice, if one needs to perform more advanced HTTP requests from a PHP script (for simple ones, use a stream!). I recently wanted to perform a HEAD request to a file, after which I wanted to perform some more advanced HTTP interaction, so CURL was also the tool of choice here.
Trying it out on the shell with a local web server, CURL was operating quite slow, in contrast to a GET request. The -i command line switch makes curl include the headers in the printed output, -X lets you define a custom HTTP request.
dotxp@tango ~ $ time curl -i -X HEAD http://localhost/admin/
HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:10:59 GMT
Server: lighttpd/1.4.19
real 0m6.079s
user 0m0.004s
sys 0m0.000s
dotxp@tango ~ $ time curl -i -X GET http://localhost/admin/
HTTP/1.1 200 OK
Transfer-Encoding: chunked
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:12:27 GMT
Server: lighttpd/1.4.19
<snip content="html source" />
real 0m0.180s
user 0m0.004s
sys 0m0.000s
A difference of 6 seconds runtime of a HEAD in contrast to 0.2 seconds for a GET is quite contrary to the original idea of a HEAD request. HEAD is used to just receive the headers of an URI instead of receiving the whole contents, to save bandwidth, memory and execution time.
ext/curl showed the exact same problem. Fiddling a bit with the command line switches, I found to replace -i with -I which makes curl print only the headers, but not the body of the response.
dotxp@tango ~ $ time curl -I -X HEAD http://localhost/admin/
HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:19:05 GMT
Server: lighttpd/1.4.19
real 0m0.044s
user 0m0.004s
sys 0m0.000s
0.04 seconds is now even faster than the corresponding GET request, with the -I switch, which took me 0.09 seconds. Now I just needed to transfer the command line options to the corresponding ext/curl ones:
$c = curl_init();
curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $c, CURLOPT_CUSTOMREQUEST, 'HEAD' );
curl_setopt( $c, CURLOPT_HEADER, 1 );
curl_setopt( $c, CURLOPT_NOBODY, true );
curl_setopt( $c, CURLOPT_URL, 'http://localhost/admin/' );
$res = curl_exec( $c );
The RETURNTRANSFER makes ext/curl return the HTTP response instead of printing it. Using the CUSTOMREQUEST option you define to send a HEAD request instead of a standard GET or POST request. The HEADER option makes ext/curl include the response headers in the return value of curl_exec() call and NOBODY avoids the inclusion of the body content here. The URL option as usually sets the URL to request and curl_exec() makes ext/curl execute the request.
The runtime was even a fraction of a second faster here, compared to the command line version, but that can be subjectively. However, the HEAD request works as expected now. Maybe it's useful for someone to know this.
Comments