cURL / Mailing Lists / curl-and-php / Single Mail



From: Shailesh N. Humbad <>
Date: Mon, 31 Mar 2008 11:07:46 -0500

I posted this as a documentation request in PHP here But I thought I'd post it here too to get
more feedback.

Setting CURLOPT_NOBODY to "true" with curl_setopt sets the request
method to HEAD for HTTP(s) requests, and furthermore, cURL does not read
any content even if a Content-Length header is found in the headers.
However, setting CURLOPT_NOBODY back to "false" does *not* reset the
request method back to GET. But because it is now "false", cURL will
wait for content if the response contains a content-length header.

If CURLOPT_NOBODY is set to "true" and back to "false", curl_exec will
appear to hang unexpectedly for a request. If the server times out the
connection, then an curl will return an error like "transfer closed with
2523 bytes remaining to read".

 From a usability standpoint, setting CURLOPT_NOBODY to "true" should
NOT set the request method to HEAD if it is not going to reset it back
when it is set to "false". Otherwise, the parameter is not truly
"on/off", and has unknown, undocumented side-effects. Ideally,
CURLOPT_NOBODY should only cause cURL to ignore the content-length
headers and not read any content.

The only way to reset the state of the cURL session is to set
CURLOPT_HTTPGET to "true", which both sets the request method to GET and
causes cURL to read content.

This behavior is not mentioned the PHP documentation, so it would be
nice to add something about it. Otherwise, reusing a curl handle causes
unexpected behavior. PHP bug 40997 is a consequence of this behavior:

So there are two documentation requests:

1. Mention that setting CURLOPT_NOBODY to "true" sets the request method
to HEAD for HTTP(S) requests, and cURL ignores the content-length header.

2. Mention that setting CURLOPT_NOBODY to "false" causes cURL to wait
for content if a content-length header is read, but it does *not* reset
the request method back to GET.

Test code:

$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 3); // set execution timeout
curl_setopt($ch, CURLOPT_URL,
// Changes request method to HEAD and ignore content
curl_setopt($ch, CURLOPT_NOBODY, true);

// cURL will wait for content, but not change the request method.
// curl_exec will timeout waiting for the content
curl_setopt($ch, CURLOPT_NOBODY, false);

// Setting HTTPGET to true resets the request method back to GET
// and cURL will read content.
//curl_setopt($ch, CURLOPT_HTTPGET, true);

print curl_error($ch)."\n";

Received on 2008-03-31