I have something like that:
$client = new Zend_Http_Client('http://www.site.com');
$client->setParameterGet(array(
'platform' => $platform,
'clientId' => $clientId,
'deploymentId' => $deploymentId,
));
try {
$response = $client->request();
...
This would generate a request similar to 'http://www.site.com/?plataform=..?clientid?..'.
Is there a way I could retrieve this full URL generated by this GET request?
Kind regards,
Surprisingly enough there is no direct method for getting full request string.
BUT
After the request is done you could check $client->getLastRequest
().
If you need to know what the ?plataform=..?clientid? part of the
request is there is a trick.
function getClientUrl (Zend_Http_Client $client)
{
try
{
$c = clone $client;
/*
* Assume there is nothing on 80 port.
*/
$c->setUri ('http://127.0.0.1');
$c->getAdapter ()
->setConfig (array (
'timeout' => 0
));
$c->request ();
}
catch (Exception $e)
{
$string = $c->getLastRequest ();
$string = substr ($string, 4, strpos ($string, "HTTP/1.1\r\n") - 5);
}
return $client->getUri (true) . $string;
}
$client = new Zend_Http_Client ('http://yahoo.com');
$client->setParameterGet ('q', 'search string');
echo getClientUrl ($client);
Related
I'm trying to make a request with my other endpoint, using GuzzleHttp in laravel, but the token isn't authorizing it. I believe it's in the way I'm going. Anyone know how to fix this? This is my code.
public function productRecommendation($rowPerPage,$keywords, $page){
try{
$request = request();
$token = $request->bearerToken();
$client = new \GuzzleHttp\Client();
$promise = $client->request('GET', $this->sellerUrl.'recommended', [
'headers' => ['Authorization' => "Bearer {$token}"],
'query' =>
[
'rowPerPage' => $rowPerPage,
'page' => $page,
'keywords' => $keywords,
],
]);
$response = (string) $promise->getBody();
return json_decode($response, true);
}
catch (Exception $e){
return $e;
}
}
You are getting the bearer token of your first application using $request->bearerToken() and send it to your second application for authorization which must not work;
You need to get a working token from your second application. You can either generate a token in your second application and copy it inside your current $token variable, or first call the login endpoint of second application with your credentials and use that token.
By the way, Laravel now supports a guzzle wrapper called Illuminate\Support\Facades\Http which makes things lot easier, you can rewrite your code like this:
public function productRecommendation($rowPerPage, $keywords, $page)
{
try{
$token = "some valid token from second endpoint";
$response = Http::withToken(
$token
)->get(
$this->sellerUrl . 'recommended',
[
'rowPerPage' => $rowPerPage,
'page' => $page,
'keywords' => $keywords,
]
);
return response()->json(
json_decode($response->body(), true)
);
}
catch (Exception $e){
return $e;
}
}
Is there any way to mock response and request in Guzzle?
I have a class which sends some request and I want to test.
In Guzzle doc I found a way how can I mock response and request separately. But how can I combine them?
Because, If use history stack, guzzle trying to send a real request.
And visa verse, when I mock response handler can't test request.
class MyClass {
public function __construct($guzzleClient) {
$this->client = $guzzleClient;
}
public function registerUser($name, $lang)
{
$body = ['name' => $name, 'lang' = $lang, 'state' => 'online'];
$response = $this->sendRequest('PUT', '/users', ['body' => $body];
return $response->getStatusCode() == 201;
}
protected function sendRequest($method, $resource, array $options = [])
{
try {
$response = $this->client->request($method, $resource, $options);
} catch (BadResponseException $e) {
$response = $e->getResponse();
}
$this->response = $response;
return $response;
}
}
Test:
class MyClassTest {
//....
public function testRegisterUser()
{
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $guzzleMock]);
$myClass = new MyClass($guzzleClient);
/**
* But how can I check that request contains all fields that I put in the body? Or if I add some extra header?
*/
$this->assertTrue($myClass->registerUser('John Doe', 'en'));
}
//...
}
#Alex Blex was very close.
Solution:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack = \GuzzleHttp\HandlerStack::create($guzzleMock);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
First of all, you don't mock requests. The requests are the real ones you are going to use in production. The mock handler is actually a stack, so you can push multiple handlers there:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$stack = \GuzzleHttp\Handler\MockHandler::createWithMiddleware([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
After you run your tests, $container will have all transactions for you to assert. In your particular test - a single transaction. You are interested in $container[0]['request'], since $container[0]['response'] will contain your canned response, so there is nothing to assert really.
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.
I'm searching to retrieve the request total time in Guzzle 6, just after a simple GET request :
$client = new GuzzleHttp\Client();
$response = client->get('http://www.google.com/');
But can't find anything in the docs about that. Any idea ?
Thanks a lot.
In Guzzle 6.1.0 You can use the 'on_stats' request option to get transfer time etc.
More information can be found at Request Options - on_stats
https://github.com/guzzle/guzzle/releases/tag/6.1.0
You can use setter and getter.
private $totaltime = 0;
public function getTotaltime(){
return $this->totaltime;
}
public function setTotaltime($time){
$this->totaltime = $time;
}
$reqtime= new self();
$response = $client->post($endpointLogin, [
'json' => $payload,
'headers' => $this->header,
'on_stats' => function (TransferStats $stats) use ($reqtime) {
$stats->getTransferTime();
//** set it here **//
$reqtime->setTotaltime($stats->getTransferTime());
}
]);
dd($reqtime->getTotaltime());
An specific example based on the #Michael post.
$client = new GuzzleHttp\Client();
$response = $client->get('http://www.google.com/', [
'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
echo $stats->getEffectiveUri() . ' : ' . $stats->getTransferTime();
}
]);
$client = new GuzzleHttp\Client();
$one = microtime(1);
$response = $client->get('http://www.google.com/');
$two = microtime(1);
echo 'Total Request time: '. ( $two - $one );
I had a similar problem although it's still Guzzle 5.3.
See Guzzle 5.3 - Get request duration for asynchronous requests
Maybe listening to an event in Guzzle6 and retrieving the TransferInfo will do the trick for you too.
This works for synchronous and asynchronous requests alike.
For reasons beyond my control, I'm forced to use NuSoap instead of SOAP to make a request to a webservice.
After some searching, I found SOAP's __getFunctions() equivalent in NuSoap. The part where I'm stuck now is to figure out in what format are the parameters expected by the webservice's function.
require_once(APPPATH.'libraries/nusoap.php');
$baseurl = 'http://www.webservicex.net/geoipservice.asmx?WSDL';
$client = new nusoap_client($baseurl, true);
$err = $client->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
die();
}
$proxy = $client->getProxyClassCode();
print_r($proxy);
The above is giving me an output of
class nusoap_proxy_1027585735 extends nusoap_client
{
// http://www.webservicex.net/:GetGeoIP^
$parameters function GetGeoIP($parameters)
{
$params = array('parameters' => $parameters);
return $this->call('GetGeoIP', $params, 'http://testuri.com', 'http://www.webservicex.net/GetGeoIP');
}
// http://www.webservicex.net/:GetGeoIPContext^
$parameters function GetGeoIPContext($parameters)
{
$params = array('parameters' => $parameters);
return $this->call('GetGeoIPContext', $params, 'http://testuri.com', 'http://www.webservicex.net/GetGeoIPContext');
}
}
So now that I know the function names (GetGeoIP and GetGeoIPContext), I'm struggling to find out what parameters do I need to pass to those functions.
I'm guessing $params = array('parameters' => $parameters); is the part I should be interested in, but that isn't giving the complete picture.
So in short, is there SOAP's __getTypes() equivalent in NuSoap?
You can use SoapUI to get an example of the request.
If you create a new project with your url endPoint (WSDL) you can get all the soapCalls. With it is more easy to understand the types define in the WSDL.
Follow this link http://www.soapui.org/SOAP-and-WSDL/working-with-wsdls.html
$parameters is an array (key -> value) for each param in the request
$parameters = array('IPAddress' => 'xxx.xxx.xxx.xxx')
$opdata = $proxy->getOperationData('GetGeoIP'); The method getOperationData is inherited from nusoap_client. See http://www.contao-docs.org/docs/nusoap/html/classnusoap__client.html.