From 4ffc73baa5e0311a8998adb6489e5dfcffcf9a4b Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 11 Oct 2026 22:52:47 -0300 Subject: [PATCH 1/3] Apply timeout to persistent connections The persistent socket was built with HTTP.persistent alone, so the timeout option only reached the non-persistent path. With persistent mode on by default, requests ran with no client-side timeout. --- CHANGELOG.md | 1 + lib/serpapi/client.rb | 2 +- spec/serpapi/client/client_spec.rb | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ff82ee..358c3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + * [Unreleased] Apply the `timeout` option to persistent connections * [Unreleased] Add Image API support * [Unreleased] Add Markdown search and archive output support * [Unreleased] Raise `SerpApiError` for non-200 text responses, including 404 responses from `get('/invalid')` diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index c872291..2667dc7 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -100,7 +100,7 @@ def initialize(params = {}) # create connection socket return unless persistent? - @socket = HTTP.persistent("https://#{BACKEND}") + @socket = HTTP.timeout(timeout).persistent("https://#{BACKEND}") end # perform a search using SerpApi.com diff --git a/spec/serpapi/client/client_spec.rb b/spec/serpapi/client/client_spec.rb index 8384d3b..724eaf3 100644 --- a/spec/serpapi/client/client_spec.rb +++ b/spec/serpapi/client/client_spec.rb @@ -159,6 +159,10 @@ expect(client.persistent).to be true end + it 'applies the timeout to the persistent socket' do + expect(client.socket.default_options.timeout_options).to eq(global_timeout: 10) + end + it 'makes a search request with valid parameters' do results = client.search(q: 'Coffee', location: 'Austin, TX') expect(results.size).to be > 5 From 3a830c771326be3db3c9649cc6961a721cc8d190 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 11 Oct 2026 22:56:21 -0300 Subject: [PATCH 2/3] Document timeout for persistent connections --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3fe4a9d..0f6e170 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ results = client.search( | `api_key` | None | Your SerpApi API key. Use an environment variable rather than committing it to source control. | | `engine` | None | The search engine used by default, such as `google` or `google_maps`. | | `persistent` | `true` | Reuses the HTTP connection between requests. Call `client.close` when finished. | -| `timeout` | `120` | Timeout in seconds for non-persistent HTTP requests. | +| `timeout` | `120` | Timeout in seconds for HTTP requests. | | `async` | `false` | Submits searches without waiting for them to complete. It can be set on the client or per search. | | `symbolize_names` | `true` | Returns JSON object keys as symbols. Pass `false` to a search to receive string keys. | From 34bbfcae5a580149e7ba130aab2fcba2935f5134 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Wed, 14 Oct 2026 08:16:23 -0300 Subject: [PATCH 3/3] Stub HTTP.timeout in image API spec --- spec/serpapi/client/image_api_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/serpapi/client/image_api_spec.rb b/spec/serpapi/client/image_api_spec.rb index 0fc4f5d..3503479 100644 --- a/spec/serpapi/client/image_api_spec.rb +++ b/spec/serpapi/client/image_api_spec.rb @@ -13,7 +13,7 @@ let(:client) { SerpApi::Client.new(api_key: api_key) } before do - allow(HTTP).to receive(:persistent).and_return(socket) + allow(HTTP).to receive(:timeout).and_return(double(persistent: socket)) allow(response).to receive(:flush) end