nethttputils 0.2.5.1 → 0.3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nethttputils.rb +260 -222
  3. data/nethttputils.gemspec +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 269ae22d3a1414546520372460907dadc16eb58f
4
- data.tar.gz: eefba89631efce4b2e0bd77ffa2cccaf18fc731a
3
+ metadata.gz: 9a9df743f10c31c23bbbcc076750dcea63f50133
4
+ data.tar.gz: 503c63e39858d28602a042701187a4f08404d349
5
5
  SHA512:
6
- metadata.gz: 891dbd459995733d28bd6acfd8203d73c72993b944847f4358ca74c10339eb6ddc9dbea4cc363739bf2aa39ba077be82cee8fe52b679645123e65bc1a63b7aa3
7
- data.tar.gz: 0e444a896a600b407b479babebe8367069251d85eec796b864550c964e31df2f9f134b003866e535ba6de559cbdd9ee8f50c737669e544af5486cb2c106fe89e
6
+ metadata.gz: 6d88ded5499b3aaddfbd187eb185099d6de32d2e78f941ab6f95ed3db7a4a5f2d5fe4b134c267bd85cbc2199aba15fec6873f2fc8b13eed184e1d4fe566d1acf
7
+ data.tar.gz: '006529bc8770f5c149572528fe0050a69755f0b2db8efbb76ec2e2fb324e198ce4f7cf176d2e04f9d6a461d1a3d07b74badc85ee96765c01889a86e7f22b2ddd'
data/lib/nethttputils.rb CHANGED
@@ -30,244 +30,262 @@ module NetHTTPUtils
30
30
  gsub(/<[^>]*>/, "").split(?\n).map(&:strip).reject(&:empty?).join(?\n)
31
31
  end
32
32
 
33
- # TODO: make it private?
34
- def get_response url, mtd = :GET, type = :form, form: {}, header: {}, auth: nil, timeout: 30, max_timeout_retry_delay: 3600, max_sslerror_retry_delay: 3600, max_read_retry_delay: 3600, max_econnrefused_retry_delay: 3600, max_socketerror_retry_delay: 3600, patch_request: nil, &block
33
+ def start_http url, timeout = 30, max_start_http_retry_delay = 3600
34
+ fail if url.is_a? URI::HTTP
35
35
  uri = url
36
36
  uri = URI.parse begin
37
37
  URI url
38
38
  url
39
39
  rescue URI::InvalidURIError
40
40
  URI.escape url
41
- end unless url.is_a? URI::HTTP
41
+ end
42
+ delay = 5
43
+ begin
44
+ Net::HTTP.start(
45
+ uri.host, uri.port,
46
+ use_ssl: uri.scheme == "https",
47
+ verify_mode: OpenSSL::SSL::VERIFY_NONE,
48
+ **({open_timeout: timeout}), # if timeout
49
+ **({read_timeout: timeout}), # if timeout
50
+ ) do |http|
51
+ # http.open_timeout = timeout # seems like when opening hangs, this line in unreachable
52
+ # http.read_timeout = timeout
53
+ http.set_debug_output( Object.new.tap do |obj|
54
+ obj.instance_eval do
55
+ def << msg
56
+ @@buffer ||= "[Net::HTTP debug] "
57
+ @@buffer.concat msg
58
+ @@buffer = @@buffer[0...997] + "..." if @@buffer.size > 500
59
+ return unless @@buffer.end_with? ?\n
60
+ NetHTTPUtils.logger.debug @@buffer.sub ?\n, " "
61
+ @@buffer = nil
62
+ end
63
+ end
64
+ end ) if logger.level == Logger::DEBUG # use `logger.debug?`?
65
+ http
66
+ end
67
+ rescue Errno::ECONNREFUSED => e
68
+ if max_start_http_retry_delay < delay *= 2
69
+ e.message.concat " to #{uri}"
70
+ raise
71
+ end
72
+ logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}'"
73
+ sleep delay
74
+ retry
75
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNRESET => e
76
+ logger.warn "retrying in 5 seconds because of #{e.class} '#{e.message}'"
77
+ sleep 5
78
+ retry
79
+ rescue SocketError => e
80
+ if max_start_http_retry_delay < delay *= 2
81
+ e.message.concat " to #{uri}"
82
+ raise e
83
+ end
84
+ logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
85
+ sleep delay
86
+ retry
87
+ rescue Errno::ETIMEDOUT, Net::OpenTimeout => e
88
+ raise if max_start_http_retry_delay < delay *= 2
89
+ logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
90
+ sleep delay
91
+ retry
92
+ rescue OpenSSL::SSL::SSLError => e
93
+ raise if max_start_http_retry_delay < delay *= 2
94
+ logger.error "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
95
+ sleep delay
96
+ retry
97
+ end.tap do |http|
98
+ http.instance_variable_set "@uri", uri
99
+ http.define_singleton_method :read do |mtd = :GET, type = :form, form: {}, header: {}, auth: nil, timeout: 30,
100
+ max_read_retry_delay: 3600,
101
+ patch_request: nil,
102
+ &block|
42
103
 
