I am using curl API to call a SOAP web service with two SSL authentication and uses UserName,PasswordDigest and Nounce in SOAP headers .
curl API code is:
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, "WEBSERVICE_URL" );
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 1000);
curl_setopt($soap_do, CURLOPT_TIMEOUT, 1000);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true );
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($soap_do, CURLOPT_POST, true );
curl_setopt($soap_do, CURLOPT_VERBOSE, '1');
curl_setopt($soap_do, CURLOPT_SSLVERSION, '1');
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($soap_do, CURLOPT_SSLKEYPASSWD, 'secret');
curl_setopt($soap_do, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($soap_do, CURLOPT_SSLKEY,"C:/XP/Projects/setups/certs/key.pem");
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $in);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=utf-8', 'Content-Length: '.strlen($in) ));
$out = curl_exec($soap_do);
if($out === false)
{
echo "err";
$err = 'Curl error: ' . curl_error($soap_do);
curl_close($soap_do);
echo $err;
return $err;
}
else
{
echo "response ==";
echo $out;
echo "execu";
curl_close($soap_do);
return 'Operation completed without any errors';
}
CACERTS are already set in php.ini file:
Response is always Policy Falsified, can anybody please review that SSLKEY is properly set and outbound POST message will be encrypted with this key?
Full Response is:
response ==<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>soapenv:Receiver</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">Policy Falsified</soapenv:Text>
</soapenv:Reason>
<soapenv:Role>REMOVED FOR PRIVACY</soapenv:Role>
<soapenv:Detail>
<l7:policyResult status="Bad Request" xmlns:l7="http://www.layer7tech.com/ws/policy/fault"/>
</soapenv:Detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
execu* Trying 216.178.233.150...
* Connected to impl.client.com (216.178.233.150) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: C:/Project_ah/php/cacert.pem
CApath: none
* SSL connection using TLSv1.0 / DHE-RSA-AES256-SHA
* Server certificate:
* subject: C=US; ST=Maryland; L=Baltimore; O=Centers for Medicare & Medicaid Services; OU=OIS; CN=REMOVED FOR PRIVACY
* start date: 2014-12-31 00:00:00 GMT
* expire date: 2016-01-23 23:59:59 GMT
* subjectAltName: REMOVED FOR PRIVACY
* issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 Secure Server CA - G4
* SSL certificate verify ok.
> POST /Imp1/servie HTTP/1.1
Host: REMOVED FOR PRIVACY
Accept: */*
Content-Type: text/xml; charset=utf-8
Content-Length: 2517
Expect: 100-continue
< HTTP/1.1 100 Continue
< HTTP/1.1 500 Internal Server Error
< Server: Apache-Coyote/1.1
< Content-Type: application/soap+xml;charset=utf-8
< Content-Length: 746
< Date: Wed, 03 Jun 2015 03:53:13 GMT
< Connection: close
<
* Closing connection 0
Note: Not using SOAPClient because it fails in parsing WSDL due to nested XSDs defining namespaces again
Related
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.
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)');
I'm getting started with the Enavato API
So far I've created an app, got client_id & client_secret and managed to get the code access_key from the https://api.envato.com/authorization after that I'm using the below php code to make POST curl request
$client_id = '***********';
$client_secret = '***********';
$redirect_uri = urlencode('http://localhost:3000');
if(isset($_GET["code"])) :
$apiUrl = 'https://api.envato.com/token';
$params = array(
'grant_type' => 'authorization_code',
'code' => $_GET["code"],
'redirect_uri' => $redirect_uri,
'client_id' => $client_id,
'client_secret' => $client_secret,
);
$curl = curl_init();
$f = fopen('request.txt', 'w');
curl_setopt($curl, CURLOPT_URL, $apiUrl);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_STDERR, $f);
$result = curl_exec($curl);
fclose($f);
// Check if any error occurred
if(empty($result))
{
// die(curl_errno($curl));
// die(curl_error($curl));
$info = curl_getinfo($curl);
echo '<br><br>';
echo 'Took ' . $info['total_time'] . ' seconds to send a request to ' . $info['url'];
echo '<br><br>';
var_dump($info);
echo '<br><br>';
}
var_dump($result);
// Close handle
curl_close($curl);
endif;
and here is the request.txt dump
* Hostname was found in DNS cache
* Hostname in DNS cache was stale, zapped
* Trying 107.23.230.180...
* Connected to api.envato.com (107.23.230.180) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.envato.com
* Server certificate: RapidSSL SHA256 CA - G3
* Server certificate: GeoTrust Global CA
> POST /token HTTP/1.1
Host: api.envato.com
Accept: */*
Content-Length: 699
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------1a95a06d7b815306
< HTTP/1.1 100 Continue
< HTTP/1.1 400 Bad Request
< Access-Control-Allow-Origin: *
< Cache-Control: no-store
< Content-Type: application/json; charset=utf-8
< Date: Sun, 17 May 2015 17:03:41 GMT
< Pragma: no-cache
* Server nginx/1.7.10 is not blacklisted
< Server: nginx/1.7.10
< set-cookie: connect.sid=s%3ARC9gGye-Txp4KLp67M9ESspXijYoUc8i.pT3jYHvu1WyOsSjwsuQzEsy5hLQlc2QpmHkZRm05pXo; Path=/; HttpOnly
< X-Frame-Options: Deny
< X-Powered-By: Express
< Content-Length: 80
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0
and finally the error(getting it in JSON)
string(80) "{"error":"invalid_request","error_description":"No authorization header passed"}"
Astonishingly every thing is working with Postman and I'm getting "refresh_token" and "access_token" with a success 200 status code.
I know I'm missing some thing but couldn't find what?
You're using curl_setopt($curl, CURLOPT_POSTFIELDS, $params); with $params being an array. That results in a HTTP POST message with multipart/form-data content type and formatting. But the spec says the content type should be application/x-www-form-urlencoded. You can achieve this by using:
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
You also don't need to urlencode the redirect_uri parameter, since http_build_query will do it for you.
Lastly, do not turn off SSL validation (CURLOPT_SSL_VERIFYHOST, CURLOPT_SSL_VERIFYPEER) since it renders your system insecure.
I am using this code to test making a connection with curl:
$url = "https://www.google.com";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_STDERR, $fp);
curl_setopt($ch, CURLOPT_CERTINFO, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
//curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,0);
//curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds
$result = curl_exec($ch);
curl_errno($ch)==0 or die("Protocol SSLv3 Disabled.\n\nError:".curl_errno($ch)." ".curl_error($ch));
fseek($fp, 0);//rewind
$str='';
while(strlen($str.=fread($fp,8192))==8192);
echo $str;
The output looks like this:
* Rebuilt URL to: https://www.google.com/
* Hostname was NOT found in DNS cache
* Trying 74.125.237.211...
* Connected to www.google.com (74.125.237.211) port 443 (#0)
* SSL connection using SSLv3 / ECDHE-RSA-AES128-SHA
* Server certificate:
* subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
* start date: 2015-04-08 14:16:31 GMT
* expire date: 2015-07-07 00:00:00 GMT
* issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> HEAD / HTTP/1.1
Host: www.google.com
Accept: */*
< HTTP/1.1 302 Found
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Location: https://www.google.com.au/?gfe_rd=cr&ei=0FY_Vd7PD8yN8Qe80IEI
< Content-Length: 261
< Date: Tue, 28 Apr 2015 09:45:52 GMT
< Server: GFE/2.0
< Alternate-Protocol: 443:quic,p=1
<
* Connection #0 to host www.google.com left intact
I would like to suppress all the information shown after the SSL information. Basically everything from > HEAD / HTTP 1.1 and down I don't want to be displayed.
Any ideas on how to can achieve this?
you have the verbose parameter set to 1. Perhaps you can set it to 0 and show the output.
i was looking for how to get the output verbose :)
The following command works perfect in the command line:
c:\>curl -v -H "Content-Type: text/xml" -d "<?xml version='1.0' encoding='utf-8'?><methodCall><methodName>create_account</methodName><params><param><value><struct><member><name>user</name><value><string>test</string></value></member><member><name>server</name><value><string>chat3.activengage.com</string></value></member><member><name>password</name><value><string>test</string></value></member></struct></value></param></params></methodCall>" http://localhost:4561
* About to connect() to localhost port 4561 (#0)
* Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 4561 (#0)
> POST / HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost:4561
> Accept: */*
> Content-Type: text/xml
> Content-Length: 428
>
* upload completely sent off: 428 out of 428 bytes
< HTTP/1.1 200 OK
< Content-Length: 113
< Server: Erlang/Process-One
< Connection: close
<
<?xml version="1.0"?><methodResponse><params><param><value><int>0</int></value><
/param></params></methodResponse>* Closing connection #0
And in PHP using the code below:
public /*string*/ function registerUser(/*string*/$user,/*string*/$pass){
$xml = "<?xml version='1.0' encoding='utf-8'?><methodCall><methodName>create_account</methodName><params><param><value><struct><member><name>user</name><value><string>test2</string></value></member><member><name>server</name><value><string>chat3.activengage.com</string></value></member><member><name>password</name><value><string>test</string></value></member></struct></value></param></params></methodCall>";
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, 'http://127.0.0.1:4561');
curl_setopt($handle, CURLOPT_VERBOSE, 1);
curl_setopt($handle, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_POSTFIELDS, $xml);
$content = curl_exec($handle);
echo $xml;
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
print_r($httpCode);
print_r($content);
if(curl_errno($handle))
{
echo 'error:' . curl_error($handle);
}
curl_close($handle);
}
The result is a HTTP Status code 400. Is there something I'm doing wrong?
UPDATE - The result of CURLINFO_HEADER_OUT
string(99) "POST / HTTP/1.1
Host: localhost:4561
Accept: */*
Content-Type: text/xml
Content-Length: 400
"
Running a curl request from my browser based PHP script failed after I broke my etc/resolv.conf file.
I discovered this after visiting
php5-curl error: couldn't resolve host
After fixing the resolve.conf file as follows:
(note: 192.168.1.1 is my router address)
# Generated by NetworkManager
nameserver 192.168.1.1
Curl behaved as expected.
I Hope it helps you