Laravel 9 | cURL request to HTTP Client - laravel

New versions of laravel have their own HTTP client. I like the syntax and want to use it. Before that I was always using cURL.
I am now trying to make a request with the new HTTP client, but I always get a weird result back. Status is 200 btw.:
{
"cookies": {},
"transferStats": {}
}
I dont know where this comes from, my endpoint does not return this.
This is the cURL version, which works:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => env('SCAMMER_CHECK_ENDPOINT'),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('auth' => $data['auth'],'authUserId' => $msd_user_id,'img' => $data['base64img']),
));
$scammer_check = curl_exec($curl);
curl_close($curl);
This is the same request with the HTTP client, which does not work:
$scammer_check = Http::post(env('SCAMMER_CHECK_ENDPOINT'), [
'auth' => $data['auth'],
'authUserId' => $msd_user_id,
'img' => $data['base64img']
]);
I also tried to use raw body, but same result:
$scammer_check = Http::withBody(
json_encode(array('auth' => $data['auth'],'authUserId' => $msd_user_id,'img' => $data['base64img'])), 'application/json'
)->post(env('SCAMMER_CHECK_ENDPOINT'));

It seems like the HTTP client is returning an empty response with cookies and transferStats. This could be due to incorrect response handling.
You could try retrieving the response body by using the "body" method on the response object like this:
$response = Http::post(env('SCAMMER_CHECK_ENDPOINT'), [
'auth' => $data['auth'],
'authUserId' => $msd_user_id,
'img' => $data['base64img']
]);
$scammer_check = $response->body();
Alternatively, you could try specifying the expected response format like this:
$scammer_check = Http::post(env('SCAMMER_CHECK_ENDPOINT'), [
'auth' => $data['auth'],
'authUserId' => $msd_user_id,
'img' => $data['base64img']
])->json();

Related

Send nested array via Laravel Http Client

I want to send request to an API website containing nested params via Laravel Http Client (Laravel 7.x)
$params = [
'type' => 'books',
'variables' => [
'color' => 'red',
'size' => 'large'
]
]
I want my url to like this:
http://example.com/?type=books&variables={"color":"red","size":"large"}
encoded above url:
http://example.com/?type=books&variables=%7B%22color%22%3A%22red%22%2C%22size%22%3A%22large%22%7D
But when I use:
Http::get('http://example.com', $params);
The API server returns error.
But when I use:
Http::get('http://example.com/?type=books&variables={"color":"red","size":"large"}');
It works well.
So how can I convert my params array into url ?
(I don't have access to API server)
try json_encode()
$params = [
'type' => 'books',
'variables' => json_encode([
'color' => 'red',
'size' => 'large'
])
]
$url = "http://example.com?".http_build_query($params);
Http::get($url);
and http_build_query()
ref link https://www.php.net/manual/en/function.http-build-query.php

form_params method get guzzle php

I have an API get list user. postmen
and Headers Content-Type = application/json
- In laravel, I use guzzle to call api
code demo:
$client = new Client();
$headers = ['Content-Type' => 'application/json'];
$body = [
'json' => [
"filter" => "{}",
"skip" => 0,
"limit" => 20,
"sort" => "{\"createAt\": 1}",
"select" => "fullname username",
"populate" => "'right', 'group'",
]
];
\Debugbar::info($body);
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'form_params' => $body
]);
echo $response->getBody();
But it does not working! please help me
form_params and body both are different params in guzzle. check json
$json = [
"filter" => json_encode((object)[]),
"skip" => 0,
"limit" => 20,
"sort" => json_encode((object)['createAt'=>1]),
"select" => "fullname username",
"populate" => "'right', 'group'"
];
$response = $client->request('get', 'http://sa-vn.com:2020/api/users/user', [
'json' => $json,
]);
If any error occur try without json_encode as well.
$json = [
"filter" => (object)[],
"skip" => 0,
"limit" => 20,
"sort" => (object)['createAt'=>1],
"select" => "fullname username",
"populate" => "'right', 'group'"
];
As per Guzzle doucmentation
form_params
Used to send an application/x-www-form-urlencoded POST request.
json
The json option is used to easily upload JSON encoded data as the body of a request. A Content-Type header of application/json will be added if no Content-Type header is already present on the message.
You are passing json data in postman. So you can use json instead of form_params
Change
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'form_params' => $body
]);
to
$response = $client->get('http://sa-vn.com:2020/api/users/user', [
'json' => $body
]);

Guzzle Post Null/Empty Values in Laravel

