httpx 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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