php - CURL - Getting HTTP code if/else to test - php
I want to do 404 testing on an API using curl and php
While valid requests to the token generation endpoint (/api/Utilities/StashData) will receive an HTTP 200 response containing a token for use with Leap, invalid requests will receive an HTTP 400 response (Bad Request). If your system receives an HTTP 400 response from the API, it must not attempt to proceed to Leap. The content of this response will contain a JSON-serialized object describing the validation error(s), as per the following example:
[
{
"Key": "CapeConsumers.TrackerNumber",
"Errors": [
{
"ErrorCode": "CC002",
"Description": "The value is required."
}
]
}
]
As you can see, the response contains an array of objects, where each object has a Key property which refers to the key submitted to the service, and an Errors property describing the reason(s) the value was rejected. The ErrorCode values are predefined and guaranteed never to change, the Description is dynamic for certain errors and exists mainly to aid debugging
The codes
CC001
Invalid value.
The value does not conform to one or more validation rules defined for
the key.
CC002
The value is required.
A required value has been omitted from the request. Sending null or a
blank string for a required value will also result in this error
(unless a blank string has been defined as valid by supporting
documentation).
CC003
The value is not of the correct type. Expected {0}, found {1}.
The system expected the value to be of one type, but a different type
was submitted. (e.g. a number was sent instead of a string)
CC004
The origin is not valid for the specified campaign.
Campaigns are linked to specific integrating parties. If an
integrating party uses a tracker number that isn’t assigned to it,
this error will be returned.
CC005
The campaign is not currently active.
The tracker number references a campaign that either hasn’t started or
has already come to an end.
Here is the code I have tried.
$endpointUser = "myuser";
//
$endpointPassword = "mypass";
//
$url = "https://webservices_test.capeconsumers.co.za/api/Utilities/StashData";
$iframeUrl = "https://onlineapplicationtest.capeconsumers.co.za/Bridge/CapeConsumersSACommercial?token=";
$fields = array(
"User.IdentityNumber"=> $_GET['security_phrase'],
"CapeConsumers.TrackerNumber"=> "6E273247DB4840G3",
"Call.AgentReference"=> $_GET['user'] ,
"Call.RecordingReference"=> $_GET['security_phrase']
);
$process = curl_init($url);
curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($process, CURLOPT_HEADER, 0);
curl_setopt($process, CURLOPT_USERPWD, $endpointUser . ":" . $endpointPassword);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
$token = curl_exec($process);
curl_close($process);
$token = str_replace('"','',$token);
$httpCode = curl_getinfo($process, CURLINFO_HTTP_CODE);
if($httpCode == 400) {
echo "there was an error"; exit;
}
?>
<iframe src="<?php echo $iframeUrl . $token; ?>" width="100%" height="800"></iframe>
My problem is that if I deliberately give it a bad response, it will still generate the iframe instead of exiting at the if statement for the 400 error.
I am unsure of my logic as this is my first attempt at curl
You are getting response code too late.
curl_close manual says:
Closes a cURL session and frees all resources. The cURL handle is also deleted.
Order must be:
$httpCode = curl_getinfo($process, CURLINFO_HTTP_CODE);
curl_close($process);
Otherwise there is no CURL handle anymore and therefore you can't retrieve response code.
404 will not be returned by API, it would be thrown if and only if requested url doesn't exist or running. To generate 404 deliberately, pls modify the hostsection of url, so that it refers to wrong location and thus should result 404.
Hope this helps.
Related
php://input empty when sending long JSON via raw POST
I am sending raw JSON POST data with cURL via PHP, and the server receives it correctly when the JSON is not too long. However, it seems to receive an empty body when it's bigger. This is how I get the body from the server: $dataReceived = file_get_contents("php://input"); When I log $dataReceived on the server side, the expected content is in the log when not big, e.g. this: {"products":[],"allProductIds":["898","920","937","947","979","1007","1044","1064","1124","1146","1162","1178","1194","1215","1239","1291","1346","1395","1444","1629","1673","1695","1757","1868","1929","1992","2018","2050","2096","2112","2136","2178","2225","2280","2303","2318","2340","2394","2447","2459","2476","2486","2510","2520","2558","2591","2626","2655","2689","2727","2975","3175","3224","3283","3311","3333","3342","3353","3376","3389","3400","3419","3469","3506","3535","3610","3722","3765","3782","3802","4002","4020","4039","4060","4094","4130","4171","4213","4246","4281","4317","4348","4426","4473","4502","4545","4558","4563","4663","4688","4713","4733","4757","4875","4924","4984","5028","5057","5088","5102","5117","5145","5174","5197","5216","5236","5255","5275","5310","5336","5369","5422","5433","5464","5477","5505","5516","5541","5563","5587","5616","5627","5673","5703","5744","5773","5822","5839","5903","5999","6075","6196","6326","6483","6794","8360","8429","8599","8724","8798","8953","9150","9198","9247","9295","9347","9415","9463","9636","9991","10105","10219","10337","10451","10566","10681","10796","10912","11134","11244","11354","11465","11576","11687","11798","11874","11924","11973","12025","12074","12125","12175","12640","12699","12838","12844","12848","12852","12862","12866","12870","12874","12880","12884","12888","12894","12935","12943","12947","12952","12958","12962","12966","12970","12974","12979","12988","12992","12997","13001","13010","13012","13016","13020","13026","13030","13034","13039","13049","13059","13093","13128","13144","13148","13154","13158","13162","13172","13182","13217","13223","13368","2851","3828","4804"],"brandlyProductIds":["229082","226046","223246","216800","216750","215456","213613","213157","143436","143406","143362","143312","134066","134022","221020","242298","144021","143921","242348","333387","333424","333443","333517","333624","333681","334021","334043","334086","334135","334159","334184","334220","334261","334318","334351","334376","334398","334448","334505","334530","334552","334581","334606","334639","334672","334701","334734","334763","334792","334825","334962","335099","335325","335382","335439","335464","335482","335491","335500","335521","335532","335553","335575","335680","335770","335795","335877","335991","336032","336049","336066","336088","336276","336293","336310","336329","336370","336411","336452","336493","336530","336561","336598","336631","336705","336751","336782","336819","336850","336859","336977","337002","337033","337058","337083","337133","337207","337256","337366","337403","337428","337456","337473","337490","337515","337540","337565","337582","337599","337616","337637","337682","337710","337738","337791","337800","337831","337881","337906","337928","337953","337981","338006","338031","338056","338099","338135","338175","338201","338244","338269","338340","338422","187730","338815","338968","339121","339427","340235","340308","340461","340614","340687","340840","340987","341060","341133","341206","341279","341352","341425","341675","341981","342072","342254","342350","342441","342532","342714","342805","342896","343042","343115","343188","343261","343407","343480","343553","343626","343690","343754","343818","343882","343946","344010","225836","225770","344210","344214","344216","344218","303935","303610","303601","344223","344234","344236","344238","344241","204360","344254","344256","344262","344264","344268","344270","344272","344274","344277","344279","344281","344283","344285","344287","344288","344290","344292","344295","344299","344301","344303","344308","344313","344330","344333","344335","344337","344340","344342","344344","344349","344354","344371","150836","344434"]} But i get an empty $dataReceived for example when the sent JSON is the one in this pastebin https://pastebin.com/p5ZLrxig This is the code i have to send the request, with verbose log protected static function _apiCall(string $url, array $additionalHeaders = [], string $method="GET", string $data=''){ if($method=="POST"){ $curlLog = __DIR__ . '/curl-log.txt'; $f = fopen($curlLog, 'w'); $ch = curl_init($url); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_STDERR, $f); curl_setopt($ch, CURLOPT_STDOUT, $f); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $hdr = [ 'Content-Type: application/json', 'Content-Length: ' . strlen($data) ]; foreach($additionalHeaders as $h) $hdr[] = $h; curl_setopt($ch, CURLOPT_HTTPHEADER, $hdr); curl_setopt($ch, CURLOPT_POSTFIELDS, $data ); $info = curl_getinfo($ch); $result = curl_exec($ch); curl_close($ch); fclose($f); mail("myemail#email.com","$url curl info",print_r($info,true) . ", result:$result, curl log: " . file_get_contents("file://$curlLog") . "\r\n, data:$data"); } else { // ... } } This is the log i get in the email for the big JSON: https://pastebin.com/0pYHTk4h Now, can it be an issue with POST size limit, either in PHP or Apache settings? But i doubt so, since the data is just 33Kb Content-Length: 34581 Also, if it was the case, shouldn't we expect the server (Apache + PHP 7.4.x) to return an HTTP error code like HTTP 500? Instead, we have HTTP 100 and HTTP 200. Seems not related to JSON formatting too, again because we'd expect the server to return an error code. One aspect that may be relevant: the called URL (from which i am logging php://input on server side) actually is a custom Wordpress REST API endpoint (that i have created by calling register_rest_route inside a rest_api_init action handler). I am not currently aware of POST size limits or related issues with WP API, i have no idea if the issue can be with WP. Any hints are appreciated!
How to fetch response from a callback URL using php?
I want to build a WhatsApp bot, for that, we are using Gupshup WhatsApp bot API, for integration they asked to give a callback URL, so created index.php in cPanel of one domain(https://sample_url/WhatsappBot/index.php), and gave the URL (https://sample_url/WhatsappBot/). As per their API documentation, they will pass a response to that URL, so I want to fetch that. Here is the remaining part of API documentation API documentation2, API documentation3, API documentation4. So I created one curl.php named file, that code is given below. <?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://sample_url/WhatsappBot/'); // curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); $headers = array(); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch) ."\n"; } else { $result_value = json_decode($result,true,JSON_PRETTY_PRINT); echo $result_value; // var_dump($result_value); } curl_close($ch); ?> they provided a collection of API for reference, but I am getting the wrong result. In their collection API have the result, Collection API result but I am getting this, myresult What is the wrong in this code? Can anyone please help me...
Your Callback URL should contain a program that receive a POST data as JSON, Go ahead to decode the JSON data, using the data received, proceed with what ever logic you plan to execute. //this should be in your call back URL index.php $post_data_expected = file_get_contents("php://input"); $decoded_data = json_decode($post_data_expected, true); You can your POSTMAN to always test your callback URL to see it behaves the way you expects.
Facebook graph API returns FALSE when using access token
In my application I'm trying to test for expired access tokens. When making a request to https://graph.facebook.com/1234?access_token=xxxxxxxxxx it always returns FALSE What's strange is that when copying the url and using it within a web browser it returns the expected result instead of false. Can't seem to find any documentation within facebook docs as to why it would ever return FALSE and how to resolve it. I have found one other question on stackoverflow which "answers" the question but the answer isn't very clear and I'm unable to comment to enquire about it. Here's the link Facebook Graph API returns false Any suggestions or help would be appreciated. Edit: When making a request to Facebook it's meant to return JSON object. Response code I receive is 0 when making a request to the url https://graph.facebook.com/1234?access_token=xxxxxxxxxx and response body is FALSE as mentiond above. The code I've used is as follows: $url = "https://graph.facebook.com/{user_id}?access_token=xxxxxxxxxx"; $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPGET, TRUE); curl_setopt($curl, CURLOPT_VERBOSE, 1); curl_setopt($curl, CURLOPT_HEADER, 1); $curl_response = curl_exec($curl); $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $header = substr($curl_response, 0, $header_size); $body = substr($curl_response, $header_size); $response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); When running the above code I receive the FALSE response and http code of 0. When I copy and paste the url into any browser what happens is described below: If the access token is valid it returns user data in JSON format. $response_code is 200 and the value of $body is supposed to look as follows: { id: "1234", first_name: "Name", gender: "male", last_name: "Surname", locale: "en_US", middle_name: "Middle Name", name: "Name Middle Name Surname", username: "name.surname" } If the access token is invalid it returns the error in JSON format. $response_code depends on the error but in most cases and in this case its a 403. Example data (value of $body: { error: { message: "Error validating access token: The user has not authorized application xxxxxxxxxxxxxx.", type: "OAuthException", code: 190, error_subcode: 458 } } I know the response code 0 usually means a request was never made or curl isn't supported or something like that however, when I make $url = "http://www.google.co.za"; using the same code I get a response code of 200 and the response body returned is the html code of the website. So I know it works, I've tested it with 3 different urls.
CURL http authentication fails when setting CURL_OPTPOST to true
I'm trying to build a payment form that integrates with Firstdata's api. I need to post an XML string to their server. They also require a client side certificate and http authentication. My CURL set up currently looks like this: function firstdata_send($config_param, $data) { $config_default = array( 'test' => FALSE, ); // settings in $config_param will overwrite settings in $config_default $config = (object)array_merge($config_default, $config_param); if($config->test) { $url = 'https://ws.merchanttest.firstdataglobalgateway.com/fdggwsapi/services/order.wsdl'; } else { $url = 'https://ws.firstdataglobalgateway.com/fdggwsapi/services/order.wsdl'; } $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, "{$config->username}:{$config->password}"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSLCERT, $config->pemfile); curl_setopt($ch, CURLOPT_SSLKEY, $config->keyfile); curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $config->keypass); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, TRUE); curl_setopt($ch, CURLOPT_VERBOSE, TRUE); $result = curl_exec($ch); $result .= curl_error($ch); return $result; } Their server responds with HTTP/1.1 401 Unauthorized. But if I comment out the post options: //curl_setopt($ch, CURLOPT_POST, TRUE); //curl_setopt($ch, CURLOPT_POSTFIELDS, $data); I get HTTP/1.1 200 OK. Unless I'm completely misunderstanding whats going on it seems like using post somehow interferes with the auth headers. I don't know what I'm missing. Solved: Turns out the ssl certificates the test account had generated were bad. I had to call their tech support and they had to regenerate the certs 3 times before the system would accept them. Sorry for wasting your time. I should have called them first. If anybody is interested the tech support number I called was (888) 477-3611. I think NomikOS was closest to being correct so I'll mark his as the answer and up vote the rest of you. Thanks again.
Form what i see you need a certificate in pem format to use this service .... A. Download the API https://www.firstdata.com/downloads/customerservice/30006_api_php.zip B. You would see so many examples Example Sales Info include"lphp.php"; $mylphp=new lphp; $myorder["host"] = "secure.linkpt.net"; $myorder["port"] = "1129"; $myorder["keyfile"] = "./YOURCERT.pem"; # Change this to the name and location of your certificate file $myorder["configfile"] = "1234567"; # Change this to your store number $myorder["ordertype"] = "SALE"; $myorder["result"] = "LIVE"; # For a test, set result to GOOD, DECLINE, or DUPLICATE $myorder["cardnumber"] = "4111-1111-1111-1111"; $myorder["cardexpmonth"] = "01"; $myorder["cardexpyear"] = "05"; $myorder["chargetotal"] = "9.99"; $myorder["addrnum"] = "123"; # Required for AVS. If not provided, transactions will downgrade. $myorder["zip"] = "12345"; # Required for AVS. If not provided, transactions will downgrade. // $myorder["debugging"] = "true"; # for development only - not intended for production use # Send transaction. Use one of two possible methods # // $result = $mylphp->process($myorder); # use shared library model $result = $mylphp->curl_process($myorder); # use curl methods if ($result["r_approved"] != "APPROVED") // transaction failed, print the reason { print "Status: $result[r_approved]\n"; print "Error: $result[r_error]\n"; } else { // success print "Status: $result[r_approved]\n"; print "Code: $result[r_code]\n"; print "OID: $result[r_ordernum]\n\n"; }
Check you access credentials (username, password) 401 Unauthorized The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43]. source: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 == OBS: I recommend you this code to check for errors // check for errors before close $result = curl_exec($ch); if ($result === false) { echo curl_error($ch); } curl_close($ch);
Just checked First Datas API is a SOAP based API... The url to the wsdl only accepts GET because the wsdl is just the xml instruction set for sending soap calls. PHP soapclient class
PHP return value from decoded object
Can someone please tell me where is the error in this code?, I use a mobile iphone application to call a php script tha will send information to apple. Apple then will return a JSON object containing several values in an associative array. I want to reach the 'status' value but every time I run the code in the phone, the php script sends me the complete apple's returned string. In the XCode debugger the received string looks like: [DEBUG]... responseString : {"receipt":{"item_id":"328348691", "original_transaction_id":"1000000000081203", "bvrs":"1.0", "product_id":"julia_01", "purchase_date":"2009-10-05 23:47:00 Etc/GMT", "quantity":"1", "bid":"com.latin3g.chicasexy1", "original_purchase_date":"2009-10-05 23:47:00 Etc/GMT", "transaction_id":"1000000000081203"}, "status":0} but the only piece I care in the string is the "status" value. I've already looked inside documentation but can't find the solution. I'm new in php but this getting too long. Here the script: <?php //The script takes arguments from phone's GET call $receipt = json_encode(array("receipt-data" => $_GET["receipt"])); //Apple's url $url = "https://sandbox.itunes.apple.com/verifyReceipt"; //USe cURL to create a post request //initialize cURL $ch = curl_init(); // set the target url curl_setopt($ch, CURLOPT_URL,$url); // howmany parameter to post curl_setopt($ch, CURLOPT_POST, 1); // the receipt as parameter curl_setopt($ch, CURLOPT_POSTFIELDS,$receipt); $result = curl_exec ($ch); //Here the code "breaks" and return the complete string (i've tested that) //and apparently doesn't get to the json_decode function (i think something's wrong there, so code breaks here) curl_close ($ch); $response = json_decode($result); echo $response->{'status'}; ?> Even if I don't put any echo at the end, the script still returns a complete string (odd to me) Thank's in advance and apollogies if I insist again from another question
Try setting the RETURNTRANSFER option to 1 so you can capture the output from the requested URL as a string. It seems that the default behaviour of cURL is to output the result directly to the browser: ... $ch = curl_init(); // set the target url curl_setopt($ch, CURLOPT_URL,$url); // howmany parameter to post curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // <---- Add this // the receipt as parameter curl_setopt($ch, CURLOPT_POSTFIELDS,$receipt); ...