httpx 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/httpx/request.rb CHANGED
@@ -4,20 +4,50 @@ require "delegate"
4
4
  require "forwardable"
5
5
 
6
6
  module HTTPX
7
+ # Defines how an HTTP request is handled internally, both in terms of making attributes accessible,
8
+ # as well as maintaining the state machine which manages streaming the request onto the wire.
7
9
  class Request
8
10
  extend Forwardable
9
11
  include Callbacks
10
12
  using URIExtensions
11
13
 
14
+ # default value used for "user-agent" header, when not overridden.
12
15
  USER_AGENT = "httpx.rb/#{VERSION}"
13
16
 
14
- attr_reader :verb, :uri, :headers, :body, :state, :options, :response
17
+ # the upcased string HTTP verb for this request.
18
+ attr_reader :verb
15
19
 
16
- # Exception raised during enumerable body writes
20
+ # the absolute URI object for this request.
21
+ attr_reader :uri
22
+
23
+ # an HTTPX::Headers object containing the request HTTP headers.
24
+ attr_reader :headers
25
+
26
+ # an HTTPX::Request::Body object containing the request body payload (or +nil+, whenn there is none).
27
+ attr_reader :body
28
+
29
+ # a symbol describing which frame is currently being flushed.
30
+ attr_reader :state
31
+
32
+ # an HTTPX::Options object containing request options.
33
+ attr_reader :options
34
+
35
+ # the corresponding HTTPX::Response object, when there is one.
36
+ attr_reader :response
37
+
38
+ # Exception raised during enumerable body writes.
17
39
  attr_reader :drain_error
18
40
 
41
+ # The IP address from the peer server.
42
+ attr_accessor :peer_address
43
+
44
+ attr_writer :persistent
45
+
46
+ # will be +true+ when request body has been completely flushed.
19
47
  def_delegator :@body, :empty?
20
48
 
49
+ # initializes the instance with the given +verb+, an absolute or relative +uri+, and the
50
+ # request options.
21
51
  def initialize(verb, uri, options = {})
22
52
  @verb = verb.to_s.upcase
23
53
  @options = Options.new(options)
@@ -37,20 +67,30 @@ module HTTPX
37
67
 
38
68
  @body = @options.request_body_class.new(@headers, @options)
39
69
  @state = :idle
70
+ @response = nil
71
+ @peer_address = nil
72
+ @persistent = @options.persistent
40
73
  end
41
74
 
75
+ # the read timeout defied for this requet.
42
76
  def read_timeout
43
77
  @options.timeout[:read_timeout]
44
78
  end
45
79
 
80
+ # the write timeout defied for this requet.
46
81
  def write_timeout
47
82
  @options.timeout[:write_timeout]
48
83
  end
49
84
 
85
+ # the request timeout defied for this requet.
50
86
  def request_timeout
51
87
  @options.timeout[:request_timeout]
52
88
  end
53
89
 
90
+ def persistent?
91
+ @persistent
92
+ end
93
+
54
94
  def trailers?
55
95
  defined?(@trailers)
56
96
  end
@@ -59,6 +99,7 @@ module HTTPX
59
99
  @trailers ||= @options.headers_class.new
60
100
  end
61
101
 
102
+ # returns +:r+ or +:w+, depending on whether the request is waiting for a response or flushing.
62
103
  def interests
63
104
  return :r if @state == :done || @state == :expect
64
105
 
@@ -69,10 +110,12 @@ module HTTPX
69
110
  @headers = @headers.merge(h)
70
111
  end
71
112
 
113
+ # the URI scheme of the request +uri+.
72
114
  def scheme
73
115
  @uri.scheme
74
116
  end
75
117
 
118
+ # sets the +response+ on this request.
76
119
  def response=(response)
77
120
  return unless response
78
121
 
@@ -85,6 +128,7 @@ module HTTPX
85
128
  emit(:response_started, response)
86
129
  end
87
130
 
131
+ # returnns the URI path of the request +uri+.
88
132
  def path
89
133
  path = uri.path.dup
90
134
  path = +"" if path.nil?
@@ -93,16 +137,28 @@ module HTTPX
93
137
  path
94
138
  end
95
139
 
96
- # https://bugs.ruby-lang.org/issues/15278
140
+ # returs the URI authority of the request.
141
+ #
142
+ # session.build_request("GET", "https://google.com/query").authority #=> "google.com"
143
+ # session.build_request("GET", "http://internal:3182/a").authority #=> "internal:3182"
97
144
  def authority
98
145
  @uri.authority
99
146
  end
100
147
 
101
- # https://bugs.ruby-lang.org/issues/15278
148
+ # returs the URI origin of the request.
149
+ #
150
+ # session.build_request("GET", "https://google.com/query").authority #=> "https://google.com"
151
+ # session.build_request("GET", "http://internal:3182/a").authority #=> "http://internal:3182"
102
152
  def origin
103
153
  @uri.origin
104
154
  end
105
155
 
156
+ # returs the URI query string of the request (when available).
157
+ #
158
+ # session.build_request("GET", "https://search.com").query #=> ""
159
+ # session.build_request("GET", "https://search.com?q=a").query #=> "q=a"
160
+ # session.build_request("GET", "https://search.com", params: { q: "a"}).query #=> "q=a"
161
+ # session.build_request("GET", "https://search.com?q=a", params: { foo: "bar"}).query #=> "q=a&foo&bar"
106
162
  def query
107
163
  return @query if defined?(@query)
108
164
 
@@ -114,6 +170,7 @@ module HTTPX
114
170
  @query = query.join("&")
115
171
  end
116
172
 
173
+ # consumes and returns the next available chunk of request body that can be sent
117
174
  def drain_body
118
175
  return nil if @body.nil?
119
176
 
@@ -139,6 +196,7 @@ module HTTPX
139
196
  end
140
197
  # :nocov:
141
198
 
199
+ # moves on to the +nextstate+ of the request state machine (when all preconditions are met)
142
200
  def transition(nextstate)
143
201
  case nextstate
144
202
  when :idle
@@ -173,6 +231,7 @@ module HTTPX
173
231
  nil
174
232
  end
175
233
 
234
+ # whether the request supports the 100-continue handshake and already processed the 100 response.
176
235
  def expects?
177
236
  @headers["expect"] == "100-continue" && @informational_status == 100 && !@response
178
237
  end
@@ -30,7 +30,7 @@ module HTTPX
30
30
  nameserver = nameserver[family] if nameserver.is_a?(Hash)
31
31
  Array(nameserver)
32
32
  end
33
- @ndots = @resolver_options[:ndots]
33
+ @ndots = @resolver_options.fetch(:ndots, 1)
34
34
  @search = Array(@resolver_options[:search]).map { |srch| srch.scan(/[^.]+/) }
35
35
  @_timeouts = Array(@resolver_options[:timeouts])
36
36
  @timeouts = Hash.new { |timeouts, host| timeouts[host] = @_timeouts.dup }
@@ -103,7 +103,7 @@ module HTTPX
103
103
  @timeouts.values_at(*hosts).reject(&:empty?).map(&:first).min
104
104
  end
105
105
 
106
- def raise_timeout_error(interval)
106
+ def handle_socket_timeout(interval)
107
107
  do_retry(interval)
108
108
  end
109
109
 
@@ -92,7 +92,7 @@ module HTTPX
92
92
  resolve
93
93
  end
94
94
 
95
- def raise_timeout_error(interval)
95
+ def handle_socket_timeout(interval)
96
96
  error = HTTPX::ResolveTimeoutError.new(interval, "timed out while waiting on select")
97
97
  error.set_backtrace(caller)
98
98
  on_error(error)
@@ -1,19 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
+ # Implementation of the HTTP Response body as a buffer which implements the IO writer protocol
5
+ # (for buffering the response payload), the IO reader protocol (for consuming the response payload),
6
+ # and can be iterated over (via #each, which yields the payload in chunks).
4
7
  class Response::Body
5
- attr_reader :encoding, :encodings
8
+ # the payload encoding (i.e. "utf-8", "ASCII-8BIT")
9
+ attr_reader :encoding
6
10
 
11
+ # Array of encodings contained in the response "content-encoding" header.
12
+ attr_reader :encodings
13
+
14
+ # initialized with the corresponding HTTPX::Response +response+ and HTTPX::Options +options+.
7
15
  def initialize(response, options)
8
16
  @response = response
9
17
  @headers = response.headers
10
18
  @options = options
11
- @threshold_size = options.body_threshold_size
12
19
  @window_size = options.window_size
13
20
  @encoding = response.content_type.charset || Encoding::BINARY
