PHP_curl loose content-length on redirect - php

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

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.

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.

Related

Curl is working however error with php CURL

We want to communicate to the 3rd party API for which we are using curl from linux terminal. The curl is -
curl -X POST \
\
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json'
When we fire this curl then we are getting expected response.
However, when we try to do this from PHP script then we are getting error as -
HTTP ERROR 500
PHP Code snippet is -
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, <URL>);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
//curl_setopt($ch, CURLOPT_POSTFIELDS,'');
curl_setopt($ch, CURLOPT_VERBOSE,true);
$headers = array();
$headers[] = 'Authorization: Bearer <token>';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo $result;
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
?>
When verbose mode is on then response received is -
* Trying <IP>...
* Connected to <URL> (<IP>) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: OU=Domain Control Validated; CN=* <domain>
* start date: Dec 17 10:41:01 2017 GMT
* expire date: Dec 17 10:41:01 2020 GMT
* subjectAltName: <URL> matched
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify ok.
> POST /app/auth HTTP/1.1
Host: <URL>
Accept: */*
Authorization: Bearer <Token>
Content-Type: application/json
Expect: 100-continue
< HTTP/1.1 500 Request failed.
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Type: text/html;charset=iso-8859-1
< Date: Wed, 08 Jan 2020 04:39:23 GMT
< Content-Length: 252
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Request failed.</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /app/auth. Reason:
<pre> Request failed.</pre></p>
</body>
</html>
Please note that Ihave replaced actual URL,IP and token while posting the question here.
To make sure that there are no issues with the PHP curl we used curl-to-PHP code generator utility to generate code ( http://incarnate.github.io/curl-to-php/).
Can someone please help me and let me know what might be going wrong.
To avoid «500 error» (for example) be sure to:
set proper "Referer: " header if needed, with
curl_setopt(CURLOPT_REFERER, 'ref page');
set proper "User-Agent: " header, with
curl_setopt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');

Invalid client error with curl POST request

I'm having troubles trying to get an access token from an oauth endpoint.
I'm making a curl POST request in the following way
$username = 'Joe';
$password = 'Doe##!'
$auth = 'Basic Y245Y3BleGF4aTp2ZWludGZxMmVwbGd5anU1Y2N6aGZtNmZ3OXdlNmJ=';
$headers = [
'Authorization' => $auth,
'Content-Type' => 'application/x-www-form-urlencoded',
];
$form_params = [
'username' => $username,
'password' => $password,
'grant_type' => 'password',
'scope' => 'auto'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://oauth.wildapricot.org/auth/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($form_params));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
but I keep getting a invalid client error (the $auth variable consists in the client and secret encoded with base 64).
I've tried encoding the postfields but didn't help. I've hardcoded the $auth variable just in case the base64_encode function was messing it up (I generated it with that function before), but it didn't change anything.
I've checked that the endpoint was actually working with Postman and it actually is.
Any ideas on what could be the issue?
Edit: I've just added some debugging lines into the code and this is what I got (if that's of any help)
* Trying 34.226.77.200:443...
* TCP_NODELAY set
* Connected to oauth.wildapricot.org (34.226.77.200) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/local/etc/openssl/cert.pem
CApath: /usr/local/etc/openssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; postalCode=M5J 2L7; ST=Ontario; L=Toronto; street=144 Front Street West; O=Wild Apricot Inc.; OU=PremiumSSL Wildcard; CN=*.wildapricot.org
* start date: Sep 20 00:00:00 2018 GMT
* expire date: Nov 17 23:59:59 2020 GMT
* subjectAltName: host "oauth.wildapricot.org" matched cert's "*.wildapricot.org"
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Organization Validation Secure Server CA
* SSL certificate verify ok.
> POST /auth/token HTTP/1.1
Host: oauth.wildapricot.org
Accept: */*
Content-Length: 76
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 76 out of 76 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Length: 68
< Content-Type: application/json; charset=utf-8
< Expires: -1
< WWW-Authenticate: Basic realm="authentication required"
< X-Powered-By: ASP.NET
< Access-Control-Allow-Origin: *
< Date: Fri, 15 Nov 2019 12:29:30 GMT
< Connection: close
< X-Backend-Server: lap1wue1b-62e2
< X-LB-Server: llblue1b-5471
<
* Closing connection 0
This line tells us there's a problem with your authentication:
WWW-Authenticate: Basic realm="authentication required"
Curl provides a simpler method for HTTP Basic auth. Try removing the Authorization header and setting the CURLOPT_USERPWD option instead:
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);

Trying to get data from IOT using PHP

