php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #80518 CURLOPT_READFUNCTION stream can't rewind
Submitted: 2020-12-15 09:19 UTC Modified: 2021-12-06 16:00 UTC
Votes:1
Avg. Score:2.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: malacca42 at gmail dot com Assigned:
Status: Open Package: cURL related
PHP Version: Next Minor Version OS: *
Private report: No CVE-ID: None
 [2020-12-15 09:19 UTC] malacca42 at gmail dot com
Description:
------------
CURLOPT_READFUNCTION  stream  can't rewind

Test script:
---------------
$file = __DIR__.'/payload';
$fp = fopen($file, 'r');

$ch = curl_init('http://localhost/server.php');
curl_setopt_array($ch, [
    CURLOPT_VERBOSE => true,
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_FOLLOWLOCATION => true,  // follow location
    CURLOPT_UPLOAD => true,
    CURLOPT_INFILESIZE => filesize($file),
    CURLOPT_READFUNCTION => function ($ch, $fd, $length) use ($fp) {
        return fread($fp, $length);
    },
]);

curl_exec($ch);
curl_close($ch);


----------

the "server.php"  is very simple

if (isset($_GET['n'])) {
    echo file_get_contents('php://input');
} else {
    Header("Location: sever.php?n=1");
    http_response_code(307);
}



Expected result:
----------------
server can read payload after redirect

as RFC, entity body will resend after response 307 redirect
https://tools.ietf.org/html/rfc7231#section-6.4

but CURLOPT_READFUNCTION function only read once
maybe  php lost CURLOPT_SEEKFUNCTION option
https://curl.se/libcurl/c/CURLOPT_SEEKFUNCTION.html

One more thing:
this is very very slow using php8,  php7 is fast



Actual result:
--------------
got issue

"necessary data rewind wasn't possible"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-12-15 09:21 UTC] nikic@php.net
-Summary: win7 +Summary: CURLOPT_READFUNCTION stream can't rewind
 [2020-12-15 10:37 UTC] malacca42 at gmail dot com
replace CURLOPT_READFUNCTION  to  CURLOPT_INFILE  still has same issue


Test script:
---------------
$file = __DIR__.'/payload';
$fp = fopen($file, 'r');

$ch = curl_init('http://localhost/server.php');
curl_setopt_array($ch, [
    CURLOPT_VERBOSE => true,
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_FOLLOWLOCATION => true,  // follow location
    CURLOPT_UPLOAD => true,
    CURLOPT_INFILESIZE => filesize($file),
    CURLOPT_INFILE => $fp,
]);

curl_exec($ch);
curl_close($ch);


result:
------------
also got "necessary data rewind wasn't possible"
 [2020-12-15 12:48 UTC] cmb@php.net
-PHP Version: 8.0.0 +PHP Version: 7.4
 [2020-12-15 12:48 UTC] cmb@php.net
This is not particularly related to PHP 8.0, but likely did never
work (at least it does not with PHP 7.3 and 7.4).  It seems to me
to make it work, we'd have to introduce CURLOPT_SEEKFUNCTION[1].

> this is very very slow using php8,  php7 is fast

Please file a separate ticket for this, because it is obviously
not directly related.

[1] <https://curl.se/libcurl/c/CURLOPT_SEEKFUNCTION.html>
 [2021-12-06 15:59 UTC] cmb@php.net
-Type: Bug +Type: Feature/Change Request -PHP Version: 7.4 +PHP Version: Next Minor Version
 [2021-12-06 15:59 UTC] cmb@php.net
Well, there is actually nothing in the docs[1] that indicates that
rewinding the stream would be supported.  Thus, changing to
feature request.

[1] <https://www.php.net/curl_setopt>
 [2021-12-06 16:00 UTC] cmb@php.net
-Operating System: windows +Operating System: *
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 11 20:01:26 2024 UTC