Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Invalid response header" with CURLOPT_FILE curl option #65

Closed
ilgazil opened this issue May 28, 2021 · 4 comments · Fixed by #66 or #68
Closed

"Invalid response header" with CURLOPT_FILE curl option #65

ilgazil opened this issue May 28, 2021 · 4 comments · Fixed by #66 or #68

Comments

@ilgazil
Copy link

ilgazil commented May 28, 2021

When using CURLOPT_FILE curl option to write huge contents into a file directly, the Response constructor tries to retrieve status code (which is not readable is this particular case) and leads to the Invalid response header exception.

$target = fopen('/path/to/target', 'wb');

$request = (new cURL())
  ->newRequest('get', 'http://path/to/resource')
  ->setOption(CURLOPT_FILE, $target);

$response = $request->send();
@anlutro
Copy link
Owner

anlutro commented Jun 1, 2021

Thanks for the report, I wasn't aware of this flag! Fixed in 1.5.0 :)

@ilgazil
Copy link
Author

ilgazil commented Jun 6, 2021

Hey, thanks for having been that fast.
But you still parse headers in response constructor, so it still fails... I haven't dug further, but I don't think there is anything in response...

The following code (with working links so that you can copy/paste to try it)

$curl = new cURL();

$file = fopen(realpath('.') . '/php-8.0.7.tar.gz', 'w');

$request = $curl
  ->newRequest('get', 'https://www.php.net/distributions/php-8.0.7.tar.gz')
  ->setOption(CURLOPT_FILE, $file)
  ->send();

Keeps throwing this exception:

PHP Fatal error:  Uncaught InvalidArgumentException: Invalid response header in /home/user/php-curl/vendor/anlutro/curl/src/Response.php:91
Stack trace:
#0 /home/user/php-curl/vendor/anlutro/curl/src/Response.php(74): anlutro\cURL\Response->parseHeaders()
#1 /home/user/php-curl/vendor/anlutro/curl/src/Response.php(61): anlutro\cURL\Response->parseHeader()
#2 /home/user/php-curl/vendor/anlutro/curl/src/cURL.php(333): anlutro\cURL\Response->__construct()
#3 /home/user/php-curl/vendor/anlutro/curl/src/cURL.php(292): anlutro\cURL\cURL->createResponseObject()
#4 /home/user/php-curl/vendor/anlutro/curl/src/Request.php(532): anlutro\cURL\cURL->sendRequest()
#5 /home/user/php-curl/index.php(12): anlutro\cURL\Request->send()
#6 {main}
  thrown in /home/user/php-curl/vendor/anlutro/curl/src/Response.php on line 91

The file is properly downloaded, but the script fails because being unable to get the response HTTP status code.

@anlutro
Copy link
Owner

anlutro commented Jun 6, 2021

The headers are part of the file that's downloaded, but there's something else going on here. I wrote a working test case but your example does indeed fail. I'll investigate further, it might be the combination of CURLOPT_FILE and something else, like gzip compression or HTTP/2.

@anlutro anlutro reopened this Jun 6, 2021
@anlutro
Copy link
Owner

anlutro commented Jun 6, 2021

Seems like this has something to do with how the file handle is opened. If you open it in write-only mode, fopen just returns an empty string. However, using w+ (same as tmpfile which I used in unit tests) doesn't seem to make a difference. I'll figure out a way to work around this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants