httpx 0.3.0 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bed8cbd465eb9d1b565024395767f619aaaff1bf2ee35d33dc15e9fe4eeec13e
4
- data.tar.gz: 65ac8fee9f8c773d6b9a7894e68641547f75ee69159f01e60c8cdc1f30b648f0
3
+ metadata.gz: 52b8402031b6deeed1d1a5c92c56e1cc8d93cae1da650d3573ddca712a413948
4
+ data.tar.gz: b2c2528c1a187eb0cdfe72636eebf6a390a240e86b78e9ebed2b81f26f3f1c89
5
5
  SHA512:
6
- metadata.gz: 1e891362a86b73f6d2670eb14a1fd0815a0fab0173f6adf58bdb8e8225d83012560492c5563291d10d03e05ab9e2d9c786ba0cc238e886832276639bab06a8aa
7
- data.tar.gz: 539853ff0c6ca209f32d56b8f5eb6209ef60a4df02f0073a588b915a5a583753b7bebe66cd91b76e599a55bb214c6d56a9d1a4d47d6d7a4d5ea2e9b18254af3c
6
+ metadata.gz: '0837f66f56ca695dbc89e9d1557703dba32d74c0748c246f3d94b5fa4baaf13b50a931c8dd018a8c6d4ec80324aac7c164c271be5d9a50afe573c7316e6bf751'
7
+ data.tar.gz: ee65a86527d020d422e68d1b5972f11d7ce710267ae4ba31d6bd7d42f6966fa606ddfdf9d4a788175516d2c7a5a857000ab0980d5762667236e8e9e2ef13ce12
@@ -61,7 +61,7 @@ module HTTPX
61
61
  channel.on(:reset) do
62
62
  @timeout.transition(:idle)
63
63
  end
64
- channel.once(:unreachable) do
64
+ channel.on(:unreachable) do
65
65
  @resolver.uncache(channel)
66
66
  resolve_channel(channel)
67
67
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "resolv"
4
+
3
5
  module HTTPX
4
6
  module Resolver
5
7
  autoload :ResolverMixin, "httpx/resolver/resolver_mixin"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "resolv"
3
4
  require "uri"
4
5
  require "cgi"
5
6
  require "forwardable"
@@ -67,13 +68,17 @@ module HTTPX
67
68
  def resolve(channel = @channels.first, hostname = nil)
68
69
  return if @building_channel
69
70
  hostname = hostname || @queries.key(channel) || channel.uri.host
70
- type = @_record_types[hostname].shift
71
+ type = @_record_types[hostname].first
71
72
  log(label: "resolver: ") { "query #{type} for #{hostname}" }
72
- request = build_request(hostname, type)
73
- @requests[request] = channel
74
- resolver_channel.send(request)
75
- @queries[hostname] = channel
76
- @channels << channel
73
+ begin
74
+ request = build_request(hostname, type)
75
+ @requests[request] = channel
76
+ resolver_channel.send(request)
77
+ @queries[hostname] = channel
78
+ @channels << channel
79
+ rescue Resolv::DNS::EncodeError, JSON::JSONError => e
80
+ emit_resolve_error(channel, hostname, e)
81
+ end
77
82
  end
78
83
 
79
84
  def find_channel(_request, **options)
@@ -107,10 +112,20 @@ module HTTPX
107
112
  end
108
113
 
109
114
  def parse(response)
110
- answers = decode_response_body(response)
115
+ answers = begin
116
+ decode_response_body(response)
117
+ rescue Resolv::DNS::DecodeError, JSON::JSONError => e
118
+ host, channel = @queries.first
119
+ if @_record_types[host].empty?
120
+ emit_resolve_error(channel, host, e)
121
+ return
122
+ end
123
+ end
111
124
  if answers.empty?
112
125
  host, channel = @queries.first
126
+ @_record_types[host].shift
113
127
  if @_record_types[host].empty?
128
+ @_record_types.delete(host)
114
129
  emit_resolve_error(channel, host)
115
130
  return
116
131
  end
@@ -173,7 +188,6 @@ module HTTPX
173
188
  when "application/dns-udpwireformat",
174
189
  "application/dns-message"
175
190
  Resolver.decode_dns_answer(response.to_s)
176
-
177
191
  # TODO: what about the rest?
178
192
  end
179
193
  end
@@ -81,9 +81,9 @@ module HTTPX
81
81
  if @ns_index < @nameserver.size
82
82
  transition(:idle)
83
83
  else