43
- logger.warn "Warning: query params included in `url` argument are discarded because `:form` isn't empty" if uri.query && !form.empty?
44
- # we can't just merge because URI fails to parse such queries as "/?1"
104
+ logger = NetHTTPUtils.logger
45
105
 
46
- uri.query = URI.encode_www_form form if :GET == (mtd = mtd.upcase) && !form.empty?
47
- cookies = {}
48
- prepare_request = lambda do |uri, mtd = :GET, form = {}|
49
- case mtd.upcase
50
- when :GET ; Net::HTTP::Get
51
- when :POST ; Net::HTTP::Post
52
- when :PUT ; Net::HTTP::Put
53
- when :DELETE ; Net::HTTP::Delete
54
- when :PATCH ; Net::HTTP::Patch
55
- else ; raise "unknown method '#{mtd}'"
56
- end.new(uri).tap do |request| # somehow Get eats even raw url, not URI object
57
- patch_request.call uri, form, request if patch_request
58
- request.basic_auth *auth if auth
59
- # pp Object.instance_method(:method).bind(request).call(:set_form).source_location
60
- if (mtd == :POST || mtd == :PATCH) && !form.empty?
61
- case type
62
- when :json ; request.body = JSON.dump form
63
- request.content_type = "application/json"
64
- when :form ; if form.any?{ |k, v| v.respond_to? :to_path }
65
- request.set_form form, "multipart/form-data"
66
- else
67
- request.set_form_data form
68
- request.content_type = "application/x-www-form-urlencoded;charset=UTF-8"
69
- end
70
- else ; raise "unknown content-type '#{type}'"
71
- end
72
- end
73
- header.each{ |k, v| request[k.to_s] = v }
74
- request["cookie"] = [*request["cookie"], cookies.map{ |k, v| "#{k}=#{v}" }].join "; " unless cookies.empty?
106
+ logger.warn "Warning: query params included in `url` argument are discarded because `:form` isn't empty" if uri.query && !form.empty?
107
+ # we can't just merge because URI fails to parse such queries as "/?1"
75
108
 
