dagger 1.3.1 → 1.4.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +18 -0
- data/dagger.gemspec +1 -0
- data/lib/dagger.rb +67 -24
- data/lib/dagger/version.rb +2 -2
- data/spec/arguments_spec.rb +1 -1
- data/spec/persistent_spec.rb +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85a53a6a5acd40ecd63cfbdf54a876d2d341626e9f5dcd2daffef6c223e89cdb
|
4
|
+
data.tar.gz: b18df51d7d507d68686cff2b4d08a204511f92a812aed2ba60c3f4833d3c7d27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fde76bd91f86ee78737bc428073f944c5fd2f9e585c50c92a65037b1ece4a424a5851635f30b86ecfdda4db6a072e9a0a20d6b27dc50ab4b286dafd14ca2c047
|
7
|
+
data.tar.gz: 64737c64a0a60fad0b01b3624725ce09aa264e5d582a616520be304277da817e23317ed88081162435057dd27d585a6c4b2b5bab76c78e4719fd68780ab0d830
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: Ruby
|
2
|
+
on: [push]
|
3
|
+
|
4
|
+
jobs:
|
5
|
+
build:
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v1
|
10
|
+
- name: Set up Ruby 2.6
|
11
|
+
uses: actions/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.6.x
|
14
|
+
- name: Build and test with Rake
|
15
|
+
run: |
|
16
|
+
gem install bundler
|
17
|
+
bundle install --jobs 4 --retry 3
|
18
|
+
bundle exec rspec
|
data/dagger.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_development_dependency "rspec-mocks"
|
20
20
|
s.add_development_dependency "rspec-expectations"
|
21
21
|
|
22
|
+
s.add_runtime_dependency "net-http-persistent", "~> 3.0"
|
22
23
|
s.add_runtime_dependency "oj", "~> 2.1"
|
23
24
|
s.add_runtime_dependency "ox", "~> 2.4"
|
24
25
|
|
data/lib/dagger.rb
CHANGED
@@ -2,16 +2,24 @@ require 'dagger/version'
|
|
2
2
|
require 'dagger/response'
|
3
3
|
require 'dagger/parsers'
|
4
4
|
|
5
|
+
require 'net/http/persistent'
|
5
6
|
require 'net/https'
|
6
7
|
require 'base64'
|
7
8
|
|
9
|
+
class URI::HTTP
|
10
|
+
def scheme_and_host
|
11
|
+
[scheme, host].join('://')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
module Dagger
|
9
16
|
|
17
|
+
DAGGER_NAME = "Dagger/#{VERSION}"
|
10
18
|
REDIRECT_CODES = [301, 302, 303].freeze
|
11
19
|
DEFAULT_RETRY_WAIT = 5.freeze # seconds
|
12
20
|
DEFAULT_HEADERS = {
|
13
21
|
'Accept' => '*/*',
|
14
|
-
'User-Agent' => "
|
22
|
+
'User-Agent' => "#{DAGGER_NAME} (Ruby Net::HTTP Wrapper, like curl)"
|
15
23
|
}
|
16
24
|
|
17
25
|
module Utils
|
@@ -25,6 +33,13 @@ module Dagger
|
|
25
33
|
uri
|
26
34
|
end
|
27
35
|
|
36
|
+
def self.resolve_uri(uri, host = nil, query = nil)
|
37
|
+
uri = host + uri if uri.to_s['//'].nil? && host
|
38
|
+
uri = parse_uri(uri.to_s)
|
39
|
+
uri.path.sub!(/\?.*|$/, '?' + Utils.encode(query)) if query and query.any?
|
40
|
+
uri
|
41
|
+
end
|
42
|
+
|
28
43
|
def self.encode(obj, key = nil)
|
29
44
|
if key.nil? && obj.is_a?(String) # && obj['=']
|
30
45
|
return obj
|
@@ -49,10 +64,14 @@ module Dagger
|
|
49
64
|
|
50
65
|
def self.init(uri, opts)
|
51
66
|
uri = Utils.parse_uri(uri)
|
52
|
-
http =
|
67
|
+
http = if opts.delete(:persistent)
|
68
|
+
Net::HTTP::Persistent.new(name: DAGGER_NAME)
|
69
|
+
else
|
70
|
+
Net::HTTP.new(uri.host, uri.port)
|
71
|
+
end
|
53
72
|
|
54
73
|
if uri.port == 443
|
55
|
-
http.use_ssl = true
|
74
|
+
http.use_ssl = true if http.respond_to?(:use_ssl) # persistent does it automatically
|
56
75
|
http.verify_mode = opts[:verify_ssl] === false ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
|
57
76
|
end
|
58
77
|
|
@@ -60,27 +79,31 @@ module Dagger
|
|
60
79
|
http.send("#{key}=", opts[key]) if opts.has_key?(key)
|
61
80
|
end
|
62
81
|
|
63
|
-
new(http)
|
82
|
+
# new(http, [uri.scheme, uri.host].join('://'))
|
83
|
+
new(http, uri.scheme_and_host)
|
64
84
|
end
|
65
85
|
|
66
|
-
def initialize(http)
|
67
|
-
@http = http
|
86
|
+
def initialize(http, host = nil)
|
87
|
+
@http, @host = http, host
|
68
88
|
end
|
69
89
|
|
70
90
|
def get(uri, opts = {})
|
71
|
-
|
72
|
-
|
73
|
-
path = uri[0] == '/' ? uri : Utils.parse_uri(uri).request_uri
|
74
|
-
path.sub!(/\?.*|$/, '?' + Utils.encode(opts[:query])) if opts[:query] and opts[:query].any?
|
91
|
+
uri = Utils.resolve_uri(uri, @host, opts[:query])
|
92
|
+
raise ArgumentError.new("#{uri.scheme_and_host} does not match #{@host}") if @host != uri.scheme_and_host
|
75
93
|
|
94
|
+
opts[:follow] = 10 if opts[:follow] == true
|
76
95
|
headers = opts[:headers] || {}
|
77
96
|
headers['Accept'] = 'application/json' if opts[:json]
|
78
97
|
|
79
|
-
request = Net::HTTP::Get.new(
|
98
|
+
request = Net::HTTP::Get.new(uri, DEFAULT_HEADERS.merge(headers))
|
80
99
|
request.basic_auth(opts.delete(:username), opts.delete(:password)) if opts[:username]
|
81
100
|
|
82
|
-
|
83
|
-
|
101
|
+
if @http.respond_to?(:started?) # regular Net::HTTP
|
102
|
+
@http.start unless @http.started?
|
103
|
+
resp, data = @http.request(request)
|
104
|
+
else # persistent
|
105
|
+
resp, data = @http.request(uri, request)
|
106
|
+
end
|
84
107
|
|
85
108
|
if REDIRECT_CODES.include?(resp.code.to_i) && resp['Location'] && (opts[:follow] && opts[:follow] > 0)
|
86
109
|
opts[:follow] -= 1
|
@@ -124,7 +147,8 @@ module Dagger
|
|
124
147
|
return get(uri, opts.merge(query: query))
|
125
148
|
end
|
126
149
|
|
127
|
-
uri
|
150
|
+
uri = Utils.resolve_uri(uri, @host)
|
151
|
+
raise ArgumentError.new("#{uri.scheme_and_host} does not match #{@host}") if @host != uri.scheme_and_host
|
128
152
|
headers = DEFAULT_HEADERS.merge(opts[:headers] || {})
|
129
153
|
|
130
154
|
query = if data.is_a?(String)
|
@@ -138,21 +162,29 @@ module Dagger
|
|
138
162
|
|
139
163
|
if opts[:username] # opts[:password] is optional
|
140
164
|
str = [opts[:username], opts[:password]].compact.join(':')
|
141
|
-
headers['Authorization'] =
|
165
|
+
headers['Authorization'] = 'Basic ' + Base64.encode64(str)
|
142
166
|
end
|
143
167
|
|
144
|
-
|
145
|
-
|
168
|
+
if @http.respond_to?(:started?) # regular Net::HTTP
|
169
|
+
args = [method.to_s.downcase, uri.path, query, headers]
|
170
|
+
args.delete_at(2) if args[0] == 'delete' # Net::HTTP's delete does not accept data
|
171
|
+
|
172
|
+
@http.start unless @http.started?
|
173
|
+
resp, data = @http.send(*args)
|
174
|
+
else # Net::HTTP::Persistent
|
175
|
+
req = Kernel.const_get("Net::HTTP::#{method.capitalize}").new(uri.path, headers)
|
176
|
+
req.set_form_data(query)
|
177
|
+
|
178
|
+
resp, data = @http.request(uri, req)
|
179
|
+
end
|
146
180
|
|
147
|
-
@http.start unless @http.started?
|
148
|
-
resp, data = @http.send(*args)
|
149
181
|
@response = build_response(resp, data || resp.body)
|
150
182
|
|
151
183
|
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EINVAL, Timeout::Error, \
|
152
184
|
SocketError, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, OpenSSL::SSL::SSLError => e
|
153
185
|
|
154
186
|
if method.to_s.downcase != 'get' && retries = opts[:retries] and retries.to_i > 0
|
155
|
-
puts "Got #{e.class}! Retrying in a sec (#{retries} retries left)"
|
187
|
+
puts "[#{DAGGER_NAME}] Got #{e.class}! Retrying in a sec (#{retries} retries left)"
|
156
188
|
sleep (opts[:retry_wait] || DEFAULT_RETRY_WAIT)
|
157
189
|
request(method, uri, data, opts.merge(retries: retries - 1))
|
158
190
|
else
|
@@ -165,13 +197,21 @@ module Dagger
|
|
165
197
|
end
|
166
198
|
|
167
199
|
def open(&block)
|
168
|
-
@http.
|
200
|
+
if @http.is_a?(Net::HTTP::Persistent)
|
169
201
|
instance_eval(&block)
|
202
|
+
else
|
203
|
+
@http.start do
|
204
|
+
instance_eval(&block)
|
205
|
+
end
|
170
206
|
end
|
171
207
|
end
|
172
208
|
|
173
209
|
def close
|
174
|
-
|
210
|
+
if @http.is_a?(Net::HTTP::Persistent)
|
211
|
+
@http.shutdown # calls finish on pool connections
|
212
|
+
else
|
213
|
+
@http.finish if @http.started?
|
214
|
+
end
|
175
215
|
end
|
176
216
|
|
177
217
|
private
|
@@ -187,8 +227,11 @@ module Dagger
|
|
187
227
|
class << self
|
188
228
|
|
189
229
|
def open(uri, opts = {}, &block)
|
190
|
-
client = Client.init(uri, opts)
|
191
|
-
|
230
|
+
client = Client.init(uri, opts.merge(persistent: true))
|
231
|
+
if block_given?
|
232
|
+
client.open(&block)
|
233
|
+
client.close
|
234
|
+
end
|
192
235
|
client
|
193
236
|
end
|
194
237
|
|
data/lib/dagger/version.rb
CHANGED
data/spec/arguments_spec.rb
CHANGED
data/spec/persistent_spec.rb
CHANGED
@@ -9,6 +9,7 @@ describe 'Persistent mode' do
|
|
9
9
|
fake_client = double('Client')
|
10
10
|
expect(Dagger::Client).to receive(:new).once.and_return(fake_client)
|
11
11
|
expect(fake_client).to receive(:open).once #.and_return(fake_resp)
|
12
|
+
expect(fake_client).to receive(:close).once #.and_return(fake_resp)
|
12
13
|
|
13
14
|
obj = Dagger.open('https://www.google.com') do
|
14
15
|
get('/search?q=dagger+http+client')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomás Pollak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: net-http-persistent
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: oj
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +116,7 @@ executables:
|
|
102
116
|
extensions: []
|
103
117
|
extra_rdoc_files: []
|
104
118
|
files:
|
119
|
+
- ".github/workflows/ruby.yml"
|
105
120
|
- ".gitignore"
|
106
121
|
- Gemfile
|
107
122
|
- README.md
|