ID: 47204 Updated by: srina...@php.net Reported By: a...@php.net Status: Open Bug Type: Feature/Change Request Operating System: Irrelevant -PHP Version: 5.2.8 +PHP Version: 5.3 -Assigned To: +Assigned To: srinatar New Comment:
since, this is a feature, this will probably apply only for 5.3 onwards. Previous Comments: ------------------------------------------------------------------------ [2009-09-20 17:31:31] j...@php.net Recategorized, this is not a bug. ------------------------------------------------------------------------ [2009-09-20 08:47:21] a...@php.net Marking this as "cURL related" to increase visibility. ------------------------------------------------------------------------ [2009-06-22 16:04:07] felix-php at 7val dot com This problem not only occurs when negotiating HTTP Auth. It's much easier to provoke by posting to a URL that answers with a redirect. Any valid HTTP redirect (be it 302, 303 or 307) lets curl rewind its request body before following the Location header. Thus CURLOPT_READFUNCTION is pretty useless for accessing web servers in the wild. Therefore I think it's rather a bug than a feature. Reproduce: Both examples above with an extra curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); and a URL answering with a redirect. (Tested with PHP 5.2.9 and curl 7.19.5) Proposal: Instead of adding CURLOPT_IOCTLFUNCTION to the PHP extension, this bug could be fixed by adding the CURLTOP_SEEKFUNCTION functionality. If set, curl uses this to rewind the body, too (see Curl_readrewind() in transfer.c). But the seek_func callback is also used for resuming uploads which might be a nice side effect. ------------------------------------------------------------------------ [2009-01-23 23:39:02] a...@php.net The same problem without PHP callback, using CURLOPT_READDATA to read request body from a file: <?php $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, true); // This should be some URL protected by HTTP digest auth! curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/digest/'); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_setopt($ch, CURLOPT_USERPWD, 'user:password'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . filesize('./postdata'))); curl_setopt($ch, CURLOPT_READDATA, fopen('./postdata', 'rb')); if (!curl_exec($ch)) { echo 'Error #' . curl_errno($ch) . ': ' . curl_error($ch); } ?> This also prints "Error #65: necessary data rewind wasn't possible" ------------------------------------------------------------------------ [2009-01-23 23:28:24] a...@php.net Description: ------------ PHP's cURL extension allows using a callback for reading the request body via CURLOPT_READFUNCTION, but it doesn't provide a way to set a CURLOPT_IOCTLFUNCTION callback for rewinding the request body. This rewinding may be needed when doing a POST or PUT HTTP request to resource protected by Digest authentication. Reproduce code: --------------- <?php $position = 0; $data = 'foo=' . str_repeat('bar', 10000); function read_callback($ch, $fd, $length) { global $position, $data; if ($position >= strlen($data)) { return ''; } $string = substr($data, $position, $length); $position += strlen($string); return $string; } $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, true); // This should be some URL protected by HTTP digest auth! curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/digest/'); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_setopt($ch, CURLOPT_USERPWD, 'user:password'); curl_setopt($ch, CURLOPT_READFUNCTION, 'read_callback'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($data))); if (!curl_exec($ch)) { echo 'Error #' . curl_errno($ch) . ': ' . curl_error($ch); } ?> Expected result: ---------------- Request should proceed. Actual result: -------------- Error #65: necessary data rewind wasn't possible ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=47204&edit=1