nethttputils 0.3.2.10 → 0.4.1.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 +4 -4
- data/lib/nethttputils.rb +64 -35
- data/nethttputils.gemspec +4 -2
- metadata +18 -6
- data/.travis.yml +0 -21
- data/Rakefile +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c68a49af2dbbca3cacf81cd5518df2ce6f2cb72
|
4
|
+
data.tar.gz: bae1db040743d7f9ea9ac17d7aeafba778f227c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ba54aa8a5fe007911b8af3117061b1a279182eb27cbdcd2be0a6293428d4408356b2b8238c7342284e93da9ee20f62d169b79346f1f30019677c24c0ca5c9af
|
7
|
+
data.tar.gz: 23e5657489821b849a611a3692d14335b46c1f367dfff1c130d862a1390eb5234742110cdda9d69bb06f9206ae98ed0fdf6dfa6d66fc7056bf45dacd62a0ca13
|
data/lib/nethttputils.rb
CHANGED
@@ -18,19 +18,22 @@ module NetHTTPUtils
|
|
18
18
|
attr_reader :code
|
19
19
|
def initialize body, code = nil
|
20
20
|
@code = code
|
21
|
-
|
21
|
+
body = body[0...997] + "..." if body.size > 1000
|
22
|
+
super "HTTP error ##{code.inspect} #{body}"
|
22
23
|
end
|
23
24
|
end
|
25
|
+
class EOFError_from_rbuf_fill < StandardError
|
26
|
+
end
|
24
27
|
|
25
28
|
class << self
|
26
29
|
|
27
30
|
def remove_tags str
|
28
|
-
str.gsub(/<script( [a-z]+="[^"]*")*>.*?<\/script>/m, "").
|
29
|
-
gsub(/<style( [a-z]+="[^"]*")*>.*?<\/style>/m, "").
|
31
|
+
str.gsub(/<script( [a-z-]+="[^"]*")*>.*?<\/script>/m, "").
|
32
|
+
gsub(/<style( [a-z-]+="[^"]*")*>.*?<\/style>/m, "").
|
30
33
|
gsub(/<[^>]*>/, "").split(?\n).map(&:strip).reject(&:empty?).join(?\n)
|
31
34
|
end
|
32
35
|
|
33
|
-
def start_http url, max_start_http_retry_delay = 3600, timeout = 30
|
36
|
+
def start_http url, max_start_http_retry_delay = 3600, timeout = 30, proxy = nil
|
34
37
|
uri = url
|
35
38
|
uri = URI.parse begin
|
36
39
|
URI url
|
@@ -42,6 +45,7 @@ module NetHTTPUtils
|
|
42
45
|
begin
|
43
46
|
Net::HTTP.start(
|
44
47
|
uri.host, uri.port,
|
48
|
+
*(proxy.split ?: if proxy),
|
45
49
|
use_ssl: uri.scheme == "https",
|
46
50
|
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
47
51
|
**({open_timeout: timeout}), # if timeout
|
@@ -54,7 +58,7 @@ module NetHTTPUtils
|
|
54
58
|
def << msg
|
55
59
|
@@buffer ||= "[Net::HTTP debug] "
|
56
60
|
@@buffer.concat msg
|
57
|
-
@@buffer = @@buffer[0...997] + "..." if @@buffer.size >
|
61
|
+
@@buffer = @@buffer[0...997] + "..." if @@buffer.size > 1000
|
58
62
|
return unless @@buffer.end_with? ?\n
|
59
63
|
NetHTTPUtils.logger.debug @@buffer.sub ?\n, " "
|
60
64
|
@@buffer = nil
|
@@ -63,7 +67,7 @@ module NetHTTPUtils
|
|
63
67
|
end ) if logger.level == Logger::DEBUG # use `logger.debug?`?
|
64
68
|
http
|
65
69
|
end
|
66
|
-
rescue Errno::ECONNREFUSED => e
|
70
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNRESET => e
|
67
71
|
if max_start_http_retry_delay < delay *= 2
|
68
72
|
e.message.concat " to #{uri}"
|
69
73
|
raise
|
@@ -71,10 +75,6 @@ module NetHTTPUtils
|
|
71
75
|
logger.warn "retrying in #{delay} seconds because of #{e.class} '#{e.message}'"
|
72
76
|
sleep delay
|
73
77
|
retry
|
74
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNRESET => e
|
75
|
-
logger.warn "retrying in 5 seconds because of #{e.class} '#{e.message}'"
|
76
|
-
sleep 5
|
77
|
-
retry
|
78
78
|
rescue SocketError => e
|
79
79
|
if max_start_http_retry_delay < delay *= 2
|
80
80
|
e.message.concat " to #{uri}"
|
@@ -155,7 +155,7 @@ module NetHTTPUtils
|
|
155
155
|
request.each_header.map{ |k, v| "-H \"#{k}: #{v}\" " unless k == "host" }.join
|
156
156
|
}#{curl_form}'#{uri.scheme}://#{uri.host}#{uri.path}#{"?#{uri.query}" if uri.query && !uri.query.empty?}'"
|
157
157
|
logger.debug "> header: #{request.each_header.to_a}"
|
158
|
-
logger.debug "> body: #{request.body.inspect.tap{ |body| body[997
|
158
|
+
logger.debug "> body: #{request.body.inspect.tap{ |body| body.replace body[0...997] + "..." if body.size > 1000 }}"
|
159
159
|
# TODO this is buggy -- mixes lines from different files into one line
|
160
160
|
stack = caller.reverse.map do |level|
|
161
161
|
/((?:[^\/:]+\/)?[^\/:]+):([^:]+)/.match(level).captures
|
@@ -169,15 +169,21 @@ module NetHTTPUtils
|
|
169
169
|
delay = 5
|
170
170
|
response = begin
|
171
171
|
http.request request, &block
|
172
|
-
rescue Errno::ECONNREFUSED, Net::ReadTimeout, Net::OpenTimeout, Zlib::BufError, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e
|
172
|
+
rescue Errno::ECONNREFUSED, Net::ReadTimeout, Net::OpenTimeout, Zlib::BufError, Errno::ECONNRESET, OpenSSL::SSL::SSLError, Errno::ETIMEDOUT, Errno::ENETUNREACH => e
|
173
173
|
raise if max_read_retry_delay < delay *= 2
|
174
174
|
logger.error "retrying in #{delay} seconds because of #{e.class} '#{e.message}' at: #{request.uri}"
|
175
175
|
sleep delay
|
176
176
|
retry
|
177
|
+
rescue EOFError => e
|
178
|
+
raise unless e.backtrace.empty?
|
179
|
+
# https://bugs.ruby-lang.org/issues/13018
|
180
|
+
# https://blog.kalina.tech/2019/04/exception-without-backtrace-in-ruby.html?spref=reddit
|
181
|
+
raise EOFError_from_rbuf_fill.new "probably the old Ruby empty backtrace EOFError exception from net/protocol.rb"
|
177
182
|
end
|
178
183
|
# response.instance_variable_set "@nethttputils_close", http.method(:finish)
|
179
184
|
# response.singleton_class.instance_eval{ attr_accessor :nethttputils_socket_to_close }
|
180
185
|
|
186
|
+
now = Time.now
|
181
187
|
remaining, reset_time, current_timestamp = if response.key? "x-ratelimit-userremaining"
|
182
188
|
logger.debug "x-ratelimit-clientremaining: #{response.fetch("x-ratelimit-clientremaining").to_i}"
|
183
189
|
[
|
@@ -189,7 +195,13 @@ module NetHTTPUtils
|
|
189
195
|
[
|
190
196
|
response.fetch("x-rate-limit-remaining").to_i,
|
191
197
|
response.fetch("x-rate-limit-reset").to_i,
|
192
|
-
|
198
|
+
now.to_i,
|
199
|
+
]
|
200
|
+
elsif response.key? "x-ratelimit-remaining"
|
201
|
+
[
|
202
|
+
response.fetch("x-ratelimit-remaining").to_i,
|
203
|
+
now + response.fetch("x-ratelimit-reset").to_i,
|
204
|
+
now.to_i,
|
193
205
|
]
|
194
206
|
end
|
195
207
|
if remaining
|
@@ -217,13 +229,15 @@ module NetHTTPUtils
|
|
217
229
|
case response.code
|
218
230
|
when /\A30\d\z/
|
219
231
|
logger.info "redirect: #{response["location"]}"
|
220
|
-
|
232
|
+
require "addressable"
|
233
|
+
new_uri = URI.join request.uri.to_s, Addressable::URI.escape(response["location"])
|
221
234
|
new_host = new_uri.host
|
235
|
+
raise Error.new "redirected in place" if new_uri == http.instance_variable_get(:@uri)
|
222
236
|
if http.address != new_host ||
|
223
237
|
http.port != new_uri.port ||
|
224
238
|
http.use_ssl? != (new_uri.scheme == "https")
|
225
239
|
logger.debug "changing host from '#{http.address}' to '#{new_host}'"
|
226
|
-
# http.finish
|
240
|
+
# http.finish # why commented out?
|
227
241
|
http = NetHTTPUtils.start_http new_uri, http.instance_variable_get(:@max_start_http_retry_delay), timeout
|
228
242
|
end
|
229
243
|
if request.method == "POST"
|
@@ -282,11 +296,12 @@ module NetHTTPUtils
|
|
282
296
|
|
283
297
|
require "set"
|
284
298
|
@@_405 ||= Set.new
|
285
|
-
def request_data http, mtd = :GET, type = :form, form: {}, header: {}, auth: nil,
|
299
|
+
def request_data http, mtd = :GET, type = :form, form: {}, header: {}, auth: nil, proxy: nil,
|
300
|
+
timeout: 30,
|
286
301
|
max_start_http_retry_delay: 3600,
|
287
302
|
max_read_retry_delay: 3600,
|
288
303
|
patch_request: nil, &block
|
289
|
-
http = start_http http, max_start_http_retry_delay, timeout unless http.is_a? Net::HTTP
|
304
|
+
http = start_http http, max_start_http_retry_delay, timeout, *proxy unless http.is_a? Net::HTTP
|
290
305
|
path = http.instance_variable_get(:@uri).path
|
291
306
|
|
292
307
|
check_code = lambda do |body|
|
@@ -349,23 +364,41 @@ if $0 == __FILE__
|
|
349
364
|
require "json"
|
350
365
|
Thread.abort_on_exception = true
|
351
366
|
|
367
|
+
server = WEBrick::HTTPServer.new Port: 8000
|
368
|
+
tt = false
|
369
|
+
server.mount_proc "/" do |req, res|
|
370
|
+
next unless "HEAD" == req.request_method
|
371
|
+
fail if tt
|
372
|
+
tt = true
|
373
|
+
res.status = 300
|
374
|
+
res["location"] = "/"
|
375
|
+
end
|
376
|
+
t = Thread.new{ server.start }
|
377
|
+
begin
|
378
|
+
NetHTTPUtils.request_data "http://localhost:8000/"
|
379
|
+
rescue NetHTTPUtils::Error => e
|
380
|
+
raise if e.code
|
381
|
+
end
|
382
|
+
server.shutdown
|
383
|
+
t.join
|
384
|
+
|
352
385
|
server = WEBrick::HTTPServer.new Port: 8000
|
353
386
|
server.mount_proc "/1" do |req, res|
|
354
387
|
next unless "GET" == req.request_method
|
355
|
-
res.cookies.push WEBrick::Cookie.new
|
356
|
-
res.cookies.push WEBrick::Cookie.new
|
357
|
-
res.cookies.push WEBrick::Cookie.new
|
358
|
-
res.cookies.push WEBrick::Cookie.new
|
359
|
-
res.cookies.push WEBrick::Cookie.new
|
360
|
-
res.cookies.push WEBrick::Cookie.new
|
388
|
+
res.cookies.push WEBrick::Cookie.new "1", "2"
|
389
|
+
res.cookies.push WEBrick::Cookie.new "3", "4"
|
390
|
+
res.cookies.push WEBrick::Cookie.new "8", "9"
|
391
|
+
res.cookies.push WEBrick::Cookie.new "a", "b"
|
392
|
+
res.cookies.push WEBrick::Cookie.new "1", "5"
|
393
|
+
res.cookies.push WEBrick::Cookie.new "f", "g h"
|
361
394
|
res.status = 300
|
362
395
|
res["location"] = "/2"
|
363
396
|
end
|
364
397
|
server.mount_proc "/2" do |req, res|
|
365
|
-
res.cookies.push WEBrick::Cookie.new
|
366
|
-
res.cookies.push WEBrick::Cookie.new
|
367
|
-
res.cookies.push WEBrick::Cookie.new
|
368
|
-
res.cookies.push WEBrick::Cookie.new
|
398
|
+
res.cookies.push WEBrick::Cookie.new "3", "6=c"
|
399
|
+
res.cookies.push WEBrick::Cookie.new "a", "d e"
|
400
|
+
res.cookies.push WEBrick::Cookie.new "8", ""
|
401
|
+
res.cookies.push WEBrick::Cookie.new "4", "7"
|
369
402
|
end
|
370
403
|
t = Thread.new{ server.start }
|
371
404
|
fail unless %w{ 3=6=c a=d\ e 8= 4=7 1=5 a=b } == p(NetHTTPUtils.request_data("http://localhost:8000/1").
|
@@ -448,16 +481,16 @@ if $0 == __FILE__
|
|
448
481
|
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/400")) == "400 Bad Request"
|
449
482
|
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/404")) == "404 Not Found"
|
450
483
|
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/500")) == "500 Internal Server Error"
|
451
|
-
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/502"))
|
484
|
+
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/502")).start_with? "httpstat.us | 502: Bad gateway\nError\n502\n"
|
452
485
|
fail unless NetHTTPUtils.method(:read).call(NetHTTPUtils.start_http("http://httpstat.us/503")) == "503 Service Unavailable"
|
453
486
|
[
|
454
|
-
["https://imgur.com/a/
|
455
|
-
["https://imgur.com/mM4Dh7Z"],
|
487
|
+
# ["https://imgur.com/a/oacI3gl"], # TODO: Imgur now hangs on these pages, I guess they had to be some 404 error page
|
488
|
+
# ["https://imgur.com/mM4Dh7Z"], # TODO: Imgur now hangs on these pages, I guess they had to be some 404 error page
|
456
489
|
["https://i.redd.it/si758zk7r5xz.jpg", "HTTP error #404 <image/png>"],
|
457
490
|
].each do |url, expectation|
|
458
491
|
begin
|
459
492
|
puts NetHTTPUtils.remove_tags NetHTTPUtils.request_data url
|
460
|
-
fail
|
493
|
+
fail url
|
461
494
|
rescue NetHTTPUtils::Error => e
|
462
495
|
raise e.code.inspect unless e.code == 404
|
463
496
|
raise e.to_s if e.to_s != expectation if expectation
|
@@ -482,10 +515,6 @@ if $0 == __FILE__
|
|
482
515
|
end
|
483
516
|
end
|
484
517
|
|
485
|
-
begin
|
486
|
-
fail NetHTTPUtils.request_data "https://oi64.tinypic.com/29z7oxs.jpg?", timeout: 5, max_start_http_retry_delay: -1
|
487
|
-
rescue Net::OpenTimeout => e
|
488
|
-
end
|
489
518
|
## this stopped failing on High Sierra
|
490
519
|
# begin
|
491
520
|
# # https://www.virtualself.co/?
|
data/nethttputils.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "nethttputils"
|
3
|
-
spec.version = "0.
|
3
|
+
spec.version = "0.4.1.1"
|
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 --
|
@@ -21,5 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.license = "MIT"
|
22
22
|
|
23
23
|
spec.require_path = "lib"
|
24
|
-
spec.files =
|
24
|
+
spec.files = %w{ LICENSE nethttputils.gemspec lib/nethttputils.rb }
|
25
|
+
|
26
|
+
spec.add_dependency "addressable"
|
25
27
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nethttputils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1.1
|
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:
|
12
|
-
dependencies:
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: |2
|
14
28
|
Back in 2015 I was a guy automating things at my job and two scripts had a common need --
|
15
29
|
they both had to pass the same credentials to Jenkins (via query params, I guess).
|
@@ -26,9 +40,7 @@ executables: []
|
|
26
40
|
extensions: []
|
27
41
|
extra_rdoc_files: []
|
28
42
|
files:
|
29
|
-
- ".travis.yml"
|
30
43
|
- LICENSE
|
31
|
-
- Rakefile
|
32
44
|
- lib/nethttputils.rb
|
33
45
|
- nethttputils.gemspec
|
34
46
|
homepage: https://github.com/nakilon/nethttputils
|
@@ -51,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
63
|
version: '0'
|
52
64
|
requirements: []
|
53
65
|
rubyforge_project:
|
54
|
-
rubygems_version: 2.5.2
|
66
|
+
rubygems_version: 2.5.2.3
|
55
67
|
signing_key:
|
56
68
|
specification_version: 4
|
57
69
|
summary: this tool is like a pet that I adopted young and now I depend on, sorry
|
data/.travis.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: ruby
|
3
|
-
|
4
|
-
script: "ruby lib/nethttputils.rb"
|
5
|
-
|
6
|
-
os:
|
7
|
-
- linux
|
8
|
-
- osx
|
9
|
-
rvm:
|
10
|
-
- ruby-head
|
11
|
-
- 2.5
|
12
|
-
- 2.4
|
13
|
-
- 2.3
|
14
|
-
- 2.2
|
15
|
-
- 2.1
|
16
|
-
- 2.0
|
17
|
-
- jruby-head
|
18
|
-
matrix:
|
19
|
-
allow_failures:
|
20
|
-
# something with `NetHTTPUtils.request_data("http://localhost:8000/?1=2&3=4", form: {1=>3})` test
|
21
|
-
- rvm: jruby-head
|
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|