14
21
  @encodings = []
15
22
  @length = 0
16
23
  @buffer = nil
24
+ @reader = nil
17
25
  @state = :idle
18
26
  initialize_inflaters
19
27
  end
@@ -28,6 +36,8 @@ module HTTPX
28
36
  @state == :closed
29
37
  end
30
38
 
39
+ # write the response payload +chunk+ into the buffer. Inflates the chunk when required
40
+ # and supported.
31
41
  def write(chunk)
32
42
  return if @state == :closed
33
43
 
@@ -44,6 +54,7 @@ module HTTPX
44
54
  size
45
55
  end
46
56
 
57
+ # reads a chunk from the payload (implementation of the IO reader protocol).
47
58
  def read(*args)
48
59
  return unless @buffer
49
60
 
@@ -55,10 +66,13 @@ module HTTPX
55
66
  @reader.read(*args)
56
67
  end
57
68
 
69
+ # size of the decoded response payload. May differ from "content-length" header if
70
+ # response was encoded over-the-wire.
58
71
  def bytesize
59
72
  @length
60
73
  end
61
74
 
75
+ # yields the payload in chunks.
62
76
  def each
63
77
  return enum_for(__method__) unless block_given?
64
78
 
@@ -74,12 +88,14 @@ module HTTPX
74
88
  end
75
89
  end
76
90
 
91
+ # returns the declared filename in the "contennt-disposition" header, when present.
77
92
  def filename
78
93
  return unless @headers.key?("content-disposition")
79
94
 
80
95
  Utils.get_filename(@headers["content-disposition"])
81
96
  end
82
97
 
98
+ # returns the full response payload as a string.
83
99
  def to_s
84
100
  return "".b unless @buffer
85
101
 
@@ -88,10 +104,16 @@ module HTTPX
88
104
 
89
105
  alias_method :to_str, :to_s
90
106
 
107
+ # whether the payload is empty.
91
108
  def empty?
92
109
  @length.zero?
93
110
  end
94
111
 
112
+ # copies the payload to +dest+.
113
+ #
114
+ # body.copy_to("path/to/file")
115
+ # body.copy_to(Pathname.new("path/to/file"))
116
+ # body.copy_to(File.new("path/to/file"))
95
117
  def copy_to(dest)
96
118
  return unless @buffer
97
119
 
@@ -132,6 +154,7 @@ module HTTPX
132
154
  end
133
155
  # :nocov:
134
156
 
157
+ # rewinds the response payload buffer.
135
158
  def rewind
136
159
  return unless @buffer
137
160
 
@@ -144,6 +167,8 @@ module HTTPX
144
167
  private
145
168
 
146
169
  def initialize_inflaters
170
+ @inflaters = nil
171
+
147
172
  return unless @headers.key?("content-encoding")
148
173
 
149
174
  return unless @options.decompress_response_body
@@ -168,7 +193,7 @@ module HTTPX
168
193
  return unless @state == :idle
169
194
 
170
195
  @buffer = Response::Buffer.new(
171
- threshold_size: @threshold_size,
196
+ threshold_size: @options.body_threshold_size,
172
197
  bytesize: @length,
173
198
  encoding: @encoding
174
199
  )
@@ -179,7 +204,7 @@ module HTTPX
179
204
  @state = nextstate
180
205
  end
181
206
 
182
- def _with_same_buffer_pos
207
+ def _with_same_buffer_pos # :nodoc:
183
208
  return yield unless @buffer && @buffer.respond_to?(:pos)
184
209
 
185
210
  # @type ivar @buffer: StringIO | Tempfile
@@ -193,7 +218,7 @@ module HTTPX
193
218
  end
194
219
 
195
220
  class << self
196
- def initialize_inflater_by_encoding(encoding, response, **kwargs)
221
+ def initialize_inflater_by_encoding(encoding, response, **kwargs) # :nodoc:
197
222
  case encoding
198
223
  when "gzip"
199
224
  Transcoder::GZIP.decode(response, **kwargs)
@@ -5,12 +5,15 @@ require "stringio"
5
5
  require "tempfile"
6
6
 
7
7
  module HTTPX
8
+ # wraps and delegates to an internal buffer, which can be a StringIO or a Tempfile.
8
9
  class Response::Buffer < SimpleDelegator