84
- ex = ResolvError.new(e.message)
85
- ex.set_backtrace(e.backtrace)
86
- raise ex
84
+ @queries.each do |host, channel|
85
+ emit_resolve_error(channel, host, e)
86
+ end
87
87
  end
88
88
  end
89
89
 
@@ -100,7 +100,7 @@ module HTTPX
100
100
  def <<(channel)
101
101
  return if early_resolve(channel)
102
102
  if @nameserver.nil?
103
- ex = ResolveError.new("Can't resolve #{channel.uri.host}")
103
+ ex = ResolveError.new("Can't resolve #{channel.uri.host}: no nameserver")
104
104
  ex.set_backtrace(caller)
105
105
  emit(:error, channel, ex)
106
106
  else
@@ -178,10 +178,21 @@ module HTTPX
178
178
  end
179
179
 
180
180
  def parse(buffer)
181
- addresses = Resolver.decode_dns_answer(buffer)
181
+ addresses = begin
182
+ Resolver.decode_dns_answer(buffer)
183
+ rescue Resolv::DNS::DecodeError => e
184
+ hostname, channel = @queries.first
185
+ if @_record_types[hostname].empty?
186
+ emit_resolve_error(channel, hostname, e)
187
+ return
188
+ end
189
+ end
190
+
182
191
  if addresses.empty?
183
192
  hostname, channel = @queries.first
193
+ @_record_types[hostname].shift
184
194
  if @_record_types[hostname].empty?
195
+ @_record_types.delete(hostname)
185
196
  emit_resolve_error(channel, hostname)
186
197
  return
187
198
  end
@@ -212,9 +223,13 @@ module HTTPX
212
223
  return unless @write_buffer.empty?
213
224
  hostname = hostname || @queries.key(channel) || channel.uri.host
214
225
  @queries[hostname] = channel
215
- type = @_record_types[hostname].shift
226
+ type = @_record_types[hostname].first
216
227
  log(label: "resolver: ") { "query #{type} for #{hostname}" }
217
- @write_buffer << Resolver.encode_dns_query(hostname, type: RECORD_TYPES[type])
228
+ begin
229
+ @write_buffer << Resolver.encode_dns_query(hostname, type: RECORD_TYPES[type])
230
+ rescue Resolv::DNS::EncodeError => e
231
+ emit_resolve_error(channel, hostname, e)
232
+ end
218
233
  end
219
234
 
220
235
  def build_socket
@@ -21,6 +21,7 @@ module HTTPX
21
21
  def uncache(channel)
22
22
  hostname = hostname || @queries.key(channel) || channel.uri.host
23
23
  Resolver.uncache(hostname)
24
+ @_record_types[hostname].shift
24
25
  end
25
26
 
26
27
  private
@@ -51,9 +52,10 @@ module HTTPX
51
52
  ips.map { |ip| IPAddr.new(ip) }
52
53
  end
53
54
 
54
- def emit_resolve_error(channel, hostname)
55
- error = ResolveError.new("Can't resolve #{hostname}")
56
- error.set_backtrace(caller)
55
+ def emit_resolve_error(channel, hostname, ex = nil)
56
+ message = ex ? ex.message : "Can't resolve #{hostname}"
57
+ error = ResolveError.new(message)
58
+ error.set_backtrace(ex ? ex.backtrace : caller)
57
59
  emit(:error, channel, error)
58
60
  end
59
61
  end
@@ -7,6 +7,11 @@ module HTTPX
7
7
  class Resolver::System
8
8
  include Resolver::ResolverMixin
9
9
 
10
+ RESOLV_ERRORS = [Resolv::ResolvError,
11
+ Resolv::DNS::Requester::RequestError,
12
+ Resolv::DNS::EncodeError,
13
+ Resolv::DNS::DecodeError].freeze
14
+
10
15
  def initialize(_, options)
11
16
  @options = Options.new(options)
12
17
  roptions = @options.resolver_options
@@ -26,7 +31,10 @@ module HTTPX
26
31
  def <<(channel)
27
32
  hostname = channel.uri.host
28
33
  addresses = ip_resolve(hostname) || system_resolve(hostname) || @resolver.getaddresses(hostname)
29
- addresses.empty? ? emit_resolve_error(channel, hostname) : emit_addresses(channel, addresses)
34
+ return emit_resolve_error(channel, hostname) if addresses.empty?
35
+ emit_addresses(channel, addresses)
36
+ rescue Errno::EHOSTUNREACH, *RESOLV_ERRORS => e
37
+ emit_resolve_error(channel, hostname, e)
30
38
  end
31
39
 
32
40
  def uncache(*); end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
11
+ date: 2018-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2