I've been trying to work with Guzzle and learn my way around it, but I'm a bit confused about using a request in conjunction with empty or null values.
For example:
$response = $client->request('POST',
'https://www.testsite.com/coep/public/api/donations', [
'form_params' => [
'client' => [
'web_id' => NULL,
'name' => 'Test Name',
'address1' => '123 E 45th Avenue',
'address2' => 'Ste. 1',
'city' => 'Nowhere',
'state' => 'CO',
'zip' => '80002'
],
'contact' => [],
'donation' => [
'status_id' => 1,
'amount' => $donation->amount,
'balance' => $donation->balance,
'date' => $donation->date,
'group_id' => $group->id,
],
]
]);
After running a test, I found out that 'web_id' completely disappears from my request if set to NULL. My question is how do I ensure that it is kept around on the request to work with my conditionals?
At this point, if I dd the $request->client, all I get back is everything but the web_id. Thanks!
I ran into this issue yesterday and your question is very well ranked on Google. Shame that it has no answer.
The problem here is that form_params uses http_build_query() under the hood and as stated in this user contributed note, null params are not present in the function's output.
I suggest that you pass this information via a JSON body (by using json as key instead of form_params) or via multipart (by using multipart instead of form_params).
Note: those 2 keys are available as constants, respectively GuzzleHttp\RequestOptions::JSON and GuzzleHttp\RequestOptions::MULTIPART
Try to define anything like form_params, headers or base_uri before creating a client, so:
// set options, data, params BEFORE...
$settings = [
'base_uri' => 'api.test',
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'ajustneedatokenheredontworry'
],
'form_params' => [
'cash' => $request->cash,
'reason' => 'I have a good soul'
]
];
// ...THEN create your client,
$client = new GuzzleClient($settings);
// ...and finally check your response.
$response = $client->request('POST', 'donations');
If you check $request->all() at the controller function that you are calling, you should see that were sent successfully.
For those using laravel, use this:
Http::asJson()

guzzle client throws exception in laravel

I am trying to make a http post request in laravel as below
$client = new Client(['debug'=>true,'exceptions'=>false]);
$res = $client->request('POST', 'http://www.myservice.com/find_provider.php', [
'form_params' => [
'street'=> 'test',
'apt'=> '',
'zip'=> 'test',
'phone'=> 'test',
]
]);
It return empty response. On debugging ,following exception is occurring
curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*
I am using latest version of guzzle.
Any idea how to solve it?.
The request() method is returning a GuzzleHttp\Psr7\Response object.
To get the actual data that is returned by your service you should use:
$data = $res->getBody()->getContents();
Now check what you have in $data and if it corresponds to the expected output.
More information on using Guzzle Reponse object here
I had to do this
$data = $res->getBody()->getContents();<br>
but also change<br>
$client = new \GuzzleHttp\Client(['verify' => false, 'debug' => true]);<br>
to<br>
$client = new \GuzzleHttp\Client(['verify' => false]);
Here is what i did for my SMS api
use Illuminate\Support\Facades\Http; // Use this on top
// Sample Code
$response = Http::asForm()
->withToken(env('SMS_AUTH_TOKEN'))
->withOptions([
'debug' => fopen('php://stderr', 'w') // Update This Line
])
->withHeaders([
'Cache-Control' => 'no-cache',
'Content-Type' => 'application/x-www-form-urlencoded',
])
->post($apiUrl,$request->except('_token'));

Ruby Curl::Multi.http 302 redirect problems

I seem to be having a problem with 302 redirects using curb (Ruby's curl programs)
Here's the code snippet that is ** NOT working** (it's NOT doing the 302 redirect)
easy_options = {:follow_location => true, :enable_cookies => true, :useragent => 'curb', :cookiefile => 'cookie.txt'}
multi_options = {:pipeline => true}
url_fields = [
{
:url => 'https://x.y.z/webapps/login/',
:method => :post,
:follow_location => true,
:enable_cookies => true,
:useragent => 'curb',
:post_fields => {
'user_id' => 'xxxx',
'password' => 'xxxx',
'action' => 'login',
'encoded_pw' => Base64.strict_encode64('xxxx')},
}
]
Curl::Multi.http(url_fields,{:pipeline => true}) do |easy, code, method|
puts easy.header_str
end
Here's the code snippet that appears to be working (it's doing the 302 redirect)
easy_options = {:follow_location => true, :enable_cookies => true, :useragent => 'curb', :cookiefile => 'cookie.txt'}
multi_options = {:pipeline => true}
url_fields = [
{ :url => 'https://x.y.z/webapps/login/',
:post_fields => {
'user_id' => 'xxxx',
'password' => 'yyyy',
'action' => 'login',
'encoded_pw' => Base64.strict_encode64('yyyy')}}
]
Curl::Multi.post(url_fields, easy_options, multi_options) do|easy|
# do something interesting with the easy response
puts easy.last_effective_url
end
Question: Why is the first block not doing the 302 redirect as expected? :follow_location is set to true?
Thanks in advance!
Let me know if you need more information

Resources