10
+ # initializes buffer with the +threshold_size+ over which the payload gets buffer to a tempfile,
11
+ # the initial +bytesize+, and the +encoding+.
9
12
  def initialize(threshold_size:, bytesize: 0, encoding: Encoding::BINARY)
10
13
  @threshold_size = threshold_size
11
14
  @bytesize = bytesize
12
15
  @encoding = encoding
13
- try_upgrade_buffer
16
+ @buffer = StringIO.new("".b)
14
17
  super(@buffer)
15
18
  end
16
19
 
@@ -20,16 +23,19 @@ module HTTPX
20
23
  @buffer = other.instance_variable_get(:@buffer).dup
21
24
  end
22
25
 
26
+ # size in bytes of the buffered content.
23
27
  def size
24
28
  @bytesize
25
29
  end
26
30
 
31
+ # writes the +chunk+ into the buffer.
27
32
  def write(chunk)
28
33
  @bytesize += chunk.bytesize
29
34
  try_upgrade_buffer
30
35
  @buffer.write(chunk)
31
36
  end
32
37
 
38
+ # returns the buffered content as a string.
33
39
  def to_s
34
40
  case @buffer
35
41
  when StringIO
@@ -49,6 +55,7 @@ module HTTPX
49
55
  end
50
56
  end
51
57
 
58
+ # closes the buffer.
52
59
  def close
53
60
  @buffer.close
54
61
  @buffer.unlink if @buffer.respond_to?(:unlink)
@@ -56,28 +63,27 @@ module HTTPX
56
63
 
57
64
  private
58
65
 
66
+ # initializes the buffer into a StringIO, or turns it into a Tempfile when the threshold
67
+ # has been reached.
59
68
  def try_upgrade_buffer
60
- if !@buffer.is_a?(Tempfile) && @bytesize > @threshold_size
61
- aux = @buffer
62
-
63
- @buffer = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
69
+ return unless @bytesize > @threshold_size
64
70
 
65
- if aux
66
- aux.rewind
67
- ::IO.copy_stream(aux, @buffer)
68
- aux.close
69
- end
71
+ return if @buffer.is_a?(Tempfile)
70
72
 
71
- else
72
- return if @buffer
73
+ aux = @buffer
73
74
 
74
- @buffer = StringIO.new("".b)
75
+ @buffer = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
75
76
 
77
+ if aux
78
+ aux.rewind
79
+ ::IO.copy_stream(aux, @buffer)
80
+ aux.close
76
81
  end
82
+
77
83
  __setobj__(@buffer)
78
84
  end
79
85
 
80
- def _with_same_buffer_pos
86
+ def _with_same_buffer_pos # :nodoc:
81
87
  current_pos = @buffer.pos
82
88
  @buffer.rewind
83
89
  begin
@@ -7,24 +7,48 @@ require "fileutils"
7
7
  require "forwardable"
8
8
 
9
9
  module HTTPX
10
+ # Defines a HTTP response is handled internally, with a few properties exposed as attributes,
11
+ # implements (indirectly, via the +body+) the IO write protocol to internally buffer payloads,
12
+ # implements the IO reader protocol in order for users to buffer/stream it, acts as an enumerable
13
+ # (of payload chunks).
10
14
  class Response
11
15
  extend Forwardable
12
16
  include Callbacks
13
17
 
14
- attr_reader :status, :headers, :body, :version
18
+ # the HTTP response status code
19
+ attr_reader :status
15
20
 
21
+ # an HTTPX::Headers object containing the response HTTP headers.
22
+ attr_reader :headers
23
+
24
+ # a HTTPX::Response::Body object wrapping the response body.
25
+ attr_reader :body
26
+
27
+ # The HTTP protocol version used to fetch the response.
28
+ attr_reader :version
29
+
30
+ # returns the response body buffered in a string.
16
31
  def_delegator :@body, :to_s
17
32
 
18
33
  def_delegator :@body, :to_str
19
34
 
35
+ # implements the IO reader +#read+ interface.
20
36
  def_delegator :@body, :read
21
37
 
38
+ # copies the response body to a different location.
22
39
  def_delegator :@body, :copy_to
23
40
 
41
+ # closes the body.
24
42
  def_delegator :@body, :close
25
43
 
44
+ # the corresponding request uri.
26
45
  def_delegator :@request, :uri
27
46
 
