Skip to content

Commit 61ae7bc

Browse files
authored
Merge pull request #197 from 907th/http_timeouts_part2
Rework of timeout errors (part 2): add support for new write_timeout option to all adapters + fix integration tests duplication
2 parents 3a6ae1c + 5d83dc9 commit 61ae7bc

19 files changed

+334
-485
lines changed

lib/httpi/adapter/curb.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def setup_client
7272
def basic_setup
7373
@client.url = @request.url.to_s
7474
@client.proxy_url = @request.proxy.to_s if @request.proxy
75-
@client.timeout_ms = @request.read_timeout * 1000 if @request.read_timeout
75+
read_or_write_timeout = @request.read_timeout || @request.write_timeout
76+
@client.timeout_ms = read_or_write_timeout * 1000 if read_or_write_timeout
7677
@client.connect_timeout_ms = @request.open_timeout * 1000 if @request.open_timeout
7778
@client.headers = @request.headers.to_hash
7879
@client.verbose = false

lib/httpi/adapter/em_http.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ def _request
7171
def connection_options
7272
options = {}
7373

74-
options[:inactivity_timeout] = @request.read_timeout if @request.read_timeout
74+
read_or_write_timeout = @request.read_timeout || @request.write_timeout
75+
options[:inactivity_timeout] = read_or_write_timeout if read_or_write_timeout
7576
options[:connect_timeout] = @request.open_timeout if @request.open_timeout
7677

7778
options[:proxy] = proxy_options if @request.proxy

lib/httpi/adapter/excon.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def client_opts
5858
opts[:user], opts[:password] = *@request.auth.credentials if @request.auth.basic?
5959
opts[:connect_timeout] = @request.open_timeout if @request.open_timeout
6060
opts[:read_timeout] = @request.read_timeout if @request.read_timeout
61+
opts[:write_timeout] = @request.write_timeout if @request.write_timeout
6162
opts[:response_block] = @request.on_body if @request.on_body
6263
opts[:proxy] = @request.proxy if @request.proxy
6364

lib/httpi/adapter/http.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def create_client
7676
timeouts = {}
7777
timeouts[:connect] = @request.open_timeout if @request.open_timeout
7878
timeouts[:read] = @request.read_timeout if @request.read_timeout
79+
timeouts[:write] = @request.write_timeout if @request.write_timeout
7980
client = client.timeout(timeouts) if timeouts.any?
8081

8182
client.headers(@request.headers)

lib/httpi/adapter/httpclient.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def basic_setup
4545
@client.proxy = @request.proxy if @request.proxy
4646
@client.connect_timeout = @request.open_timeout if @request.open_timeout
4747
@client.receive_timeout = @request.read_timeout if @request.read_timeout
48+
@client.send_timeout = @request.write_timeout if @request.write_timeout
4849
end
4950

5051
def setup_auth

lib/httpi/adapter/net_http.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ def setup_client
155155
@client.use_ssl = @request.ssl?
156156
@client.open_timeout = @request.open_timeout if @request.open_timeout
157157
@client.read_timeout = @request.read_timeout if @request.read_timeout
158+
if @request.write_timeout
159+
if @client.respond_to?(:write_timeout=) # Expected to appear in Ruby 2.6
160+
@client.write_timeout = @request.write_timeout
161+
else
162+
raise NotSupportedError, "Net::HTTP supports write_timeout starting from Ruby 2.6"
163+
end
164+
end
158165
end
159166

160167
def setup_ssl_auth

lib/httpi/adapter/net_http_persistent.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def setup_client
3232

3333
@client.open_timeout = @request.open_timeout if @request.open_timeout
3434
@client.read_timeout = @request.read_timeout if @request.read_timeout
35+
raise NotSupportedError, "Net::HTTP::Persistent does not support write_timeout" if @request.write_timeout
3536
end
3637

3738
def thread_key

lib/httpi/request.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module HTTPI
1111
class Request
1212

1313
# Available attribute writers.
14-
ATTRIBUTES = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout, :follow_redirect, :redirect_limit, :query]
14+
ATTRIBUTES = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout, :write_timeout, :follow_redirect, :redirect_limit, :query]
1515

1616
# Accepts a Hash of +args+ to mass assign attributes and authentication credentials.
1717
def initialize(args = {})
@@ -90,7 +90,7 @@ def set_cookies(object_or_array)
9090
headers["Cookie"] = cookies if cookies
9191
end
9292

93-
attr_accessor :open_timeout, :read_timeout
93+
attr_accessor :open_timeout, :read_timeout, :write_timeout
9494
attr_reader :body
9595

9696
# Sets a body request given a String or a Hash.

spec/httpi/adapter/curb_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,19 @@
152152
adapter.request(:get)
153153
end
154154

155-
it "is set if specified" do
155+
it "is set if specified read_timeout" do
156156
request.read_timeout = 30
157157
curb.expects(:timeout_ms=).with(30_000)
158158

159159
adapter.request(:get)
160160
end
161+
162+
it "is set if specified write_timeout" do
163+
request.write_timeout = 30
164+
curb.expects(:timeout_ms=).with(30_000)
165+
166+
adapter.request(:get)
167+
end
161168
end
162169

163170
describe "connect_timeout_ms" do

spec/httpi/adapter/em_http_spec.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
end
119119

120120
describe "receive_timeout" do
121-
it "is passed as a connection option" do
121+
it "is passed as a connection option (when read_timeout specified)" do
122122
request.read_timeout = 60
123123

124124
url = "http://example.com:80"
@@ -128,6 +128,17 @@
128128

129129
adapter
130130
end
131+
132+
it "is passed as a connection option (when write_timeout specified)" do
133+
request.write_timeout = 60
134+
135+
url = "http://example.com:80"
136+
connection_options = { inactivity_timeout: 60 }
137+
138+
EventMachine::HttpRequest.expects(:new).with(url, connection_options)
139+
140+
adapter
141+
end
131142
end
132143

133144
describe "set_auth" do

0 commit comments

Comments
 (0)