76
- logger.info "> #{request.class} #{uri.host} #{request.path}"
77
- next unless logger.debug?
78
- logger.debug "content-type: #{request.content_type}" unless mtd == :GET
79
- curl_form = case request.content_type
80
- when "application/json" ; "-d #{JSON.dump form} "
81
- when "multipart/form-data" ; form.map{ |k, v| "-F \"#{k}=#{v.respond_to?(:to_path) ? "@#{v.to_path}" : v}\" " }.join
82
- when "application/x-www-form-urlencoded" ; "-d \"#{URI.encode_www_form form}\" "
83
- else ; mtd == :GET ? "" : fail("unknown content-type '#{request.content_type}'")
84
- end
85
- logger.debug "curl -vsSL --compressed -o /dev/null #{
86
- request.each_header.map{ |k, v| "-H \"#{k}: #{v}\" " unless k == "host" }.join
87
- }#{curl_form}'#{url.gsub "&", "\\\\&"}#{"?#{uri.query}" if uri.query && uri.query.empty?}'"
88
- logger.debug "> header: #{request.each_header.to_a}"
89
- logger.debug "> body: #{request.body.inspect.tap{ |body| body[997..-1] = "..." if body.size > 500 }}"
90
- # TODO this is buggy -- mixes lines from different files into one line
91
- stack = caller.reverse.map do |level|
92
- /((?:[^\/:]+\/)?[^\/:]+):([^:]+)/.match(level).captures
93
- end.chunk(&:first).map do |file, group|
94
- "#{file}:#{group.map(&:last).chunk{|_|_}.map(&:first).join(",")}"
95
- end
96
- logger.debug stack.join " -> "
97
- end
98
- end
99
- start_http = lambda do |uri|
100
- delay = 5
101
- begin
102
- Net::HTTP.start(
103
- uri.host, uri.port,
104
- use_ssl: uri.scheme == "https",
105
- verify_mode: OpenSSL::SSL::VERIFY_NONE,
106
- **({open_timeout: timeout}), # if timeout
107
- **({read_timeout: timeout}), # if timeout
108
- ) do |http|
109
- # http.open_timeout = timeout # seems like when opening hangs, this line in unreachable
110
- # http.read_timeout = timeout
111
- http.set_debug_output( Object.new.tap do |obj|
112
- obj.instance_eval do
113
- def << msg
114
- @@buffer ||= "[Net::HTTP debug] "
115
- @@buffer.concat msg
116
- @@buffer = @@buffer[0...997] + "..." if @@buffer.size > 500
117
- return unless @@buffer.end_with? ?\n
118
- NetHTTPUtils.logger.debug @@buffer.sub ?\n, " "
119
- @@buffer = nil
109
+ uri.query = URI.encode_www_form form if :GET == (mtd = mtd.upcase) && !form.empty?
110
+ cookies = {}
111
+ prepare_request = lambda do |uri, mtd = :GET, form = {}|
112
+ case mtd.upcase
113
+ when :GET ; Net::HTTP::Get
114
+ when :POST ; Net::HTTP::Post
115
+ when :PUT ; Net::HTTP::Put
116
+ when :DELETE ; Net::HTTP::Delete
117
+ when :PATCH ; Net::HTTP::Patch
118
+ else ; raise "unknown method '#{mtd}'"
119
+ end.new(uri).tap do |request| # somehow Get eats even raw url, not URI object
120
+ patch_request.call uri, form, request if patch_request
121
+ # p Object.instance_method(:method).bind(request).call(:basic_auth).source_location
122
+ # p Object.instance_method(:method).bind(request).call(:set_form).source_location
123
+ # request.basic_auth *p(auth.map(&URI.method(:escape))) if auth
124
+ request.basic_auth *auth if auth
125
+ if (mtd == :POST || mtd == :PATCH) && !form.empty?
126
+ case type
127
+ when :json ; request.body = JSON.dump form
128
+ request.content_type = "application/json"
129
+ when :form ; if form.any?{ |k, v| v.respond_to? :to_path }
130
+ request.set_form form, "multipart/form-data"
131
+ else
132
+ request.set_form_data form
133
+ request.content_type = "application/x-www-form-urlencoded;charset=UTF-8"
134
+ end
135
+ else ; raise "unknown content-type '#{type}'"
120
136
  end
121
137
  end
122
- end ) if logger.level == Logger::DEBUG # use `logger.debug?`?
123
- http
124
- end
125
- rescue Errno::ECONNREFUSED => e
126
- if max_econnrefused_retry_delay < delay *= 2
127
- e.message.concat " to #{uri}"
128
- raise
129
- end
130
- logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}'"
131
- sleep delay
132
- retry
133
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNRESET => e
134
- logger.warn "retrying in 5 seconds because of #{e.class} '#{e.message}'"
135
- sleep 5
136
- retry
137
- rescue SocketError => e
138
- if max_socketerror_retry_delay < delay *= 2
139
- e.message.concat " to #{uri}"
140
- raise e
141
- end
142
- logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
143
- sleep delay
144
- retry
145
- rescue Errno::ETIMEDOUT, Net::OpenTimeout => e
146
- raise if max_timeout_retry_delay < delay *= 2
147
- logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
148
- sleep delay
149
- retry
150
- rescue OpenSSL::SSL::SSLError => e
151
- raise if max_sslerror_retry_delay < delay *= 2
152
- logger.error "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{uri}"
153
- sleep delay
154
- retry
155
- end
156
- end
157
- http = start_http[uri]
158
- do_request = lambda do |request|
159
- delay = 5
160
- response = begin
161
- http.request request, &block
162
- rescue Errno::ECONNREFUSED, Net::ReadTimeout, Net::OpenTimeout, Zlib::BufError, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e
163
- raise if max_read_retry_delay < delay *= 2
164
- logger.error "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{request.uri}"
165
- sleep delay
166
- retry
167
- end
168
- # response.instance_variable_set "@nethttputils_close", http.method(:finish)
169
- # response.singleton_class.instance_eval{ attr_accessor :nethttputils_socket_to_close }
138
+ header.each{ |k, v| request[k.to_s] = v }
139
+ request["cookie"] = [*request["cookie"], cookies.map{ |k, v| "#{k}=#{v}" }].join "; " unless cookies.empty?
170
140
 
