How does Laravel know Request::wantsJson is a request for JSON? - php

I noticed that Laravel has a neat method Request::wantsJson - I assume when I make the request I can pass information to request a JSON response, but how do I do this, and what criteria does Laravel use to detect whether a request asks for JSON ?

It uses the Accept header sent by the client to determine if it wants a JSON response.
Let's look at the code :
public function wantsJson() {
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && $acceptable[0] == 'application/json';
}
So if the client sends a request with the first acceptable content type to application/json then the method will return true.
As for how to request JSON, you should set the Accept header accordingly, it depends on what library you use to query your route, here are some examples with libraries I know :
Guzzle (PHP):
GuzzleHttp\get("http://laravel/route", ["headers" => ["Accept" => "application/json"]]);
cURL (PHP) :
$curl = curl_init();
curl_setopt_array($curl, [CURLOPT_URL => "http://laravel/route", CURLOPT_HTTPHEADER => ["Accept" => "application/json"], CURLOPT_RETURNTRANSFER => true]);
curl_exec($curl);
Requests (Python) :
requests.get("http://laravel/route", headers={"Accept":"application/json"})

Related

No callback from API after php cURL request

My code makes a curl request to an API that converts image formats e.g. png to jpg.
The API documentation offers a callback from the API which, when the conversion is finished, will send a GET request to a url on my server (hosted, not localhost). I provide this url to the API with the key/value pair:
"callback" => "12coins.net/cc_callback.php"
Unfortunately the API never calls back. Are my curl_setopt parameters wrong or what could be the problem?
$ch_start_process = curl_init();
$start_process_data = array(
"callback" => "https://12coins.com/cc_callback.php",
"input" => "download",
"file" => "https://12coins.com/photo_file.png",//the image I want converted
"tag" => "tag - unused for now",
"outputformat" => "jpg");
$process_url = "https:".$url_from_create;//prepend https to construct a valid endpoint.
//$url_from_create is a url returned by the API to a request immediately prior to this one
curl_setopt($ch_start_process, CURLOPT_URL, $process_url);
curl_setopt($ch_start_process, CURLOPT_POSTFIELDS, http_build_query ($start_process_data));
curl_setopt($ch_start_process, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_start_process, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
$start_response=curl_exec($ch_start_process);//assign return value of curl_exec()
This is the script on my (remote) server 12coins.net/cc_callback.php to which the API should call back but doesn't:
<?php
header('Access-Control-Allow-Origin: *');
echo 'cc_callback has been called';
echo 'The GET request from CloudConvert is: '. $_GET;
?>
The API does in fact make a call back. It was just that with the code as shown in cc_callback.php there was no way for me to detect the callback. I had assumed that the echo statements would allow me to see the API's response in the (Chrome) network tab of my brower's dev tools. But of course the echo statements echo to the client that 'called' it with a GET request. In this case, that client is the API and not my browser/html page.
Realising this, I was then easily able to check that it had worked all along by adding
mail(myemailaddress#gmail.com, 'This is the url returned to the callback',$GET[url]); to my php script (shown in the question). This sent me an email when I sent an image to the API for processing and thus confirmed that the API was making the call back..
The curl code in the question is good. It makes a successful request to the API.
Lastly, the curl code is for a request to the CloudConvert API, version 1. There is a version 2 but the code above is not good for that. Also, there's an earlier curl request which must be used in conjunction with the one above which I'll post later for the sake of completeness.

How to send raw data with curl GET in PHP?

I am developing REST API and while it is easy to set raw JSON data for request in cURL for POST
$payload = json_encode(array("user" => $data));
//attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
I cannot figure out how to send such data with GET requests.
Is there something like CURLOPT_GETFIELDS or CURLOPT_RAWDATA? The purpose of sending JSON with GET request is to pass in some params.
I do not wish to add formdata to the request, I wish to post JSON so that it can be parsed on the receiver.
Thanks!
EDIT:
based on comments I want to avoid confusion, so the resulting request should look like:
GET / HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/json
Accept: application/json
Host: 127.0.0.1:3000
content-length: 13
Connection: keep-alive
cache-control: no-cache
{
"a": "b"
}
as you can see, GET request here has data and it is parsed and works perfectly by web server. How do I achieve this with cURL?
GET requests do not have a body, that's the whole idea: you're just getting something from the server, as opposed to posting something to it. From RFC 7231:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
In other words, a GET request can have data, but it should not. From earlier in the spec, where GET is defined as a safe method:
Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource.
...
Of the request methods defined by this specification, the GET, HEAD,
OPTIONS, and TRACE methods are defined to be safe.
If you really want to have JSON in your GET request (and send it to a reasonably implemented server resource) the only place it can go is in the URI as part of the query string. For GET requests I find using file_get_contents to be much easier than dealing with cURL.
<?php
$payload = json_encode(["user" => $data]);
$url_data = http_build_query([
"json" => $payload
]);
$url = "https://some.example/endpoint.php?" . $url_data;
$result = file_get_contents($url);
If you want to send it to an unreasonably implemented server resource, and violate the spirit of the HTTP RFCs, you could do this:
<?php
$url = "https://some.example/endpoint.php";
$payload = json_encode(["user" => $data]);
$ctx = stream_context_create(["http" => [
"header"=>"Content-Type: application/json",
"content"=>$payload
]]);
$result = file_get_contents($url, false, $ctx);
If you're determined to do this specifically with cURL, you might have luck with the CURLOPT_CUSTOMREQUEST option set to "GET" and CURLOPT_POSTDATA with your data.

DELETE request with parameters using Guzzle

I have to do a DELETE request, with parameters, in the CodeIgnitor platform. First, I tried using cURL, but I switched to Guzzle.
An example of the request in the console is:
curl -X DELETE -d '{"username":"test"}' http://example.net/resource/id
But in the documentation of Guzzle they use parameters just like GET, like DELETE http://example.net/resource/id?username=test, and I don't want to do that.
I tried with:
$client = new GuzzleHttp\Client();
$client->request('DELETE', $url, $data);
but the request just calls DELETE http://example.com/resource/id without any parameters.
If I interpret your curl request properly, you are attempting to send json data as the body of your delete request.
// turn on debugging mode. This will force guzzle to dump the request and response.
$client = new GuzzleHttp\Client(['debug' => true,]);
// this option will also set the 'Content-Type' header.
$response = $client->delete($uri, [
'json' => $data,
]);
coming late on this question after having same.
Prefered solution, avoiding debug mode is to pass params in 'query' as :
$response = $client->request('DELETE', $uri, ['query' => $datas]);
$datas is an array
Guzzle V6
$response = json_decode($this->client->delete($uri,$params)->getStatusCode());
echo $response;
This will also give the status of the response as 204 or 404

CURL is failed in sending the parameters to the Server

I am going to send a Log in request to the server by using CURL in my PHP code. This request is POST and I wrote following code,
if (strpos($header, 'POST') !== false){
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 1,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'proxy',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $postParameters,
CURLOPT_COOKIE => $postCoockies
));
$respond = curl_exec($curl);
curl_close($curl); }
and if I want to say what my variables are here:
$url is the exact String after POST and before HTTP/1.1.
when I want to send the GET request also, I am using this part as my urs which would be contained all parameters in my query String.
$postParameters is the exact String that exist in POST body.
(That's a String, not an associative array)
$postCoockies in the exact String after Cookie: in my request header.
(again, that's not an associative array)
My problem is:
When I send this request, server sends me back a response to only the URL I am passing. Which is to load the login page again! it seems that the server is not receiving my parameters!
Also, when I used GET request for login (I have access to the source code of website), and sent the whole URL and parameters inside the $url, the same thing happened.
Am I wrong somewhere in sending my request?
Should I consider something else here?

How to send URL variables programmatically with response from my PHP endpoint

I have a basic API endpoint set up on my site, which a 3rd party site will use to verify certain info that is entered into a form by the user.
Here's the flow:
1. User is on 3rd party site.
2. User enters info into a form
3. Info is sent to my site's endpoint.
4. My site checks the information and returns a JSON object.
As you can see from #4, my API is currently set up to return a JSON object. After the info is checked, something like this happens:
header('content-type: application/json; charset=utf-8');
echo json_encode($response);
exit;
However, the 3rd party site is only set up to receive URL variables. Is there a way to pass back url variables programmatically? I realize I could theoretically send a new request, but it's not clear to me where that request should go (the internal workings of the 3rd party site aren't well documented), so I'd much prefer to send it as a response.
I hope this makes sense. Please comment if it doesn't. Thanks in advance!
You don't get to send GET/POST parameters in the response, but in the response body you can send whatever you want in whatever format you want - and they can use curl or file_get_content and parse it on their side (3rd party's website).
For example (on the 3rd party's website):
//setting a call to your server
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-Type: text/xml\r\n".
"Authorization: Basic ".base64_encode("$https_user:$https_password")."\r\n",
'content' => $body,
'timeout' => 60
)
);
$context = stream_context_create($opts);
$url = 'https://'.$https_server;
// Here they call your server
$result = file_get_contents($url, false, $context, -1, 40000);
// Here you'll parse the $result

Categories