Limit connecting time with Guzzle HTTP PHP client
Asked Answered
O

5

23

I'm using Guzzle to open a list of url-s and get the headers. Some of the urls are taking too long to respond and can't be openned and i want to ignore them. It takes me up to 20+ seconds before Guzzle throws an exception and i want to change this and limit the time for connecting to 2 sec. I have this code but it still takes much longer:

<?php
include 'vendor/autoload.php';

$start = new \DateTime("now");

$start = $start->format("d.m.Y H:i:s");
echo $start."\n";
$client = new Guzzle\Http\Client();

Guzzle\Http\StaticClient::mount();

try {
    $request = $client->get('http://takestoolongexample', [], ['connect_timeout' => 2, 'timeout' => 3, 'debug' => true]);
    $response = $request->send();

    var_dump($response->getStatusCode());
} catch (Exception $e) {
    echo "\n".$e->getMessage()."\n";
}

$end = new \DateTime("now");

$end = $end->format("d.m.Y H:i:s");

echo "\n".$end."\n";
?>

Here's an example result. As you can see, it took 13 seconds.

$ php test.php
30.12.2013 22:00:07
* getaddrinfo(3) failed for takestoolongexample:80
* Couldn't resolve host 'takestoolongexample'
* Closing connection 0

[curl] 6: Couldn't resolve host 'http://takestoolongexample' http://takestoolongexample

30.12.2013 22:00:20

(http://takestoolongexample was a real url, changed it here)

Olnee answered 30/12, 2013 at 21:10 Comment(0)
O
42

Here's the updated solution to this problem for Guzzle version (Guzzle 4).

$request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url), [
    'timeout' => 5, // Response timeout
    'connect_timeout' => 5, // Connection timeout
]);

Throws Guzzle\Http\Exception\RequestException

Documentation for the latest version is here: Guzzle request options - connect_timeout, timeout.

Orpiment answered 10/11, 2014 at 14:18 Comment(1)
In case of someone searching for same solution for Symfony Goutte or HttpClient, it's max_durationTreadway
R
12

Small precision, you also can define timeouts on Client constructor

$client = new Guzzle\Http\Client('', array(
    'request.options' => array (
        'timeout' => 6,
        'connect_timeout' => 6 
    ) 
));

It'll be valid for all requests made from this Client

Robison answered 6/11, 2015 at 11:17 Comment(1)
You can set the options directly as the first param too - new \GuzzleHttp\Client(['timeout' => 6, 'connect_timeout' => 6]); github.com/guzzle/guzzle/blob/master/docs/…Lenin
F
6

The only way I know how to do it in Guzzle is:

$params = array(
    'command.request_options' = array(
        'timeout'         => 5,
        'connect_timeout' => 2
    )
);

$client = new Client();

$description = ServiceDescription::factory('/path/to/service/description/file');
$client->setDescription($description);

$command = $client->getCommand('commandName', $params);
$command->prepare();

$client->execute($command);

At first glance, Guzzle's documentation seems very good, but I think it's poor, confusing and incomplete. So, for me, is hard to figure out if your code is actually correct and if it should work.

Florence answered 30/12, 2013 at 21:22 Comment(0)
P
0

Your example is correct, but it will always fail.

The error is happening on cURL level, not Guzzle. Before sending an HTTP request (Guzzle's job), you need to establish the related IP session (cURL's one). To get the IP session, DNS translation must happen before packets are sent.

In your example, DNS resolution is failing. It is happening in cURL code, not Guzzle one. So your timeout value won't be used.

If you're still having this error with your real URL, you may add, before your guzzle request, a test which will check if DNS is resolved. Or you may define the following cURL option: CURLOPT_CONNECTTIMEOUT or CURLOPT_CONNECTTIMEOUT_MS (see http://php.net/manual/en/function.curl-setopt.php)

Prepossess answered 30/12, 2013 at 21:28 Comment(0)
L
0

Set dns resolve timeout before use guzzle client

putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1'); //dns resolve params

$request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url), 
array(
'timeout' => 5, // Response timeout
'connect_timeout' => 5, // Connection timeout
));
Liberalize answered 18/10, 2016 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.