171
- remaining, reset_time, current_timestamp = if response.key? "x-ratelimit-userremaining"
172
- logger.debug "x-ratelimit-clientremaining: #{response.fetch("x-ratelimit-clientremaining").to_i}"
173
- [
174
- response.fetch("x-ratelimit-userremaining").to_i,
175
- response.fetch("x-ratelimit-userreset").to_i,
176
- response.fetch("x-timer")[/\d+/].to_i,
177
- ]
178
- elsif response.key? "x-rate-limit-remaining"
179
- [
180
- response.fetch("x-rate-limit-remaining").to_i,
181
- response.fetch("x-rate-limit-reset").to_i,
182
- Time.now.to_i,
183
- ]
184
- end
185
- if remaining
186
- logger.debug "x-remaining: #{remaining}"
187
- if remaining <= 100
188
- t = (reset_time - current_timestamp + 1).fdiv remaining
189
- logger.warn "x-ratelimit sleep #{t} seconds"
190
- sleep t
141
+ logger.info "> #{request.class} #{uri.host} #{request.path}"
142
+ next unless logger.debug?
143
+ logger.debug "content-type: #{request.content_type}" unless mtd == :GET
144
+ curl_form = case request.content_type
145
+ when "application/json" ; "-d #{JSON.dump form} "
146
+ when "multipart/form-data" ; form.map{ |k, v| "-F \"#{k}=#{v.respond_to?(:to_path) ? "@#{v.to_path}" : v}\" " }.join
147
+ when "application/x-www-form-urlencoded" ; "-d \"#{URI.encode_www_form form}\" "
148
+ else ; mtd == :GET ? "" : fail("unknown content-type '#{request.content_type}'")
149
+ end
150
+ logger.debug "curl -vsSL --compressed -o /dev/null #{
151
+ request.each_header.map{ |k, v| "-H \"#{k}: #{v}\" " unless k == "host" }.join
152
+ }#{curl_form}'#{url.gsub "&", "\\\\&"}#{"?#{uri.query}" if uri.query && uri.query.empty?}'"
153
+ logger.debug "> header: #{request.each_header.to_a}"
154
+ logger.debug "> body: #{request.body.inspect.tap{ |body| body[997..-1] = "..." if body.size > 500 }}"
155
+ # TODO this is buggy -- mixes lines from different files into one line
156
+ stack = caller.reverse.map do |level|
157
+ /((?:[^\/:]+\/)?[^\/:]+):([^:]+)/.match(level).captures
158
+ end.chunk(&:first).map do |file, group|
159
+ "#{file}:#{group.map(&:last).chunk{|_|_}.map(&:first).join(",")}"
160
+ end
161
+ logger.debug stack.join " -> "
162
+ end
191
163
  end
192
- end
164
+ http = NetHTTPUtils.start_http url, timeout, max_start_http_retry_delay
165
+ do_request = lambda do |request|
166
+ delay = 5
167
+ response = begin
168
+ http.request request, &block
169
+ rescue Errno::ECONNREFUSED, Net::ReadTimeout, Net::OpenTimeout, Zlib::BufError, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e
170
+ raise if max_read_retry_delay < delay *= 2
171
+ logger.error "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{request.uri}"
172
+ sleep delay
173
+ retry
174
+ end
175
+ # response.instance_variable_set "@nethttputils_close", http.method(:finish)
176
+ # response.singleton_class.instance_eval{ attr_accessor :nethttputils_socket_to_close }
193
177
 
