how to compress(gzip) body of a request in guzzle 6 - php

need to send compressed (gzip) body to a server
e.g.
protected function postOrPutData($method, $data, $type, $uri = null, array $options = [])
{
$requestBody = $this->serializer->serialize($data, 'json');
$request = new Request($method, $uri, [], $requestBody);
$response = $this->httpClient->send($request, $options);
return $this->serializer->deserialize((string) $response->getBody(), $type, 'json');
}

I think you can get inspiration also from similar question about pure cURL.
Try to use this custom setting with Guzzle (I assume that you are using it with cURL handler):
$options['curl'] = [CURLOPT_ENCODING => 'gzip'];
$request = new Request($method, $uri, [], $requestBody);
$response = $this->httpClient->send($request, $options);

Related

laravel and guzzle auth

Hi i want to consume a service and i use laravel 5.x with guzzle with this code i can send request and i use the correct api-key but i always obtain 403 forbidden....
public function searchP(Request $request) {
$targa = request('targa');
$client = new \GuzzleHttp\Client();
$url = 'https://xxx.it/api/xxx/xxx-number/'.$targa.'/xxx-xxxx';
$api_key ='xxxxxcheepohxxxx';
try {
$response = $client->request(
'GET',
$url,
['auth' => [null, $api_key]]);
} catch (RequestException $e) {
var_dump($e->getResponse()->getBody()->getContent());
}
// Get JSON
$result = $response->json();
}
Why? I cannot understand
In postman i write in the AUTHORIZATION label this
key : x-apikey
value: xxxxxcheepohxxxx
Add to header
and it works.
i also tried this
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey', $api_key
]
]);
} catch .....
but doesn't work
Thx
it should be this, you have a typo
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey'=> $api_key
]
]);
} catch .....

Why GuzzleHttp client throws ClientException when using it to make network request on Laravel/Lumen?

I am currently building a Financial micro service application using Laravel/Lumen micro framework.Everything have been working perfectly as expected. My problem now is that i am trying to make a network request to my internal services via Api call from ApiGateway using GuzzleHttp client. The problem is that when i make request to the internal service, it always throws an exception of ClientException.
ClientException.
Client error: GET http://127.0.0.1:8081/v1/admin resulted in a 401
Unauthorized response: {"error":"Unauthorized.","code":401}
I have tried to make network request to the same internal services using postman; and it works fine. However, for some reason still fail to work with GuzzleHttp. I don't know what i am doing wrong. Please your assist will be appreciated.
Here is the httpClient.php in ApiGateway.
//Constructor method
public function __construct() {
$this->baseUri = config('services.auth_admin.base_uri');
}
public function httpRequest($method, $requestUrl, $formParams = [], $headers = []) {
//Instantiate the GazzleHttp Client
$client = new Client([
'base_uri' => $this->baseUri,
]);
//Send the request
$response = $client->request($method, $requestUrl, ['form_params' => $formParams, 'headers' => $headers]);
//Return a response
return $response->getBody();
}
//Internal Service Communication in ApiGateway**
public function getAdmin($header) {
return $this->httpRequest('GET', 'admin', $header);
}
InternalServiceController.php
public function getAdmin(Request $request) {
return $this->successResponse($this->authAdminService->getAdmin($request->header()));
}
I am using Lumen version: 5.8 and GuzzleHttp Version: 6.3
You pass your headers as formParams (third index instead of fourth).
Try below:
return $this->httpRequest('GET', 'admin', [], $header);
I am making some assumptions here which I hope should be helpful to you.
PHP does not support skipping optional parameters and thus you should pass an empty array [] when calling httpRequest().
public function httpRequest($method, $requestUrl, $formParams = [], $headers = [], $type='json', $verify = false) {
//Instantiate the GazzleHttp Client
$client = new Client([
'base_uri' => $this->baseUri,
]);
//the request payload to be sent
$payload = [];
if (!$verify) {
$payload['verify'] = $verify; //basically for SSL and TLS
}
//add the body to the specified payload type
$payload[$type] = $formParams;
//check if any headers have been passed and add it as well
if(count($headers) > 0) {
$payload['headers'] = $headers;
}
//Send the request
$response = $client->request($method, $requestUrl, $payload);
//Return a response
return $response->getBody();
}
Now you need to call it in this manner when you are not passing in any form_params or body
//Internal Service Communication in ApiGateway**
public function getAdmin($header) {
return $this->httpRequest('GET', 'admin', [], $header);
}

