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 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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Fri May 09 14:01:27 2025 UTC