194
- response.to_hash.fetch("set-cookie", []).each do |c|
195
- k, v = c.split(?=)
196
- logger.debug "set-cookie: #{k}=#{v[/[^;]+/]}"
197
- cookies.store k, v[/[^;]+/]
198
- end
199
- logger.debug "< header: #{response.to_hash}"
200
- case response.code
201
- when /\A3\d\d\z/
202
- logger.info "redirect: #{response["location"]}"
203
- new_uri = URI.join request.uri, URI.escape(response["location"])
204
- new_host = new_uri.host
205
- if http.address != new_host ||
206
- http.port != new_uri.port ||
207
- http.use_ssl? != (new_uri.scheme == "https")
208
- logger.debug "changing host from '#{http.address}' to '#{new_host}'"
209
- # http.finish
210
- http = start_http[new_uri]
211
- end
212
- do_request.call prepare_request[new_uri]
213
- when "404"
214
- logger.error "404 at #{request.method} #{request.uri} with body: #{
215
- if response.body.is_a? Net::ReadAdapter
216
- "impossible to reread Net::ReadAdapter -- check the IO you've used in block form"
217
- elsif response.to_hash["content-type"] == ["image/png"]
218
- response.to_hash["content-type"].to_s
178
+ remaining, reset_time, current_timestamp = if response.key? "x-ratelimit-userremaining"
179
+ logger.debug "x-ratelimit-clientremaining: #{response.fetch("x-ratelimit-clientremaining").to_i}"
180
+ [
181
+ response.fetch("x-ratelimit-userremaining").to_i,
182
+ response.fetch("x-ratelimit-userreset").to_i,
183
+ response.fetch("x-timer")[/\d+/].to_i,
184
+ ]
185
+ elsif response.key? "x-rate-limit-remaining"
186
+ [
187
+ response.fetch("x-rate-limit-remaining").to_i,
188
+ response.fetch("x-rate-limit-reset").to_i,
189
+ Time.now.to_i,
190
+ ]
191
+ end
192
+ if remaining
193
+ logger.debug "x-remaining: #{remaining}"
194
+ if remaining <= 100
195
+ t = (reset_time - current_timestamp + 1).fdiv remaining
196
+ logger.warn "x-ratelimit sleep #{t} seconds"
197
+ sleep t
198
+ end
199
+ end
200
+
201
+ response.to_hash.fetch("set-cookie", []).each do |c|
202
+ k, v = c.split(?=)
203
+ logger.debug "set-cookie: #{k}=#{v[/[^;]+/]}"
204
+ cookies.store k, v[/[^;]+/]
205
+ end
206
+ logger.debug "< header: #{response.to_hash}"
207
+ case response.code
208
+ when /\A3\d\d\z/
209
+ logger.info "redirect: #{response["location"]}"
210
+ new_uri = URI.join request.uri, URI.escape(response["location"])
211
+ new_host = new_uri.host
212
+ if http.address != new_host ||
213
+ http.port != new_uri.port ||
214
+ http.use_ssl? != (new_uri.scheme == "https")
215
+ logger.debug "changing host from '#{http.address}' to '#{new_host}'"
216
+ # http.finish
217
+ http = start_http new_uri, timeout, max_start_http_retry_delay
218
+ end
219
+ do_request.call prepare_request[new_uri]
220
+ when "404"
221
+ logger.error "404 at #{request.method} #{request.uri} with body: #{
222
+ if response.body.is_a? Net::ReadAdapter
223
+ "impossible to reread Net::ReadAdapter -- check the IO you've used in block form"
224
+ elsif response.to_hash["content-type"] == ["image/png"]
225
+ response.to_hash["content-type"].to_s
226
+ else
227
+ response.body.tap do |body|
228
+ body.replace remove_tags body if body[/<html[> ]/]
229
+ end.inspect
230
+ end
231
+ }"
232
+ response
233
+ when "429"
234
+ logger.error "429 at #{request.method} #{request.uri} with body: #{response.body.inspect}"
235
+ response
236
+ when /\A50\d\z/
237
+ logger.error "#{response.code} at #{request.method} #{request.uri} with body: #{
238
+ response.body.tap do |body|
239
+ body.replace remove_tags body if body[/<html[> ]/]
240
+ end.inspect
241
+ }"
242
+ response
243
+ when /\A20/
244
+ response
219
245
  else
