cURL works via command line but not in PHP Curl - php

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

Related

curl works in CLI, but not in PHP

curl works in CLI, but not in PHP.
The following command works in the command line:
curl -X POST --header "Content-Type: application/json" --header "Authorization: Basic [token]" https://api.example.com/v1/token -v -k
* About to connect() to api.example.com port 443 (#0)
..
> POST /v1/token HTTP/1.1
> User-Agent: curl/7.29.0
> Host: api.example.com
> Accept: */*
> Content-Type: application/json
> Authorization: Basic [token]
>
< HTTP/1.1 200 OK
< Date: Fri, 30 Apr 2021 02:52:24 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 325
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"145-rseWkvhNxxhur+O7jUfApznKiww"
<
* Connection #0 to host api.example.com left intact
{"accesstoken":"token","type":"Bearer","expired":"20210501115224"}
And in PHP using the code below:
test.php
<?php
$host = 'https://api.example.com/v1/token';
$headers = array(
'Content-Type: application/json',
'Authorization: Basic [token]'
);
$oCurl = curl_init();
curl_setopt($oCurl, CURLOPT_URL, $host);
curl_setopt($oCurl, CURLOPT_POST, true);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($oCurl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($oCurl, CURLOPT_VERBOSE, true);
$response = curl_exec($oCurl);
curl_close($oCurl);
$ php test.php
* About to connect() to api.example.com port 443 (#0)
..
> POST /v1/token HTTP/1.1
Host: api.example.com
Accept: */*
Content-Type: application/json
Authorization: Basic [token]
Content-Length: -1
Expect: 100-continue
< HTTP/1.1 100 Continue
< HTTP/1.1 400 Bad Request
< Server: nginx
< Date: Fri, 30 Apr 2021 04:22:08 GMT
< Content-Type: text/html
< Content-Length: 150
< Connection: close
<
* Closing connection 0
The result is a HTTP Status code 400 Bad Request. Is there something I'm doing wrong?
Please Help.
Any ideas would be greatly appreciated.
Content-Length: -1 looks weird.
Seems like cURL is adding that automatically, because your request does not contain a POST body - but then it should be set to 0, if it gets set at all.
Add 'Content-Length: 0' to your $headers array, so that cURL won’t add the header itself with the wrong value.
#choi
did you encode your token?
ej.
$host = 'https://api.example.com/v1/token';
$token = base64_encode('username:Password0..');
$headers = array(
'Content-Type: application/json',
'Authorization: Basic ' . $token
);
$oCurl = curl_init();
curl_setopt($oCurl, CURLOPT_URL, $host);
...
Response
$> php curl_test.php
* Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /v1/token HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Content-Type: application/json
Authorization: Basic dXNlcm5hbWU6UGFzt3dtcmQwLi4=
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Fri, 30 Apr 2021 06:50:59 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
...
Ref: curl basic auth

Converting Curl command to PHP not working

I have curl command working through terminal and when I converts that command in PHP, it is giving me an error.
Here is Curl command from terminal:
[root#localhost ~]# curl -XPOST -v http://localhost:5636/api/1/event/AVyWHzgsJ-3JxxYdx60x/archive
* About to connect() to localhost port 5636 (#0)
* Trying ::1...
* Connected to localhost (::1) port 5636 (#0)
> POST /api/1/event/AVyWHzgsJ-3JxxYdx60x/archive HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:5636
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< X-Evebox-Git-Revision: 8ef8639
< X-Evebox-Session-Id: IUi21/bP7TkbJ11jpYcihe1w/S41vyAbP1L1qBIJKJiL8E3440J3imOSGxKYO9j5ffqAPyv2Q3tCXqUQxhIqnw
< Date: Wed, 05 Jul 2017 06:34:31 GMT
< Content-Length: 14
<
* Connection #0 to host localhost left intact
{"status":200}[root#localhost ~]#
Here is the curl command in PHP:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:5636/api/1/event/AVyWHzgsJ-3JxxYdx60x/archive");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
This is response: 400 Bad Request
Here is the Verbose Output:
Verbose information:
* About to connect() to localhost port 5636 (#6)
* Trying ::1...
* Connected to localhost (::1) port 5636 (#6)
> POST /api/1/event/AVyWHzgsJ-3JxxYdx60x/archive HTTP/1.1
Host: localhost:5636
Accept: */*
Content-Length: -1
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
< HTTP/1.1 400 Bad Request
< Content-Type: text/plain; charset=utf-8
< Connection: close
<
* Closing connection 6
400 Bad Request
Using the Requests library you could convert that cURL query as
include('vendor/rmccue/requests/library/Requests.php');
Requests::register_autoloader();
$headers = array();
$response = Requests::post('http://localhost:5636/api/1/event/AVyWHzgsJ-3JxxYdx60x/archive', $headers);
Use
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
or using urlencode($url);
Add this line, as your API will respond only to POST requests, and 400 error means you are asking API with Non-POST method,
Add this line and it should work ...
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

cURL response body missing (data not shown)

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

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.

Send SOAP request using CURL

I am sending a soap request using PHP curl(). I need to print my request, so that I can have a look into my request and understand weather it is going in a right format.
Here is my code:
$parameters = "<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ejb='http://ejb.gateway.ebpp.fawryis.com/'>
<soapenv:Header/>
<soapenv:Body>
<ejb:process>
//...
</ejb:process>
</soapenv:Body>
</soapenv:Envelope>";
$url='//URL to the service';
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl,CURLOPT_ENCODING,'utf-8');
curl_setopt($curl,CURLOPT_HTTPHEADER,array (
'SOAPAction:""',
'Content-Type: text/xml;
charset=utf-8',
));
curl_setopt ($curl, CURLOPT_POST, 1);
curl_setopt ($curl, CURLOPT_POSTFIELDS, $parameters);
$result = curl_exec($curl);
I get a wrong data sent error from the API side which means I am not sending a correct format.
Can anyone please let me know how to do that?
Update:
Verbose information
* About to connect() to 10.2.250.4 port 9081 (#0)
* Trying 10.2.250.4...
* connected
* Connected to 10.2.250.4 (10.2.250.4) port 9081 (#0)
> POST /CoreWeb/ApplicationBusinessFacadeService HTTP/1.1
Host: 10.2.250.4:9081
Accept: */*
Accept-Encoding: utf-8
SOAPAction:""
Content-Type: text/xml;
charset=utf-8
Content-Length: 1087
Expect: 100-continue
< HTTP/1.1 100 Continue
< Content-Length: 0
< Date: Thu, 20 Mar 2014 14:04:19 GMT
< Server: WebSphere Application Server/7.0
< HTTP/1.1 200 OK
< Date: Thu, 20 Mar 2014 14:04:19 GMT
< Server: WebSphere Application Server/7.0
< Content-Type: text/xml; charset=utf-8
< Content-Language: en-US
< Content-Length: 914
<
* Connection #0 to host 10.2.250.4 left intact
Your Header is broken into two lines:
'Content-Type: text/xml;
charset=utf-8',
Make it in one line. May be it is causing the problem for you.
'Content-Type: text/xml;charset=UTF-8',
UPDATE:
curl_setopt($curl,CURLOPT_HTTPHEADER,array (
'SOAPAction:""',
'Content-Type: text/xml;charset=utf-8',
'Expect:'
));

Categories