From 93279a1f7bea6ddc3cfa9bfddc0f3fce5c50c57f Mon Sep 17 00:00:00 2001 From: Ryan McCue Date: Tue, 14 Jun 2016 13:41:03 +1000 Subject: [PATCH 1/4] Round up to at least 1 second timeouts --- library/Requests/Transport/cURL.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/library/Requests/Transport/cURL.php b/library/Requests/Transport/cURL.php index 3ce0c5157..28e612640 100755 --- a/library/Requests/Transport/cURL.php +++ b/library/Requests/Transport/cURL.php @@ -349,11 +349,17 @@ protected function setup_handle($url, $headers, $data, $options) { break; } - if (is_int($options['timeout']) || $this->version < self::CURL_7_16_2) { - curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($options['timeout'])); + // cURL requires a minimum timeout of 1 second when using the system + // DNS resolver (getaddrinfo). There's no way to detect which DNS + // resolver is being used from our end, so we need to round up + // regardless of the supplied timeout. + $timeout = min($options['timeout'], 1); + + if (is_int($timeout) || $this->version < self::CURL_7_16_2) { + curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout)); } else { - curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($options['timeout'] * 1000)); + curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000)); } if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) { From cb650f862e260d1ca03e31e6a1741a321f9fc955 Mon Sep 17 00:00:00 2001 From: Ryan McCue Date: Tue, 14 Jun 2016 13:49:53 +1000 Subject: [PATCH 2/4] Use max, not min I am dumb. --- library/Requests/Transport/cURL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Requests/Transport/cURL.php b/library/Requests/Transport/cURL.php index 28e612640..3c33e45fa 100755 --- a/library/Requests/Transport/cURL.php +++ b/library/Requests/Transport/cURL.php @@ -353,7 +353,7 @@ protected function setup_handle($url, $headers, $data, $options) { // DNS resolver (getaddrinfo). There's no way to detect which DNS // resolver is being used from our end, so we need to round up // regardless of the supplied timeout. - $timeout = min($options['timeout'], 1); + $timeout = max($options['timeout'], 1); if (is_int($timeout) || $this->version < self::CURL_7_16_2) { curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout)); From 4e1c18ff40568addd2f50b23e86e382766e7f3ba Mon Sep 17 00:00:00 2001 From: Ryan McCue Date: Tue, 14 Jun 2016 13:55:11 +1000 Subject: [PATCH 3/4] Add note on why 1s is the minimum --- library/Requests/Transport/cURL.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/Requests/Transport/cURL.php b/library/Requests/Transport/cURL.php index 3c33e45fa..36cba510c 100755 --- a/library/Requests/Transport/cURL.php +++ b/library/Requests/Transport/cURL.php @@ -350,9 +350,11 @@ protected function setup_handle($url, $headers, $data, $options) { } // cURL requires a minimum timeout of 1 second when using the system - // DNS resolver (getaddrinfo). There's no way to detect which DNS - // resolver is being used from our end, so we need to round up - // regardless of the supplied timeout. + // DNS resolver, as it uses `alarm()`, which is second resolution only. + // There's no way to detect which DNS resolver is being used from our + // end, so we need to round up regardless of the supplied timeout. + // + // https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609 $timeout = max($options['timeout'], 1); if (is_int($timeout) || $this->version < self::CURL_7_16_2) { From 9d956c7028ac987f8c90ce7d9f37db45c293d8cf Mon Sep 17 00:00:00 2001 From: Ryan McCue Date: Tue, 14 Jun 2016 13:56:55 +1000 Subject: [PATCH 4/4] Add note to docs --- library/Requests.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/Requests.php b/library/Requests.php index 6a8eef375..49489c0a5 100755 --- a/library/Requests.php +++ b/library/Requests.php @@ -304,6 +304,8 @@ public static function patch($url, $headers, $data = array(), $options = array() * options: * * - `timeout`: How long should we wait for a response? + * Note: for cURL, a minimum of 1 second applies, as DNS resolution + * operates at second-resolution only. * (float, seconds with a millisecond precision, default: 10, example: 0.01) * - `connect_timeout`: How long should we wait while trying to connect? * (float, seconds with a millisecond precision, default: 10, example: 0.01)