PHP_curl loose content-length on redirect

I’m trying to make a request to payment processing page. This requires authorization, which takes place through a set of redirects. In the second step, I get "411 Length Required" error, which means that content-length was lost along the way. Indeed, I cannot see it in the log. What can be done here? Change tool (programming language)?

CURLOPT_VERBOSE:

*   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  

My code is:

        $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); 
Add Comment
2 Answer(s)

Set the content-length in the header, which would be set to the string length strlen() of $order_data

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",    "Content-Length: ". strlen($order_data)    ));   

you can also debug this by checking out curl_setopt($ch, CURLINFO_HEADER_OUT, true); which makes curl_getinfo() include the request’s headers in its output.

Answered on July 16, 2020.
Add Comment

The problem was in using curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method). Curl tryed to swithc to GET, like mostly browsers do, but cannot. Use curl_setopt($ch, CURLOPT_POST, 1); indeed.

Answered on July 16, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.