admin管理员组

文章数量:1125717

I am trying to test for timeout scenarios for my API requests using WP_Http::request() by passing a very short timeout argument (a minimal fraction of a second). After my API requests continued to succeed regardless of my extremely low setting, I noticed that my timeout was being set to a thousand milliseconds (one second) even though I had set it much lower for testing.

Is there a way I can get around this and pass a timeout less than a second?

Simplest example:

$http = new WP_Http;
$response = $http->request(
    'YOUR_URL',
    array(
        'timeout' => 0.00001,
    ),
);

(timeout is set small to test for a real-world timeout scenario, but it doesn't fail as expected unless over 1,000 ms)

I am trying to test for timeout scenarios for my API requests using WP_Http::request() by passing a very short timeout argument (a minimal fraction of a second). After my API requests continued to succeed regardless of my extremely low setting, I noticed that my timeout was being set to a thousand milliseconds (one second) even though I had set it much lower for testing.

Is there a way I can get around this and pass a timeout less than a second?

Simplest example:

$http = new WP_Http;
$response = $http->request(
    'YOUR_URL',
    array(
        'timeout' => 0.00001,
    ),
);

(timeout is set small to test for a real-world timeout scenario, but it doesn't fail as expected unless over 1,000 ms)

Share Improve this question edited Feb 29, 2024 at 19:47 Talk Nerdy To Me asked Feb 29, 2024 at 18:54 Talk Nerdy To MeTalk Nerdy To Me 2852 silver badges10 bronze badges 1
  • can you edit your question to include the code you used? As well as how you confirmed the thousand milliseconds? – Tom J Nowell Commented Feb 29, 2024 at 19:20
Add a comment  | 

1 Answer 1

Reset to default 2

I suspect this is the cause in the Requests library that powers WP_HTTP:

  • Transfer & connect timeouts, in seconds & milliseconds

cURL is unable to handle timeouts under a second in DNS lookups, so we round those up to ensure 1-999ms isn't counted as an instant failure.

The code looks to be here:

https://github.com/WordPress/Requests/blob/90db63ab54449c071fc2192a4fc3487cafbf67d0/src/Transport/Curl.php#L448-L460

        if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
            curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
        } else {
            // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_timeout_msFound
            curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
        }

If your goal is to test that a response time is within a certain limit by using the timeout so it fails when it takes too long, as clever as it sounds there are other things that interfere. Instead timing the request at the API server side, and at the client side, then using the time taken to implement your own timeout test would be more reliable ( and give you the opportunity to add more logic, e.g. a warning threshold ).

https://github.com/WordPress/Requests/issues/58

It's also possible your server is using an old version of curl that does not support microsecond based timeouts

本文标签: http apiwphttp remote request not respecting timeout