I'm trying to get JSON from my IOT application. I can post data to my IOT application so my connection is ok but cant get a response. I only get a not allowed error.
I use this code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$endpoint_url);
$result = curl_exec($ch);
if ($result === FALSE) {
printf("cUrl error (#%d): %s<br>\n", curl_errno($ch),
htmlspecialchars(curl_error($ch)));
}
curl_close($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
But all I get back is the following:
Verbose information:
* Hostname integrations.thethingsnetwork.org was found in DNS cache
* Trying 13.69.184.129...
* Connected to integrations.thethingsnetwork.org (13.69.184.129) port 443
(#0)
* ALPN, offering http/1.1
* Cipher selection:
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* 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: CN=integrations.thethingsnetwork.org
* start date: Jan 31 12:04:08 2019 GMT
* expire date: May 1 12:04:08 2019 GMT
* subjectAltName: integrations.thethingsnetwork.org matched
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> GET /ttn-eu/api/v2/down/secret/test?key=secret HTTP/1.1
Host: integrations.thethingsnetwork.org
Accept: */*
< HTTP/1.1 405 Method Not Allowed
< Server: nginx/1.13.7
< Date: Wed, 20 Mar 2019 15:33:10 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host integrations.thethingsnetwork.org left intact
How can I get the data?
You are not specifying the Request type in your curl request which automatically defaults it to a GET one. Add the following to your code.
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

can't get image using php CURL with SSL

so I'm trying to make a CURL connection using PHP....when I use command line here's what gets returned
curl -iv https://example.com/image.gif
* Hostname was NOT found in DNS cache
* Trying ip.ad.dr.es.ss...
* Connected to site.com (ip.ad.dr.es.ss) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* Server certificate: example.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> GET /image.gif HTTP/1.1
> User-Agent: curl/7.37.1
> Host: example.com
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: image/gif
Content-Type: image/gif
< Last-Modified: Thu, 14 Jul 2011 22:16:46 GMT
Last-Modified: Thu, 14 Jul 2011 22:16:46 GMT
< Accept-Ranges: bytes
Accept-Ranges: bytes
< ETag: "09bd8b77342cc1:0"
ETag: "09bd8b77342cc1:0"
* Server Microsoft-IIS/7.5 is not blacklisted
< Server: Microsoft-IIS/7.5
Server: Microsoft-IIS/7.5
< X-Powered-By: ASP.NET
X-Powered-By: ASP.NET
< X-UA-Compatible: IE=EmulateIE10, requiresActiveX=true
X-UA-Compatible: IE=EmulateIE10, requiresActiveX=true
< Date: Thu, 05 Nov 2015 20:57:22 GMT
Date: Thu, 05 Nov 2015 20:57:22 GMT
< Content-Length: 43
Content-Length: 43
< Set-Cookie: BIGipServerSpace=596747530.20480.0000; path=/
Set-Cookie: BIGipServerSpace=596747530.20480.0000; path=/
<
* Connection #0 to host example.com left intact
And here's how I try to access it via PHP
$ch = curl_init();
$url_to_check = 'https://example.com/image.gif';
curl_setopt( $ch, CURLOPT_URL, $url_to_check );
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
curl_setopt($ch, CURLOPT_PORT, 443);
curl_exec( $ch );
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo curl_error($ch);
echo '||';
echo $httpcode;
curl_close( $ch );
But then it ends up returning
Empty reply from server||0
What did I do wrong? How can I fetch the image using SSL via php CURL accordingly?
What cURL version is your PHP using? Perhaps it doesn't support TLS 1.2 which was added in cURL 7.34.0.
Or your CA bundle might not recognize the CA of the site you are connecting to.
Try adding:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
To see the debug output from cURL in PHP like you get on the command line, you can add:
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'w'));
That might shed some light on the issue, as well as calling var_dump(curl_getinfo($ch)); after the request is executed.

Unable to post query string via CURL

URL Working fine in Browser after accepting the exception , but not working in curl.
My code is as follows :::
PHP CODE :
<?php
$str1 = "https://50.60.70.80/servlet/API";
$url = $str1."?".$_SERVER['QUERY_STRING'];
echo $url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST, true);
$data = curl_exec($ch);
echo curl_errno($ch);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
}
else {
echo 'Success: '.$data;
}
curl_close($ch);
?>
URL : https://50.60.70.80/servlet/API?userName=Test&password=pwd&message=My_Message&mobile=5555558888
Error getting while using through command line with "-k" and "-v":
***** About to connect() to 50.60.70.80 port 443 (#0)
* Trying 50.60.70.80... connected
* Connected to 50.60.70.80 (50.60.70.80) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* warning: ignoring value of ssl.verifyhost
* skipping SSL peer certificate verification
* SSL connection using TLS_DHM_RSA_W1TH_AES_128_CBC_SEA
* Server certificate:
* subject: E=abcd#mnmn.com,OU=lelna,O=teledna
* start date: Mar 01 09:51:25 2013 GMT
* expire date: Mar 01 09:51:25 2014 GMT
* common name: (nil)
* issuer: E=abcd#mnmn.com,OU=lelna,O=teledna
> GET /servlet/API?UserName=Test HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 50.60.70.80
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Pragma: no-cache
< Cache-Control: no-store
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Transfer-Encoding: chunked
< Date: Thu, 08 Aug 2013 16:38:57 GMT
<
status=FAILED,transid=4526698561,reasoncode=201
* Connection #0 to host 50.60.70.80 left intact
* Closing connection #0****
Can anybody help ?
I am using following versions ::
PHP Version -- 5.3.3
CURL Version -- 7.19.7
Using Apache
You need to add this
EDITED :
curl_setopt( $ch ,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

Categories