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");
Related
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
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 make a curl request to the address https://trimet.ru/contacts/ and get:
301 Moved Permanently Location: http://trimet.ru/contacts
I change url to http://trimet.ru/contacts and get:
302 Found
When I try to add curl params:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_MAXREDIRS,100);
curl_setopt($ch, CURLOPT_AUTOREFERER,1);
I get empty result. (safe_mode = off, open_basedir none).
my source code:
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,10);
curl_setopt($ch, CURLOPT_TIMEOUT,60);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1');
curl_setopt($ch, CURLOPT_VERBOSE,2);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_MAXREDIRS,100);
curl_setopt($ch, CURLOPT_AUTOREFERER,1);
$result = curl_exec($ch);
curl debug:
* About to connect() to trimet.ru port 80 (#0)
* Trying 2a03:6f00:1::5c35:6090... * connected
* Connected to trimet.ru (2a03:6f00:1::5c35:6090) port 80 (#0)
> GET /contacts HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Ubuntu/9.04 (jaunty) Shiretoko/3.5.1
Host: trimet.ru
Accept: */*
< HTTP/1.1 302 Moved Temporarily
< Server: nginx/1.6.3
< Date: Wed, 23 Dec 2015 20:09:32 GMT
< Content-Type: text/html
< Content-Length: 160
< Connection: keep-alive
< Location: https://trimet.ru/contacts
<
* Ignoring the response-body
* Connection #0 to host trimet.ru left intact
* Issue another request to this URL: 'https://trimet.ru/contacts'
* About to connect() to trimet.ru port 443 (#1)
* Trying 2a03:6f00:1::5c35:6090... * connected
* Connected to trimet.ru (2a03:6f00:1::5c35:6090) port 443 (#1)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using AES128-SHA
* Server certificate:
* subject: C=RU; ST=Saint-Petersburg; L=Saint Petersburg; O=TimeWeb Company Limited; CN=*.timeweb.ru
* start date: 2014-11-28 00:00:00 GMT
* expire date: 2016-01-27 23:59:59 GMT
* issuer: C=US; O=thawte, Inc.; CN=thawte SSL CA - G2
* SSL certificate verify ok.
> GET /contacts HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Ubuntu/9.04 (jaunty) Shiretoko/3.5.1
Host: trimet.ru
Accept: */*
Referer: http://trimet.ru/contacts
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.6.3
< Date: Wed, 23 Dec 2015 20:09:32 GMT
< Content-Type: text/html
< Content-Length: 184
< Connection: keep-alive
< Location: http://trimet.ru/contacts
<
* Ignoring the response-body
* Connection #1 to host trimet.ru left intact
* Issue another request to this URL: 'http://trimet.ru/contacts'
* Re-using existing connection! (#0) with host trimet.ru
* Connected to trimet.ru (2a03:6f00:1::5c35:6090) port 80 (#0)
> GET /contacts HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Ubuntu/9.04 (jaunty) Shiretoko/3.5.1
Host: trimet.ru
Accept: */*
Referer: https://trimet.ru/contacts
< HTTP/1.1 302 Moved Temporarily
< Server: nginx/1.6.3
< Date: Wed, 23 Dec 2015 20:09:32 GMT
< Content-Type: text/html
< Content-Length: 160
< Connection: keep-alive
< Location: https://trimet.ru/contacts
<
* Ignoring the response-body
* Connection #0 to host trimet.ru left intact
* Issue another request to this URL: 'https://trimet.ru/contacts'
* Re-using existing connection! (#1) with host trimet.ru
* Connected to trimet.ru (2a03:6f00:1::5c35:6090) port 443 (#1)
> GET /contacts HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Ubuntu/9.04 (jaunty) Shiretoko/3.5.1
Host: trimet.ru
Accept: */*
Referer: http://trimet.ru/contacts
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.6.3
< Date: Wed, 23 Dec 2015 20:09:33 GMT
< Content-Type: text/html
< Content-Length: 184
< Connection: keep-alive
< Location: http://trimet.ru/contacts
<
* Ignoring the response-body
* Connection #1 to host trimet.ru left intact
* Issue another request to this URL: 'http://trimet.ru/contacts'
* Re-using existing connection! (#0) with host trimet.ru
* Connected to trimet.ru (2a03:6f00:1::5c35:6090) port 80 (#0)
> GET /contacts HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Ubuntu/9.04 (jaunty) Shiretoko/3.5.1
Host: trimet.ru
Accept: */*
Referer: https://trimet.ru/contacts
< HTTP/1.1 302 Moved Temporarily
I'm trying to upload a file via cURL but something is missing. I forces this request to be HTTP 1.0 because cURL adds the Expect: 100 header if I use HTTP 1.1 so thats why the extra header. Here is a simple test code:
<?php
if(isset($_POST["id"])) {
$data = array("id" => $_POST["id"]);
$data["file"] = "#".realpath($_FILES["file"]["tmp_name"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453',
'Connection: keep-alive'
));
curl_setopt($ch, CURLOPT_URL, "http://localhost:8080/test-api/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
$response = curl_exec($ch);
var_dump($response);
exit;
}
?>
My Jersey based server picks it up, and I can see these headers:
INFO: 25 * Server has received a request on thread http-nio-8080-exec-1
25 > POST http://localhost:8080/test-api/upload
25 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
25 > connection: keep-alive
25 > content-length: 261
25 > content-type: multipart/form-data; boundary=------------------------53f7ba34739b4d9e
25 > host: localhost:8080
See the content-length? It's way too short. When I send the same file and the same request via my Postman REST client, I get these headers:
INFO: 26 * Server has received a request on thread http-nio-8080-exec-3
26 > POST http://localhost:8080/test-api/upload
26 > accept-encoding: gzip, deflate
26 > accept-language: hu-HU,hu;q=0.8,en-US;q=0.6,en;q=0.4
26 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
26 > cache-control: no-cache, no-cache
26 > connection: keep-alive
26 > content-length: 144954
26 > content-type: multipart/form-data; boundary=----WebKitFormBoundarye5Tg0kEqi10nEBwv
26 > cookie: ff_uvid=126143952; _ga=GA1.1.459454356.1439469592; CAKEPHP=9mffidqo8203ugktan4roc0u82
26 > host: localhost:8080
26 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
26 > user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36
The content-length now is set property. What could be wrong here?
It sounds like you're using PHP 5.6.0 or later. As of this release, the # prefix for file uploads is disabled by default. You can enable it with
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
This option was added in 5.5, but the default was false for backward compatibility; 5.6 changed the default incompatibly.
The preferred way to perform file uploads starting with 5.5 is with the CurlFile class.
$data["file"] = new CurlFile(realpath($_FILES["file"]["tmp_name"]));
You have to actually insert the filecontent, this differs from the cli-version of curl.
try:
$data["file"] = file_get_contents($_FILES["file"]["tmp_name"]);
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