I'm trying to set up an API call through php using cURL. The API documentation gives an example for a call to this API from Java:
HttpResponse<JsonNode> response = Unirest.get("https://api2445582011268.apicast.io/games/1942?fields=*")
.header("user-key", "*******")
.header("Accept", "application/json")
.asJson();
This is my attempt at converting it to a cURL call in php:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api2445582011268.apicast.io/games/1942?fields=*");
curl_setopt($ch, CURLOPT_HEADER, array(
"user-key: *******",
"Accept: application/json"
));
$output = curl_exec($ch);
echo $output;
curl_close($ch);
However my php is echoing the following output:
HTTP/1.1 403 Forbidden Content-Type: text/plain; charset=us-ascii Date: Sat, 02 Sep 2017 02:52:40 GMT Server: openresty/1.9.15.1 Content-Length: 33 Connection: keep-alive Authentication parameters missing1
Does anyone know how to solve this?
You used CURLOPT_HEADER (which is a Boolean to indicate you want the headers in the output), but you need CURLOPT_HTTPHEADER (which is used to pass an array with the headers for the request):
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"user-key: *******",
"Accept: application/json"
));
Related
In curl default content type not changing 'application/json' in output.
$headers = array();
$headers[] = 'Accept: application/xml';
$headers[] = 'Content-Type: application/xml';
$url = url('someurl here');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response=curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
Output:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Request-Time: 295
Date: Wed, 28 Jun 2017 07:41:58 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Connection: Transfer-Encoding
am i done any mistake in that above code? I need output in xml format only.
There is no mistake. Content-type header that you setted is a request header. It defines type of content that you're sending to a server. Which make no sense in GET requests type.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
Is a response headers. Content type here shows format of the server response.
Maybe you didn't pass some parameter that tells server to return xml data instead of json.
I've been scouring around trying to understand curl and building headers but it seems no matter what I do I get the following error :
HTTP/1.1 400 Bad Request Date: Tue, 12 Apr 2016 18:15:33 GMT Server: Apache/2.2.29 (Unix) mod_wsgi/3.5 Python/2.7.10 PHP/5.6.10 mod_ssl/2.2.29 OpenSSL/0.9.8zh DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.22.0 Content-Length: 226 Connection: close Content-Type: text/html; charset=iso-8859-1
Bad Request
Your browser sent a request that this server could not understand.
The following is the function that I am using to send post variables and fetch the contents via curl. Both the file doing the fetching and the file whose contents are fetched are being hosted locally on MAMP
$url = "./lib/otherpage.php";
$data = array("url"=>$_POST["url"],"format"=>"json");
function tryCurl($baseurl,$data)
{
$bodydata = array(json_encode($data));
$bodystr = http_build_query($bodydata);
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$baseurl);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$bodystr);
curl_setopt($ch, CURLOPT_PORT,8888);
curl_setopt($ch, CURLOPT_HEADER,1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array(
"POST / HTTP/1.0",
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: ".strlen($bodystr),
"Host: localhost:8888/gt_dev/",
"User-Agent: My-User-Agent 1.0",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Cache-Control: no-cache",
"Accept-Language: en;q=0.7,en-us;q=0.3",
"Connection: close",
));
// Execute
$result=curl_exec($ch);
// Printing any errors..
echo curl_error($ch);
curl_close($ch);
return $result;
}
Ultimately, the request should send two post variables ("url" and "format") to the receiving file, and expect a json string in return.
This isn't so much an answer to the original issue but turns out I was thinking about my problem the wrong way.
I wanted to use page A as a proxy to page B. And to pass the same variables page B expected from Page A.
Turns out the same effect can be achieved by simply including page B, not curling the expected parameters to it. So the answer is just
include("./lib/otherpage.php");
My goal is to send a POST request to a server and get the proper response.
Note: Angled brackets represent placeholders.
In Terminal, using the following code will provide me the desired response.
curl -u <user>:<pass> -H 'Content-Type: application/xml' -X POST https://<rest of url>
My current PHP looks something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); //$uri is the same that I use in terminal
curl_setopt($ch, CURLOPT_USERPWD,
sprintf('%s:%s', $user, $pass)); //same as terminal user & pass
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$headers = array(
'Content-Type: application/xml', //expect an xml response
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$curl_result = curl_exec($ch);
Using this PHP, I get a 400 Bad Request error.
The verbose information:
> POST <same url> HTTP/1.1
Authorization: Basic YWRtaW5Ac3Bhcms0NTEuY29tOnNwYXJrc29tZXRoaW5n
Host: <correct host>
Accept: */*
Content-Type: application/xml
Content-Length: -1
Expect: 100-continue
* HTTP 1.0, assume close after body
< HTTP/1.0 400 Bad request
< Cache-Control: no-cache
< Connection: close
< Content-Type: text/html
Why am I getting a 400 Bad Request error when I use PHP, but not when I use command line? How can I fix this issue so that I get my desired response using PHP?
curl_setopt($ch, CURLOPT_POSTFIELDS, array());
After adding this line, I resolved my problem. In a way, this solution makes sense; but I don't understand why CURLOPT_POSTFIELDS is required. In the PHP documentation, this part should be included under CURLOPT_POST, unless this just accidentally works.
I don't know if this can help you, but for me the Expect: 100-continue looks strange. Take a look at this comment:
http://php.net/manual/en/function.curl-setopt.php#82418
So maybe you can fix it like in the example:
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
?>
I am trying to execute a curl command that I can execute successfully in the terminal but it fails in PHP script with the following error:
HTTP/1.1 401 Unauthorized Access-Control-Allow-Origin: * Access-Control-Request-Method: * Cache-Control: no-cache Content-Type: application/json; charset=utf-8 Date: Mon, 06 Feb 2012 00:38:56 GMT Server: nginx/1.0.4 Set-Cookie: _parse_session=XXXXXX; domain=.parse.com; path=/; expires=Sun, 06-Feb-2022 00:38:56 GMT; HttpOnly Status: 401 Unauthorized WWW-Authenticate: Basic realm="Parse" X-Runtime: 0.002486 X-UA-Compatible: IE=Edge,chrome=1 Content-Length: 24 Connection: keep-alive {"error":"unauthorized"}
This is the command executed in terminal that executes successfully:
curl -H "Accept: application/json" -H "X-Parse-Application-Id: XXXXXXX" -H "X-Parse-REST-API-Key: XXXXXXXXX" -X GET "https://api.parse.com/1/classes/XXXXXX"
This is the PHP code:
$fields = array('Accept: '=>'application/json',
'X-Parse-Application-Id:' => 'XXXXX',
'X-Parse-REST-API-Key:' => 'XXXXX');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.parse.com/1/classes/XXXX');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_HEADER, $fields);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt(CURLOPT_USERPWD, 'XXXXXX');
$result = curl_exec($ch);
curl_close($ch);
The interesting note is that when executed in the terminal authentication info is not required.
Help will be appreciated.
Thanks
Your header fields shouldn't have the : in the array defnition:
'X-Parse-REST-API-Key:' => 'XXXXX');
^---remove these
That makes the : part of the field name, so you're actually sending:
X-Parse-REST-API-Key:: XXXXX
^^---note the doubled colons
Your header is set using CURLOPT_HTTPHEADER, not CURLOPT_HEADER which expects a boolean value
I am not that experienced with cURL and I have spent a couple of days trying to sort this problem: I have an issue with cURL not appending the query string to my URL in the headers when I submit a POST request; hence no 'payload' is received by the server and I get returned an error status code by the service I'm accessing which indicated it didn't receive the appropriate data.
I think the POST should start with the full domain name, but I'm not sure. If I'm posting data, shouldn't Content-Length be '0' instead of what I am getting?
The outgoing header looks like this:
POST /rest/v1/oliver/groups/ORIGINNUMBER/member? HTTP/1.1
Accept: application/xml
Content-type: text/plain
User-Agent: Custom PHP Script
Host: campaign.oventus.com
Cookie: JSESSIONID=SECRETCOOKIE
Content-Length: 95
My php code looks like this:
$fields_string = "firstName=$fname&secondName=$sname&password=$pass&deviceAddress=$phonenumber¬es=testing";
$url = "http://campaign.oventus.com/rest/v1/ACCOUNTNAME/groups/ORIGINNUMBER/member?";
$header[] = "Accept: application/xml";
$header[] = "Content-type: text/plain";
$header[] = "User-Agent: Custom PHP Script";
$header[] = "Host: campaign.oventus.com";
$header[] = "Cookie: ".$cookie;
$cx = curl_init();
curl_setopt($cx, CURLOPT_URL,$url);
curl_setopt($cx, CURLOPT_POST, 5);
curl_setopt($cx, CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($cx, CURLOPT_HTTPHEADER, $header);
curl_setopt($cx, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($cx, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($cx, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cx, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($cx, CURLOPT_TIMEOUT, 15);
curl_setopt($cx, CURLOPT_HEADER, 1);
curl_setopt($cx, CURLINFO_HEADER_OUT, TRUE);
$final = curl_exec($cx);
$errors = curl_error($cx);
$errornos = curl_errno($cx);
$headcut2 = explode ("n/xml", $final);
$headstring2 = $headcut2[0]."n/xml";
$xmlstring2 = $headcut2[1];
echo "<h2>Add to Group result: </h2>";
echo "<p>RAW header: <code>$final</code></p>";
//echo "<p>Response header: <code>".htmlentities($headstring2)."</code></p>";
echo "<p>XML response: <code>".htmlentities($xmlstring2)."</code></p>";
//echo "<p>".print_r($info)."</p>";
//echo "<p>CURL info: $info</p>";
//echo "<p>Curl error: $errors</p>";
echo "<p>Curl error num: $errornos</p>";
print "<pre>\n";
print_r(curl_getinfo($cx)); // get error info
print "</pre>\n";
curl_close($cx);
And the header returned by the server is this:
HTTP/1.1 200 OK Date: Fri, 26 Aug 2011 17:30:12 GMT
Server: Apache/2.2.17 (Unix) DAV/2 Content-Length: 144
X-Powered-By: Servlet/2.5 JSP/2.1 Cache-Control: no-store, no-cache
Vary: Accept-Encoding,User-Agent Pragma: no-cache
Content-Type: application/xml 202
With the returned XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<status xmlns="http://jaxb.rest.pageone.com" description="No Devices to add">202</status>
As far as I can tell, I'm definitely hitting the server, but it doesn't seem to receive the data I'm sending it..
Stumped. Hope someone can point me in the right direction!
Cheers,
Looks like your hitting the server, and likely the data is going to... I think the answer lies in 202:No Devices to add... which the REST interface documentation should explain (perhaps you're missing a required field?) {202 FYI means accepted but no processing was completed, could also mean the user exists}
By the way you should be escaping those arguments you're putting into the POST payload ($fname,$sname,$pass,$phonenumber)... otherwise a weird value (say name) could cause the post to act completely differently to the way you expected. You can do that using urlencode, or by instead building the POST string with http_build_query
<?php
$fields_string=http_build_query(array(
"firstName"=>$fname,
"secondName"=>$sname,
"password"=>$pass,
"deviceAddress"=>$phonenumber,
"notes"=>"testing"));
//...
?>