cURL response body missing (data not shown) - php

I'm working with a specific restful API on CakePHP 2.4.x, part of the API includes sending files via curl POST/PUT and we've been unable to replicate what we need in CakePHP's HttpSocket so opted for traditional curl. The attempts to use PHP's curl commands would output nothing at all (despite pauses to show they were running).
Setting up a shell_exec will output information but unfortunately we are not getting the response body which is important to save data or view specific error messages.
I'm adding everything I think is relevant to this issue (I am on OSX, local environment XAMPP). My cURL version prints:
curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz
Deprecated PHP Code (This prints string(0) "" )
$ch = curl_init();
curl_setopt ($ch, CURLOPT_HTTPHEADER, Array(
"Authorization: Bearer {$authInfo->access_token}",
'Accept: application/json'
));
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
$post[$data['file']['name']] = '#' . $data['file']['location'];
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_URL, $url);
$response = curl_exec($ch);
pr($post); // print_r wrapper
pr(curl_getinfo($ch));
var_dump($response);
curl_close($ch);
Shell Exec Code
This code works fine in actually doing what we want with the API, the only issue is we're not getting the response body.
$command = Configure::read('DM.CurlBinary') . ' -sb -k -v -X POST ';
$command .= $url . ' -F "' . $data['file']['name'] . '=#' . $data['file']['location'] . '"';
$command .= ' -H "AUTHORIZATION: Bearer ' . $authInfo->access_token . '"';
$command .= ' -H "ACCEPT: application/json" -H "EXPECT: 100-continue"';
$output = shell_exec($command);
pr($output); // print_r wrapper
pr($command);
Actual CURL Command
curl -sb -k -v -X POST https://idolcamp.idol.io/api/v1/tracks/857707/records -F "record[new_file]=#/Users/someuser/Documents/Development/DittoCake/app/tmp/Idol_857707.flac" -H "AUTHORIZATION: Bearer speacialtokengoeshere" -H "ACCEPT: application/json" -H "EXPECT: 100-continue"
Response
This shows as an 422 error because the file I am uploading already exists, I'd check it by its id but we have no response in order to get the id and check if it exists next time around.
Adding handle: conn: 0x7f8e3c004000
Adding handle: send: 0
Adding handle: recv: 0
Curl_addHandleToPipeline: length: 1
- Conn 0 (0x7f8e3c004000) send_pipe: 1, recv_pipe: 0
About to connect() to idolcamp.idol.io port 443 (#0)
Trying 212.83.129.122...
Connected to idolcamp.idol.io (212.83.129.122) port 443 (#0)
TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Server certificate: *.idol.io
Server certificate: Gandi Standard SSL CA
Server certificate: UTN-USERFirst-Hardware
POST /api/v1/tracks/857707/records HTTP/1.1
User-Agent: curl/7.30.0
Host: idolcamp.idol.io
AUTHORIZATION: Bearer somespecialtoken
ACCEPT: application/json
EXPECT: 100-continue
Content-Length: 29600116
Content-Type: multipart/form-data; boundary=----------------------------3bd64d03cd9b
HTTP/1.1 100 Continue
} [data not shown]
HTTP/1.1 422 Unprocessable Entity
Server nginx is not blacklisted
Server: nginx
Date: Tue, 25 Aug 2015 15:08:00 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
X-Request-Id: 3803269a-18ea-4558-8623-08810a058030
X-Runtime: 1.112917
HTTP error before end of send, stop sending
Closing connection 0
API Doc: Request
API Doc: Response

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

I am using php to connect to spotify's API with PHP and with the client credentials flow

I am new to using an sort of REST protocol and am having trouble getting my access token back from the cURL request.
This is using WAMP. I have already enabled the cURL extension and that works now. I also have already made a spotify application and have my client ID and secret ID.
<?php
/* Spotify Application Client ID and Secret Key */
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
/* Get Spotify Authorization Token */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://accounts.spotify.com/api/token' );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials' );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic '.base64_encode($client_id.':'.$client_secret)));
$result=curl_exec($ch);
$json = json_decode($result, true);
echo "Results of json: ". + $json['access_token'];
/* Get Spotify Artist Photo */
echo "<pre>";
exec('curl -i "https://api.spotify.com/v1/search?<br>q=Maycon+%26+Vinicius+&limit=1&type=artist" -H "Accept: application/json" -H "Authorization: Bearer '.$json['access_token'].'" -H "Content-Type: application/json" 2>&1', $pp);
echo implode("\r\n", $pp);
?>
The error that I get is:
""status": 400,
"message": "Only valid bearer authentication supported""
When I try to print out the results of my json resource variable $json[access_token] it prints 0.
Here is the full error message.
HTTP/2 400 www-authenticate: Bearer realm="spotify",
error="invalid_request", error_description="Only valid bearer
authentication supported" access-control-allow-origin: *
access-control-allow-headers: Accept, App-Platform, Authorization,
Content-Type, Origin, Retry-After, Spotify-App-Version
access-control-allow-methods: GET, POST, OPTIONS, PUT, DELETE,
PATCH access-control-allow-credentials: true
access-control-max-age: 604800 content-type: application/json
content-length: 99 date: Sat, 26 Oct 2019 15:55:39 GMT via:
1.1 google alt-svc: clear
Have you tried other requests and run into similar authentication errors? To test I took your query and simplified it a bit to test it on my system and it returned one artist, so it looks like it's working.
curl -i "https://api.spotify.com/v1/search?q=Maycon+%26+Vinicius+&limit=1&type=artist" -H "Accept: application/json" -H "Authorization: Bearer $AccessToken" -H "Content-Type: application/json"

cURL Failed to connect to port 80

I am using cURL in my PHP script to test my API. When i try to use my function to get data it throw me an error
Error: Failed to connect to alenke.test port 80: Connection refused
but when I execute it in the terminal
curl --ipv4 -v "http://alenke.test/wp-json/chatbot/v1/brand";
it give me
`Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to alenke.test (127.0.0.1) port 80 (#0)
GET /wp-json/chatbot/v1/brand HTTP/1.1
Host: alenke.test
User-Agent: curl/7.54.0
Accept:
HTTP/1.1 200 OK
Server: nginx/1.15.7
Date: Sun, 01 Sep 2019 16:47:36 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/7.3.7
X-Robots-Tag: noindex
Link: <http://alenke.test/wp-json/>; rel="https://api.w.org/"
X-Content-Type-Options: nosniff Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages Access-Control-Allow-Headers: Authorization, Content-Type Allow: GET `
and give me all data that I need but when to execute this php script
function callAPI($method, $url, $data){
$curl = curl_init();
switch ($method){
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// OPTIONS:
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "admin:admin");
// EXECUTE:
$result = curl_exec($curl);
if(!$result){
if (curl_errno($curl)) {
echo 'Error: ' . curl_error($curl);
echo'//;
echo print_r(curl_getinfo($curl));
echo'//;
die("Connection Failure..?");
}
}
curl_close($curl);
return $result;
}
it shows me this error
Error: Failed to connect to alenke.test port 80: Connection refused
I've copy-pasted your code to a file (test.php) on my computer, surrounded it with a
<?php .. ?>
block, and added a call like this after the function:
$res=callAPI('GET', 'http://myserver/', '');
echo $res;
Then started the script in command line by php test.php, and got the expected result (the index.html file of my server).
So whatever you're doing works. Try testing it in command line first to see if necessary modules are installed/enabled. If it works that way, try to fix your webserver's config files. If you need more help, please add some information about your system (webserver, version, OS, and anything relevant). Sysadmins tend to disable certain features (including curl) on shared hosting, maybe your default configuration is based on that.
I will recommend you check your firewall and to check if the domain what ip is resolving.
telnet domain 80
telnet ipserver 80

SSL connection through proxy server

I'm trying to connect to the Twitter api server to make an "Application-only Autentication".
I don't care any other way to connect to Twitter. I need this specific method.
I need to go from localhost through my corporation's proxy to api.twitter.com which needs ssl
Following the instruction of this twitter developer's page https://dev.twitter.com/docs/auth/application-only-auth, i tried with:
cUrl:
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if ($this->proxy != '') {
curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
curl_setopt($ch, CURLOPT_PROXYPORT, $this->port);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->userpwd);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("
POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
"));
$response = curl_exec($ch);
if (FALSE === $response) throw new Exception(curl_error($ch), curl_errno($ch));
curl_close($ch);
var_dump(json_decode($response));
}
catch(Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
Which gives me
Fatal error: Curl failed with error #35: Unknown SSL protocol error in connection to api.twitter.com
file_get_contents:
$context = stream_context_create(array(
"http" => array(
"method"=>"CONNECT",
"proxy" => $this->proxy.":".$this->port,
"request_fulluri" => true,
"header" => "
POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Proxy-Authorization: Basic ".base64_encode(urlencode($this->userpwd))."
Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
",
),
));
$response = file_get_contents($url, False, $context);
var_dump(json_decode($response));
Which gives me
Warning: file_get_contents(https://api.twitter.com/oauth2/token) [function.file-get-contents]: failed to open stream: Cannot connect to HTTPS server through proxy
fsockopen:
$fp = fsockopen($this->proxy, $this->port);
fputs($fp, "
POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
");
$data="";
while (!feof($fp)) $data .= fgets($fp,1024);
fclose($fp);
var_dump($data);
Which gives me
HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 727
I am sure that the 443 port is open and it's not a problem of the localhost (I got the same error trying on an online server).
I tried even using CONNECT method instead of POST.
I tried tunneling the proxy, but I'm neither sure I made it nor that that's the problem.
I'm running out ideas..
Try to remove this:
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
You only have one value in this array, it's wrong.
curl_setopt($ch, CURLOPT_HTTPHEADER, array("
POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
"));
Change the above for this:
$consumer_key = base64_encode(urlencode($consumer_key);
$consumer_secret = urlencode($consumer_secret);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Host: api.twitter.com",
"User-Agent: My Twitter App v1.0.23",
"Authorization: Basic $consumer_key:$consumer_secret",
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
"Accept-Encoding: gzip",
"grant_type=client_credentials"
));
if you want to include the Content-Length: xx, you need to use strlen() to get string length of the post, ex;
$length = strlen($post_content);
Then add it to the CURLOPT_HTTPHEADER array:
"Content-Length: $length"
Found the problem. There's no need (maybe only in this case, i'm not sure) to base64 encode the credentials. They'll be encoded by the server.
I don't know the reason of that different error responses, but was in fact a problem of double encoding, because of which the server was not able to verify my credentials.

cURL works via command line but not in PHP Curl

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

Categories