php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79855 php_curl lost content-length header on 302 redirect
Submitted: 2020-07-14 07:00 UTC Modified: 2020-07-15 08:56 UTC
From: kaa at g-it dot su Assigned:
Status: Not a bug Package: cURL related
PHP Version: 7.2.24 OS: Ubuntu 18.04.4 LTS
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kaa at g-it dot su
New email:
PHP Version: OS:

 

 [2020-07-14 07:00 UTC] kaa at g-it dot su
Description:
------------
Right version of php I'm using is 7.2.24. Installed from Ubuntu repos. PHP_curl with enabled CURLOPT_FOLLOWLOCATION lost http header "Content-Length" on second redirect with 302 "Redirect temporary".
Seems to be relevant to #53556

Test script:
---------------
		$verbose = fopen('curl.log', 'w+');

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $path);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
			"Content-Type: application/x-www-form-urlencoded",
			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
		));
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $order_data);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_VERBOSE, true);
		curl_setopt($ch, CURLOPT_STDERR, $verbose);
		$response = curl_exec($ch);
		curl_close($ch);

Actual result:
--------------
*   Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.dev.example.com
*  start date: Apr 27 00:00:00 2019 GMT
*  expire date: Apr 26 23:59:59 2021 GMT
*  subjectAltName: host "api.dev.example.com" matched cert's "*.dev.example.com"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
> POST /p2p/v2/payer HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Length: 224

* upload completely sent off: 224 out of 224 bytes
< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 213
< Connection: keep-alive
< Keep-Alive: timeout=20
< Cache-Control: private
< Location: /api/payer/auth?sessionToken=e744a95992fa405ba10662bbc6908d6bedd48a73cc0d45d589f4ef2f7d7a0b88
< Set-Cookie: returnUrl=http://example.com/returnurl.php; path=/
< 
* Ignoring the response-body
* Connection #0 to host api.dev.walletone.com left intact
* Issue another request to this URL: 'https://api.dev.example.com/auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88'
* Switch from POST to GET
* Found bundle for host api.dev.example.com: 0x5649fd243480 [can pipeline]
* Re-using existing connection! (#0) with host api.dev.example.com
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
> POST /auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88 HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

< HTTP/1.1 411 Length Required
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=us-ascii
< Content-Length: 344
< Connection: keep-alive
< Keep-Alive: timeout=20
< 
* Connection #0 to host api.dev.example.com left intact

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-14 07:26 UTC] sjon@php.net
-Status: Open +Status: Feedback -PHP Version: 7.2.32 +PHP Version: 7.2.24
 [2020-07-14 07:26 UTC] sjon@php.net
can you clarify what you think the bug is? The ignored Content-Length on the 302 response is perfectly valid, and I've tested with CURLOPT_HEADER=true and it correctly includes the Content-Length header in both the 302 and the final response
 [2020-07-14 07:35 UTC] kaa at g-it dot su
-Status: Feedback +Status: Open
 [2020-07-14 07:35 UTC] kaa at g-it dot su
I will illustrate,  with your permission)

Me --> Server : POST request with php_curl, content-length is ok
Me <-- Server : 302 Redirect temporary
Me --> Server : GET request with php_curl, content-length is missing
Me <-- Server : 411 Length Required

So I expect that php_curl will add "content-length" parameter on step 3.
 [2020-07-14 07:44 UTC] cmb@php.net
Well, actually we do no longer actively support 7.2.  Does any of the actively supported PHP versions[1] behave this way?

[1] <https://www.php.net/supported-versions.php>
 [2020-07-14 08:09 UTC] kaa at g-it dot su
Yes. I've installed PHP 7.4.8 (cli) (built: Jul 13 2020 16:45:47) ( NTS )
 [2020-07-14 17:31 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-07-14 17:31 UTC] requinix@php.net
Unless I'm misreading this, cURL is trying to switch from POST to GET
  * Switch from POST to GET
but since you apparently set a custom request method of POST
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method);
it's going to repeat that method on the second request.

So don't use a custom method and cURL will use POST/GET appropriately.

It's also suspicious that you're trying to send to /p2p/v2/payer but that redirects you to /auth. I don't think you're using the API correctly. Seems like you needed to authenticate *before* sending your request, then include whatever credentials (the sessionToken?) in it.
 [2020-07-15 08:53 UTC] kaa at g-it dot su
-Status: Feedback +Status: Closed
 [2020-07-15 08:53 UTC] kaa at g-it dot su
Damian Wadley, thank you vary much. You are right. Changing to curl_setopt($ch, CURLOPT_POST, 1) solve my problem and request now working properly. And I'm using protocol in right way)
 [2020-07-15 08:56 UTC] requinix@php.net
-Status: Closed +Status: Not a bug
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 10:01:29 2024 UTC