47
+ # the IP address of the peer server.
48
+ def_delegator :@request, :peer_address
49
+
50
+ # inits the instance with the corresponding +request+ to this response, an the
51
+ # response HTTP +status+, +version+ and HTTPX::Headers instance of +headers+.
28
52
  def initialize(request, status, version, headers)
29
53
  @request = request
30
54
  @options = request.options
@@ -33,32 +57,49 @@ module HTTPX
33
57
  @headers = @options.headers_class.new(headers)
34
58
  @body = @options.response_body_class.new(self, @options)
35
59
  @finished = complete?
60
+ @content_type = nil
36
61
  end
37
62
 
63
+ # merges headers defined in +h+ into the response headers.
38
64
  def merge_headers(h)
39
65
  @headers = @headers.merge(h)
40
66
  end
41
67
 
68
+ # writes +data+ chunk into the response body.
42
69
  def <<(data)
43
70
  @body.write(data)
44
71
  end
45
72
 
73
+ # returns the response mime type, as per what's declared in the content-type header.
74
+ #
75
+ # response.content_type #=> "text/plain"
46
76
  def content_type
47
77
  @content_type ||= ContentType.new(@headers["content-type"])
48
78
  end
49
79
 
80
+ # returns whether the response has been fully fetched.
50
81
  def finished?
51
82
  @finished
52
83
  end
53
84
 
85
+ # marks the response as finished, freezes the headers.
54
86
  def finish!
55
87
  @finished = true
56
88
  @headers.freeze
57
89
  end
58
90
 
91
+ # returns whether the response contains body payload.
59
92
  def bodyless?
60
93
  @request.verb == "HEAD" ||
61
- no_data?
94
+ @status < 200 || # informational response
95
+ @status == 204 ||
96
+ @status == 205 ||
97
+ @status == 304 || begin
98
+ content_length = @headers["content-length"]
99
+ return false if content_length.nil?
100
+
101
+ content_length == "0"
102
+ end
62
103
  end
63
104
 
64
105
  def complete?
@@ -75,32 +116,53 @@ module HTTPX
75
116
  end
76
117
  # :nocov:
77
118
 
119
+ # returns an instance of HTTPX::HTTPError if the response has a 4xx or 5xx
120
+ # status code, or nothing.
121
+ #
122
+ # ok_response.error #=> nil
123
+ # not_found_response.error #=> HTTPX::HTTPError instance, status 404
78
124
  def error
79
125
  return if @status < 400
80
126
 
81
127
  HTTPError.new(self)
82
128
  end
83
129
 
130
+ # it raises the exception returned by +error+, or itself otherwise.
131
+ #
132
+ # ok_response.raise_for_status #=> ok_response
133
+ # not_found_response.raise_for_status #=> raises HTTPX::HTTPError exception
84
134
  def raise_for_status
85
135
  return self unless (err = error)
86
136
 
87
137
  raise err
88
138
  end
89
139
 
140
+ # decodes the response payload into a ruby object **if** the payload is valid json.
141
+ #
142
+ # response.json #≈> { "foo" => "bar" } for "{\"foo\":\"bar\"}" payload
143
+ # response.json(symbolize_names: true) #≈> { foo: "bar" } for "{\"foo\":\"bar\"}" payload
90
144
  def json(*args)
91
145
  decode(Transcoder::JSON, *args)
92
146
  end
93
147
 
148
+ # decodes the response payload into a ruby object **if** the payload is valid
149
+ # "application/x-www-urlencoded" or "multipart/form-data".
94
150
  def form
95
151
  decode(Transcoder::Form)
96
152
  end
97
153
 
154
+ # decodes the response payload into a Nokogiri::XML::Node object **if** the payload is valid
155
+ # "application/xml" (requires the "nokogiri" gem).
98
156
  def xml
99
157
  decode(Transcoder::Xml)
100
158
  end
101
159
 
102
160
  private
103
161
 
162
+ # decodes the response payload using the given +transcoder+, which implements the decoding logic.
163
+ #
164
+ # +transcoder+ must implement the internal transcoder API, i.e. respond to <tt>decode(HTTPX::Response response)</tt>,
165
+ # which returns a decoder which responds to <tt>call(HTTPX::Response response, **kwargs)</tt>
104
166
  def decode(transcoder, *args)
105
167
  # TODO: check if content-type is a valid format, i.e. "application/json" for json parsing
106
168
 
@@ -112,20 +174,9 @@ module HTTPX
112
174
 
