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"));
//...
?>
Related
I'm trying to access this website natura.com.br to get info about some products, I'm trying to make a request the same way I do in the browser but I receive Access denied.
<?php
$url = "https://www.natura.com.br/";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:89.0) Gecko/20100101 Firefox/89.0",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3",
"Connection: keep-alive",
"Cookie: dtPC=11$302937546_809h-vKVNUNMUJAHDKTQPPAHFQIMSCQPPRKILC-0e0; rxvt=1625712010903|1625710210903; _abck=141C18ABCC9C79DFA1F4D45EF108501A~-1~YAAQk9j2SGYWZX56AQAAtC1zgwbF2BpCRBBWxNKDpMPWjPEYtw7XLvfB2g+dxkZSpfXBRCTvbE4fZTzGxjqtGVa7tZqz9pWp/hYSf65phFg2VW06IioCwpy7tox8su7QlWIt3eZUeTFIJ5S7nRtSv3Te859lzghM7a2lLnZOjpjS5eYLrJzYzyKFsRdc8Kpgj+sGCZA9iKiMvfqtJlI5e+90UfUDDzTQB2sV2U5i2yavjB+GsgBZ1qcKIfmo41PYfXtS8efG+3C4F4cw3sePIjj4vQIex1pQdg3twIbyqAMsEClNaqbGJ29NVu/orK7dAJ7rteSqWvyMuMu9MCltlPoYaYYi/O0Uzv18AiK9hSMYYWod7U/IqUkfE/touhQz6OT0S2KPjG0wJVJ8dghA8LdDJFH4+Y3YX4+oDw==~0~-1~-1; dtCookie=v_4_srv_11_sn_44IDRCETVPHGS7OCQ5F7DV8IS6T6HDI3_perc_100000_ol_0_mul_1_app-3A2a1999229615da92_1_app-3A58ea22250e34b990_1_rcs-3Acss_0; rxVisitor=1625332161003TGNBC4CH08VFEACK6NT19CQ14GERSQEA; dtSa=-; dtLatC=6; RT="z=1&dm=www.natura.com.br&si=a6979d10-a558-4bb3-a962-ccb19999271b&ss=kqu5jycl&sl=0&tt=0"; JSESSIONID=IUGNrH_B8h7DHZlVAsWr38FYiZq_I13dabE1sdnURzTRvdlsps50!-405357702; verifyFirstRequest=true; ORDER_ID=%3B%20; ORDER_NUMBER=%3B%20; X-Oracle-BMC-LBS-Route=93a9c3aed1d29d32ea0391633407edd696daed8327da03a11a2ff120e313e9b656c62fd8a7c42ae86da5fb4c73ec2333f092dbf8c9611add8055dec1; undefined; GTMUtmTimestamp=1625702943894; GTMCampaignReferrer=https%3A%2F%2Fwww.google.com%2F; GTMCampaignLP=https%3A%2F%2Fwww.natura.com.br%2Fp%2Fdesodorante-Col%25C3%25B4nia-kaiak-urbe-masculino-100ml%2F34075%3Futm_content%3DSP_Resp_MCKaiak_2020_Kaiak_Urbe%26cnddefault%3Dtrue%26gclid%3DEAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; _gcl_au=1.1.467484977.1625332166; _ga_15QCH7XEDY=GS1.1.1625874531.3.0.1625874531.60; _ga=GA1.3.1744316957.1625332166; GTMBrowserSessionEntranceTimestamp=1625332166546; GTMBrowserSessionEntranceLP=https%3A%2F%2Fwww.natura.com.br%2Facesso-consultor; GTMBrowserSessionEntranceReferrer=https%3A%2F%2Fwww.google.com%2F; GTMLastEntranceTimestamp=1625702945066; GTMLastEntranceLP=https%3A%2F%2Fwww.natura.com.br%2Fp%2Fdesodorante-Col%25C3%25B4nia-kaiak-urbe-masculino-100ml%2F34075%3Futm_content%3DSP_Resp_MCKaiak_2020_Kaiak_Urbe%26cnddefault%3Dtrue%26gclid%3DEAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; GTMLastEntranceReferrer=https%3A%2F%2Fwww.google.com%2F; _fbp=fb.2.1625332167173.86579534; GTMUtmSource=google; GTMUtmMedium=cpc; GTMUtmCampaign=auto; GTMGclid=EAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; _gcl_aw=GCL.1625702944.EAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; _ttgclid=EAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; _ttgclid=EAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; __bid=4dbbd24a-fc0e-42aa-a664-43c865cae2ef; _gac_UA-35236522-3=1.1625703004.EAIaIQobChMIxrmerJfS8QIV7R-tBh01uwM5EAAYASAAEgIZU_D_BwE; cto_bundle=qVL1jF8yb3h2cW01cmFaUjF5S2VnMkdGcDEyNHdrWWM3ZXpZcFFIMkowdmZqOFZpNTE3VGIlMkJibkZZZXpMJTJGYXBqRElFT0FwdFRia3ZwQ1JZSzZ2ZEx1RSUyQnBXUW54MmM1S3UlMkY3WjlqenBXU1dDZFlRaTYlMkZucVdPM2c5MTJUcERYc2pLcEdyeURWQU9ieDhmaTR1WGJoN1FhaHR4Nm5MZWdJUUNmZUI0MkdNYk50VXpFRGg0Z2hUSlNxS25xZGFNVjJZTGpC; GTMVisitSession=1625702947208; GTMVisitPermanent=1625702947208; _uetvid=b67fe410df8011eb85947b37dce069f8; smeventsclear_d13b2682b72e42cc9203ee1f0a20b68d=true; personNumber=141692103; smCloseBounce=true",
"Upgrade-Insecure-Requests: 1",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
var_dump($resp);
?>
I get this HEADER when I do the request
"HTTP/1.1 403 Forbidden Server: AkamaiGHost Mime-Version: 1.0 Content-Type: text/html Content-Length: 271 Cache-Control: max-age=1800 Expires: Sat, 10 Jul 2021 21:35:46 GMT Date: Sat, 10 Jul 2021 21:05:46 GMT Connection: close Server-Timing: cdn-cache; desc=HIT Server-Timing: edge; dur=1 Timing-Allow-Origin: true Access-Control-Max-Age: 86400 Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: * Access-Control-Allow-Methods: GET,POST,OPTIONS Access-Control-Allow-Origin: *
First of all, within "" PHP tries to convert variables to strings. So
$foo = "Hello, ";
echo "$foo World" . PHP_EOL;
would output
Hello, World
You are using "" and have the $-sign in your cookie (not to mention the fact that the cookie-string itself contains the "-sign). So PHP is not sending that "as-is" in the cookie but instead trying to find that variable and turn it into a string. If you don't want this behavior use single quotes ' instead.
So that could be your issue as long as the information in the cookie is valid and should allow you access.
Besides this it is hard to know what happens in the backend of natura.com.br to block your access. It could be any number of things. Do you need to login, do you have a valid session etc.
Instead of working with curl directly you could use Guzzle which is a great PHP based HTTP-Client that simplifies a lot of stuff. It can keep track of cookies and append them automatically etc.
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"
));
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");
I would like to perform a PUT operation on a webservice using CURL. Let's assume that:
webservice url: http://stageapi.myprepaid.co.za/api/ConsumerRegisterRequest/cac52674-1711-e311-b4a8-00155d4905d3
municipality= NMBM
sgc= 12345
I've written the code below, but it outputs this error message: "ExceptionMessage":"Object reference not set to an instance of an object.". Any help would be so much appreciated. Thanks!
<?php
function sendJSONRequest($url, $data)
{
$data_string = json_encode($data);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Accept: application/json',
'X-MP-Version: 10072013')
);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
ob_start();
$result = curl_exec($ch);
$info = curl_getinfo($ch);
if ($result === false || $info['http_code'] == 400) {
return $result;
} else {
return $result;
}
ob_end_clean();
curl_close($ch);
}
$mun = $_GET['municipality'];
$sgc = $_GET['sgc'];
$req = $_GET['req']; //cac52674-1711-e311-b4a8-00155d4905d3
//myPrepaid PUT URL
echo $mpurl = "http://stageapi.myprepaid.co.za/api/ConsumerRegisterRequest/$req";
// Set Variables
$data = array("Municipality" => "$mun", "SGC" => "$sgc");
//Get Response
echo $response = sendJSONRequest($mpurl, $data);
?>
I copied your code, but changed it so it pointed at a very basic HTTP server on my localhost. Your code is working correctly, and making the following request:
PUT /api/ConsumerRegisterRequest/cac52674-1711-e311-b4a8-00155d4905d3 HTTP/1.1
Host: localhost:9420
Content-Type: application/json
Accept: application/json
X-MP-Version: 10072013
Content-Length: 37
{"Municipality":"NMBM","SGC":"12345"}
The error message you're receiving is coming from the stageapi.myprepaid.co.za server. This is the full response when I point it back to them:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 30 Aug 2013 04:30:41 GMT
Connection: close
Content-Length: 867
{"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","StackTrace":" at MyPrepaidApi.Controllers.ConsumerRegisterRequestController.Put(CrmRegisterRequest value) in c:\\Workspace\\MyPrepaid\\Prepaid Vending System\\PrepaidCloud\\WebApi\\Controllers\\ConsumerRegisterRequestController.cs:line 190\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)"}
You may want to check out the API to make sure you're passing them the correct information. If you are, the problem could be on their end.
And while I realize this isn't part of your question and this is in development, please remember to sanitize any data from $_GET. :)
Try with:
curl_setopt($ch, CURLOPT_PUT, true);