220
- response.body.tap do |body|
221
- body.replace remove_tags body if body[/<html[> ]/]
222
- end.inspect
246
+ logger.warn "code #{response.code} at #{request.method} #{request.uri}#{
247
+ " and so #{url}" if request.uri.to_s != url
248
+ } from #{
249
+ [__FILE__, caller.map{ |i| i[/(?<=:)\d+/] }].join ?:
250
+ }"
251
+ logger.debug "< body: #{
252
+ response.body.tap do |body|
253
+ body.replace remove_tags body if body[/<html[> ]/]
254
+ end.inspect
255
+ }"
256
+ response
223
257
  end
224
- }"
225
- response
226
- when "429"
227
- logger.error "429 at #{request.method} #{request.uri} with body: #{response.body.inspect}"
228
- response
229
- when /\A50\d\z/
230
- logger.error "#{response.code} at #{request.method} #{request.uri} with body: #{
231
- response.body.tap do |body|
232
- body.replace remove_tags body if body[/<html[> ]/]
233
- end.inspect
234
- }"
235
- response
236
- when /\A20/
237
- response
238
- else
239
- logger.warn "code #{response.code} at #{request.method} #{request.uri}#{
240
- " and so #{url}" if request.uri.to_s != url
241
- } from #{
242
- [__FILE__, caller.map{ |i| i[/(?<=:)\d+/] }].join ?:
243
- }"
244
- logger.debug "< body: #{
245
- response.body.tap do |body|
246
- body.replace remove_tags body if body[/<html[> ]/]
247
- end.inspect
248
- }"
249
- response
258
+ end
259
+ do_request[prepare_request[uri, mtd, form]].tap do |response|
260
+ cookies.each{ |k, v| response.add_field "Set-Cookie", "#{k}=#{v};" }
261
+ logger.debug "< header: #{response.to_hash}"
262
+ end.body
263
+
250
264
  end
251
265
  end
252
- do_request[prepare_request[uri, mtd, form]].tap do |response|
253
- cookies.each{ |k, v| response.add_field "Set-Cookie", "#{k}=#{v};" }
254
- logger.debug "< header: #{response.to_hash}"
255
- end
256
266
  end
257
267
 
258
- def request_data *args, &block
259
- response = get_response *args, &block
268
+ def request_data http, mtd = :GET, type = :form, form: {}, header: {}, auth: nil, timeout: 30,
269
+ max_start_http_retry_delay: 3600,
270
+ max_read_retry_delay: 3600,
271
+ patch_request: nil, &block
272
+ http = start_http http, timeout, max_start_http_retry_delay unless http.is_a? Net::HTTP
273
+ path = http.instance_variable_get(:@uri).path
274
+ head = http.head path
260
275
  raise Error.new(
261
- (response.to_hash["content-type"] == ["image/png"] ? response.to_hash["content-type"] : response.body),
262
- response.code.to_i
263
- ) unless response.code[/\A(20\d|3\d\d)\z/]
264
- if response["content-encoding"] == "gzip"
265
- Zlib::GzipReader.new(StringIO.new(response.body)).read
276
+ (head.to_hash["content-type"] == ["image/png"] ? head.to_hash["content-type"] : head.body),
277
+ head.code.to_i
278
+ ) unless head.code[/\A(20\d|3\d\d)\z/]
279
+ body = http.read mtd, type, form: form, header: header, auth: auth, timeout: timeout,
280
+ max_read_retry_delay: max_read_retry_delay,
281
+ patch_request: patch_request, &block
282
+ if head.to_hash["content-encoding"] == "gzip"
283
+ Zlib::GzipReader.new(StringIO.new(body)).read
266
284
  else
267
- response.body
285
+ body
268
286
  end.tap do |string|
269
- string.instance_variable_set :@uri_path, response.uri.path
270
- string.instance_variable_set :@header, response.to_hash
287
+ string.instance_variable_set :@uri_path, path
288
+ string.instance_variable_set :@header, head.to_hash
271
289
  end
272
290
  # ensure
273
291
  # response.instance_variable_get("@nethttputils_close").call if response
@@ -282,8 +300,27 @@ if $0 == __FILE__
282
300
  print "self testing... "
283
301
  require "pp"
284
302
 
303
+
285
304
  require "webrick"
286
305
  require "json"