113
175
  decoder.call(self, *args)
114
176
  end
115
-
116
- def no_data?
117
- @status < 200 || # informational response
118
- @status == 204 ||
119
- @status == 205 ||
120
- @status == 304 || begin
121
- content_length = @headers["content-length"]
122
- return false if content_length.nil?
123
-
124
- content_length == "0"
125
- end
126
- end
127
177
  end
128
178
 
179
+ # Helper class which decodes the HTTP "content-type" header.
129
180
  class ContentType
130
181
  MIME_TYPE_RE = %r{^([^/]+/[^;]+)(?:$|;)}.freeze
131
182
  CHARSET_RE = /;\s*charset=([^;]+)/i.freeze
@@ -134,6 +185,9 @@ module HTTPX
134
185
  @header_value = header_value
135
186
  end
136
187
 
188
+ # returns the mime type declared in the header.
189
+ #
190
+ # ContentType.new("application/json; charset=utf-8").mime_type #=> "application/json"
137
191
  def mime_type
138
192
  return @mime_type if defined?(@mime_type)
139
193
 
@@ -141,6 +195,10 @@ module HTTPX
141
195
  m && @mime_type = m.strip.downcase
142
196
  end
143
197
 
198
+ # returns the charset declared in the header.
199
+ #
200
+ # ContentType.new("application/json; charset=utf-8").charset #=> "utf-8"
201
+ # ContentType.new("text/plain").charset #=> nil
144
202
  def charset
145
203
  return @charset if defined?(@charset)
146
204
 
@@ -149,14 +207,31 @@ module HTTPX
149
207
  end
150
208
  end
151
209
 
210
+ # Wraps an error which has happened while processing an HTTP Request. It has partial
211
+ # public API parity with HTTPX::Response, so users should rely on it to infer whether
212
+ # the returned response is one or the other.
213
+ #
214
+ # response = HTTPX.get("https://some-domain/path") #=> response is HTTPX::Response or HTTPX::ErrorResponse
215
+ # response.raise_for_status #=> raises if it wraps an error
152
216
  class ErrorResponse
153
217
  include Loggable
154
218
  extend Forwardable
155
219
 
156
- attr_reader :request, :response, :error
220
+ # the corresponding HTTPX::Request instance.
221
+ attr_reader :request
157
222
 
223
+ # the HTTPX::Response instance, when there is one (i.e. error happens fetching the response).
224
+ attr_reader :response
225
+
226
+ # the wrapped exception.
227
+ attr_reader :error
228
+
229
+ # the request uri
158
230
  def_delegator :@request, :uri
159
231
 
232
+ # the IP address of the peer server.
233
+ def_delegator :@request, :peer_address
234
+
160
235
  def initialize(request, error, options)
161
236
  @request = request
162
237
  @response = request.response if request.response.is_a?(Response)
@@ -165,18 +240,22 @@ module HTTPX
165
240
  log_exception(@error)
166
241
  end
167
242
 
243
+ # returns the exception full message.
168
244
  def to_s
169
245
  @error.full_message(highlight: false)
170
246
  end
171
247
 
248
+ # closes the error resources.
172
249
  def close
173
- @response.close if @response.respond_to?(:close)
250
+ @response.close if @response && @response.respond_to?(:close)
174
251
  end
175
252
 
253
+ # always true for error responses.
176
254
  def finished?
177
255
  true
178
256
  end
179
257
 
258
+ # raises the wrapped exception.
180
259
  def raise_for_status
181
260
  raise @error
182
261
  end
@@ -73,7 +73,7 @@ class HTTPX::Selector
73
73
  readers, writers = IO.select(r, w, nil, interval)
74
74
 
75
75
  if readers.nil? && writers.nil? && interval
76
- [*r, *w].each { |io| io.raise_timeout_error(interval) }
76
+ [*r, *w].each { |io| io.handle_socket_timeout(interval) }
77
77
  return
78
78
  end
79
79
  rescue IOError, SystemCallError
@@ -110,7 +110,7 @@ class HTTPX::Selector
110
110
  end
111
111
 
112
112
  unless result || interval.nil?
113
- io.raise_timeout_error(interval)
113
+ io.handle_socket_timeout(interval)
114
114
  return
115
115
  end
116
116
  # raise HTTPX::TimeoutError.new(interval, "timed out while waiting on select")