Generating many URLs in one Symfony Controller action

I have an action with annotation route to "showAllLinks"
/**
* #param Request $request
* #return Response
* #Route("/showAllLinks/")
**/
When that action is accessed, I would like to generate URLs (relative and absolute) to several other actions I wrote in the same controller. Is that possible? So far I've tried with several URLs being generated and pushed into array which then would be included in response, but from what I see, Symfony is either asking for
The Response content must be a string or object implementing __toString(), "array" given.
See action below:
public function showAllLinksAction(Request $request)
{
$linksArr = [];
$url1 = $this->generateUrl('helloWorld', [], 302, UrlGeneratorInterface::ABSOLUTE_URL);
$linksArr[] = $url1;
$url2 = $this->generateUrl('goodbye', [], 302, UrlGeneratorInterface::ABSOLUTE_URL);
$linksArr[] = $url2;
$url3 = $this->generateUrl('welcome', [], 302, UrlGeneratorInterface::ABSOLUTE_URL);
$linksArr[] = $url3;
$url4 = $this->generateUrl('welcome', [], 302, UrlGeneratorInterface::ABSOLUTE_URL);
$linksArr[] = $url4;
return new Response($linksArr);
}
You are passing an array to the response object, you should pass an string. These are the params of the response object, from the Symfony documentation:
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
Response::HTTP_OK,
array('content-type' => 'text/html')
);
I think you could use
$response = new Response('Content');
or
$response = new Response();
$response->setContent('Content');
In any case, the 'Content' parameter is a string. You are trying to set $linksArr, which is an array. This should work, although may not be the result you want to achieve:
return new Response(implode(",", $linksArr));

Guzzle Request query params

I have a method using gullzehttp and would like to change it to the pool plus the pool implements the Request method
<?php
use GuzzleHttp\Client;
$params = ['password' => '123456'];
$header = ['Accept' => 'application/xml'];
$options = ['query' => $params, 'headers' => $header];
$response = $client->request('GET', 'http://httpbin.org/get', $options);
I need to change to the Request method, but I could not find in the documentation how to send querystring variables in the Request
<?php
use GuzzleHttp\Psr7\Request;
$request = new Request('GET', 'http://httpbin.org/get', $options);
You need to add the query as a string to the URI.
For that you can use http_build_query or a guzzle helper function to convert a parameter array to an encoded query string:
$uri = new Uri('http://httpbin.org/get');
$request = new Request('GET', $uri->withQuery(GuzzleHttp\Psr7\build_query($params)));
// OR
$request = new Request('GET', $uri->withQuery(http_build_query($params)));
I also had trouble figuring out how to properly place the new Request() parameters. but structuring it the way i did below using php http_build_query to convert my arrays to query params and then appended it to the url before sending fixed it.
try {
// Build a client
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://pro-api.coinmarketcap.com',
// You can set any number of default request options.
// 'timeout' => 2.0,
]);
// Prepare a request
$url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest';
$headers = [
'Accepts' => 'application/json',
'X-CMC_PRO_API_KEY' => '05-88df-6f98ba'
];
$params = [
'id' => '1'
];
$request = new Request('GET', $url.'?'.http_build_query($params), $headers);
// Send a request
$response = $client->send($request);
// Receive a response
dd($response->getBody()->getContents());
return $response->getBody()->getContents();
} catch (\Throwable $th) {
dd('did not work', $th);
return false;
}

Laravel get_file_contents() replaces & with &

How can I avoid Laravel replacing & with & when calling get_file_contents()? I always get a "Bad Request" response because of this,
which is not a problem when not using Laravel.
use file_get_contents(htmlspecialchars_decode($URL));
I solve my problem just use the " instead ' when building string URL path like follow:
public function __construct($url, $username, $password)
{
$this->url = $url;
$this->params = 'send?username='.$username.'&password='.$password.'&dlr=no';
}
to:
public function __construct($url, $username, $password)
{
$this->url = $url;
$this->params = "send?username=".$username."&password=".$password."&dlr=no";
}
Instead of use file_get_contents() you can use guzzlehttp/guzzle you can use this link for installation, and following example to send request and get response:
$client = new Client([
'base_uri' => $this->url,
'timeout' => 1.0,
]);
$request = $client->request('POST', $params);
$response = $request->getBody()->getContents();
You can access the content's of body by getContents() method, hop this help you.

Categories