306
+ Thread.abort_on_exception = true
307
+
308
+ server = WEBrick::HTTPServer.new Port: 8000
309
+ stack = []
310
+ server.mount_proc ?/ do |req, res|
311
+ stack.push req.request_method
312
+ end
313
+ Thread.new{ server.start }
314
+ NetHTTPUtils.start_http("http://localhost:8000/")
315
+ fail unless stack == %w{ }
316
+ stack.clear
317
+ NetHTTPUtils.start_http("http://localhost:8000/").head("/")
318
+ fail unless stack == %w{ HEAD }
319
+ stack.clear
320
+ NetHTTPUtils.request_data("http://localhost:8000/")
321
+ fail unless stack == %w{ HEAD GET }
322
+ server.shutdown
323
+
287
324
  server = WEBrick::HTTPServer.new Port: 8000
288
325
  server.mount_proc ?/ do |req, res|
289
326
  # pp req.dup.tap{ |_| _.instance_variable_set "@config", nil }
@@ -299,6 +336,7 @@ if $0 == __FILE__
299
336
  fail unless JSON.dump(["/", %w{ accept-encoding accept user-agent host content-type connection content-length }]) == NetHTTPUtils.request_data("http://localhost:8000/", :post, form: {1=>2})
300
337
  server.shutdown
301
338
 
339
+
302
340
  fail unless NetHTTPUtils.request_data("http://httpstat.us/200") == "200 OK"
303
341
  [400, 404, 500, 502, 503].each do |code|
304
342
  begin
@@ -307,11 +345,11 @@ if $0 == __FILE__
307
345
  raise unless e.code == code
308
346
  end
309
347
  end
310
- fail unless NetHTTPUtils.get_response("http://httpstat.us/400").body == "400 Bad Request"
311
- fail unless NetHTTPUtils.get_response("http://httpstat.us/404").body == "404 Not Found"
312
- fail unless NetHTTPUtils.get_response("http://httpstat.us/500").body == "500 Internal Server Error"
313
- fail unless NetHTTPUtils.get_response("http://httpstat.us/502").body == "502 Bad Gateway"
314
- fail unless NetHTTPUtils.get_response("http://httpstat.us/503").body == "503 Service Unavailable"
348
+ fail unless NetHTTPUtils.start_http("http://httpstat.us/400").read == "400 Bad Request"
349
+ fail unless NetHTTPUtils.start_http("http://httpstat.us/404").read == "404 Not Found"
350
+ fail unless NetHTTPUtils.start_http("http://httpstat.us/500").read == "500 Internal Server Error"
351
+ fail unless NetHTTPUtils.start_http("http://httpstat.us/502").read == "502 Bad Gateway"
352
+ fail unless NetHTTPUtils.start_http("http://httpstat.us/503").read == "503 Service Unavailable"
315
353
  NetHTTPUtils.logger.level = Logger::FATAL
316
354
  [
317
355
  ["https://imgur.com/a/cccccc"],
@@ -331,7 +369,7 @@ if $0 == __FILE__
331
369
  http://www.cutehalloweencostumeideas.org/wp-content/uploads/2017/10/Niagara-Falls_04.jpg
332
370
  }.each do |url|
333
371
  begin
334
- fail NetHTTPUtils.request_data url, max_socketerror_retry_delay: -1
372
+ fail NetHTTPUtils.request_data url, max_start_http_retry_delay: -1
335
373
  rescue SocketError => e
336
374
  raise unless e.message["getaddrinfo: "]
337
375
  end
@@ -347,7 +385,7 @@ if $0 == __FILE__
347
385
  end
348
386
 
349
387
  begin
350
- fail NetHTTPUtils.request_data "https://oi64.tinypic.com/29z7oxs.jpg?", timeout: 5, max_timeout_retry_delay: -1
388
+ fail NetHTTPUtils.request_data "https://oi64.tinypic.com/29z7oxs.jpg?", timeout: 5, max_start_http_retry_delay: -1
351
389
  rescue Net::OpenTimeout => e
352
390
  end
353
391
  ## this stopped failing on High Sierra
data/nethttputils.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "nethttputils"
3
- spec.version = "0.2.5.1"
3
+ spec.version = "0.3.0.0"
4
4
  spec.summary = "this tool is like a pet that I adopted young and now I depend on, sorry"
5
5
  spec.description = <<-EOF
6
6
  Back in 2015 I was a guy automating things at my job and two scripts had a common need --
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nethttputils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.1
4
+ version: 0.3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov aka Nakilon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-05 00:00:00.000000000 Z
11
+ date: 2018-12-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Back in 2015 I was a guy automating things at my job and two scripts had a common need --