dagger 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/lib/dagger.rb +117 -77
- data/lib/dagger/ox_extension.rb +25 -1
- data/lib/dagger/version.rb +2 -2
- data/test/parsers_spec.rb +2 -2
- metadata +2 -3
- data/test/requests_spec.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 212d001704ff60792d0e250469c8271d0ccbdc77
|
4
|
+
data.tar.gz: fecce54d5ca8b521df7ee101d1a7f01797562034
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10e9e8a85477e41656a1b7c28b797092903fa017fbe0764504d3bbc5271e170b62929915e24744203c37cbd5f1f2622814dc63395d7d277acad556ca42ca5ff3
|
7
|
+
data.tar.gz: a0aafed3e61cdf7e720436fd48ce1ee8dcd203d9806bec82746d4a4e09d8cb6379c5c61911468edbffd0a0f3da6d8a4d67d38c43d3d98a758a1c83269a8427fb
|
data/Gemfile
CHANGED
data/lib/dagger.rb
CHANGED
@@ -10,117 +10,157 @@ module Dagger
|
|
10
10
|
|
11
11
|
REDIRECT_CODES = [301, 302, 303].freeze
|
12
12
|
DEFAULT_HEADERS = {
|
13
|
-
'Accept'
|
13
|
+
'Accept' => '*/*',
|
14
14
|
'User-Agent' => "Dagger/#{VERSION} (Ruby Net::HTTP Wrapper, like curl)"
|
15
15
|
}
|
16
16
|
|
17
|
-
|
18
|
-
opts[:follow] = 10 if opts[:follow] == true
|
17
|
+
module Utils
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
request.basic_auth(opts.delete(:username), opts.delete(:password))
|
19
|
+
def self.parse_uri(uri)
|
20
|
+
uri = 'http://' + uri unless uri.to_s['http']
|
21
|
+
uri = URI.parse(uri)
|
22
|
+
raise ArgumentError.new("Invalid URI: #{uri}") unless uri.is_a?(URI::HTTP)
|
23
|
+
uri.path = '/' if uri.path == ''
|
24
|
+
uri
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
def self.encode(value, key = nil)
|
28
|
+
case value
|
29
|
+
when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
|
30
|
+
when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
|
31
|
+
when nil then ''
|
32
|
+
else
|
33
|
+
"#{key}=#{URI.escape(value.to_s)}"
|
34
|
+
end
|
35
|
+
end
|
30
36
|
|
31
|
-
|
32
|
-
|
33
|
-
return get(resp['Location'], nil, opts)
|
37
|
+
def self.append_key(root_key, key)
|
38
|
+
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
|
34
39
|
end
|
35
40
|
|
36
|
-
build_response(resp, data || resp.body) # 1.8 vs 1.9 style responses
|
37
41
|
end
|
38
42
|
|
39
|
-
|
40
|
-
send_request('post', uri, params, options)
|
41
|
-
end
|
43
|
+
class Client
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
def self.init(uri, opts)
|
46
|
+
uri = Utils.parse_uri(uri)
|
47
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
49
|
+
if uri.port == 443
|
50
|
+
http.use_ssl = true
|
51
|
+
http.verify_mode = opts[:verify_ssl] === false ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
|
52
|
+
end
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
[:open_timeout, :read_timeout, :ssl_version, :ciphers].each do |key|
|
55
|
+
http.send("#{key}=", opts[key]) if opts.has_key?(key)
|
56
|
+
end
|
57
|
+
|
58
|
+
new(http)
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(http)
|
62
|
+
@http = http
|
63
|
+
end
|
64
|
+
|
65
|
+
def get(uri, opts = {})
|
66
|
+
opts[:follow] = 10 if opts[:follow] == true
|
67
|
+
|
68
|
+
path = uri[0] == '/' ? uri : Utils.parse_uri(uri)
|
69
|
+
path.sub!(/\?.*|$/, '?' + Utils.encode(opts[:query])) if opts[:query]
|
70
|
+
|
71
|
+
request = Net::HTTP::Get.new(path, DEFAULT_HEADERS.merge(opts[:headers] || {}))
|
72
|
+
request.basic_auth(opts.delete(:username), opts.delete(:password)) if opts[:username]
|
73
|
+
|
74
|
+
@resp, @data = @http.request(request)
|
75
|
+
|
76
|
+
if REDIRECT_CODES.include?(@resp.code.to_i) && @resp['Location'] && (opts[:follow] && opts[:follow] > 0)
|
77
|
+
opts[:follow] -= 1
|
78
|
+
return get(@resp['Location'], nil, opts)
|
79
|
+
end
|
80
|
+
|
81
|
+
response
|
82
|
+
end
|
83
|
+
|
84
|
+
def request(method, uri, data, opts = {})
|
85
|
+
return get(uri, opts.merge(query: data)) if method.to_s.downcase == 'get'
|
86
|
+
|
87
|
+
uri = Utils.parse_uri(uri)
|
88
|
+
headers = DEFAULT_HEADERS.merge(opts[:headers] || {})
|
89
|
+
|
90
|
+
query = if data.is_a?(String)
|
91
|
+
data
|
92
|
+
elsif opts[:json]
|
93
|
+
Oj.dump(data) # convert to JSON
|
94
|
+
headers['Content-Type'] = 'application/json'
|
95
|
+
else # querystring, then
|
96
|
+
Utils.encode(data)
|
97
|
+
end
|
55
98
|
|
56
|
-
|
99
|
+
if opts[:username] # opts[:password] is optional
|
100
|
+
str = [opts[:username], opts[:password]].compact.join(':')
|
101
|
+
headers['Authorization'] = "Basic " + Base64.encode64(str)
|
102
|
+
end
|
57
103
|
|
58
|
-
|
59
|
-
|
60
|
-
headers = opts[:headers] || {}
|
104
|
+
args = [method.to_s.downcase, uri.path, query, headers]
|
105
|
+
args.delete_at(2) if args[0] == 'delete' # Net::HTTP's delete does not accept data
|
61
106
|
|
62
|
-
|
63
|
-
|
64
|
-
elsif opts[:json]
|
65
|
-
Oj.dump(params) # convert to JSON
|
66
|
-
headers['Content-Type'] = 'application/json'
|
67
|
-
else
|
68
|
-
encode(params)
|
107
|
+
@resp, @data = @http.send(*args)
|
108
|
+
response
|
69
109
|
end
|
70
110
|
|
71
|
-
|
72
|
-
|
73
|
-
|
111
|
+
def response
|
112
|
+
raise 'No response yet!' unless @resp
|
113
|
+
@response ||= build_response(@resp, @data || @resp.body) # 1.8 vs 1.9 style responses
|
74
114
|
end
|
75
115
|
|
76
|
-
|
77
|
-
args.delete_at(2) if method.to_s == 'delete' # Net::HTTP's delete does not accept data
|
116
|
+
private
|
78
117
|
|
79
|
-
|
80
|
-
|
81
|
-
|
118
|
+
def build_response(resp, body)
|
119
|
+
resp.extend(Response)
|
120
|
+
resp.set_body(body) unless resp.body
|
121
|
+
resp
|
122
|
+
end
|
82
123
|
|
83
|
-
def self.build_response(resp, body)
|
84
|
-
resp.extend(Response)
|
85
|
-
resp.set_body(body) unless resp.body
|
86
|
-
resp
|
87
124
|
end
|
88
125
|
|
89
|
-
|
90
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
126
|
+
class << self
|
91
127
|
|
92
|
-
|
93
|
-
|
94
|
-
|
128
|
+
def open(uri, opts = {}, &block)
|
129
|
+
uri = Utils.parse_uri(uri)
|
130
|
+
opts.merge!(use_ssl: uri.scheme == 'https')
|
131
|
+
opts.merge!(verify_mode: OpenSSL::SSL::VERIFY_NONE) if opts[:verify_ssl] === false
|
132
|
+
|
133
|
+
Net::HTTP.start(uri.host, uri.port, opts) do |http|
|
134
|
+
client = Client.new(http)
|
135
|
+
# yield(client)
|
136
|
+
client.instance_eval(&block)
|
137
|
+
end
|
95
138
|
end
|
96
139
|
|
97
|
-
|
98
|
-
|
140
|
+
def get(uri, options = {})
|
141
|
+
request(:get, uri, nil, options)
|
99
142
|
end
|
100
143
|
|
101
|
-
|
102
|
-
|
144
|
+
def post(uri, data, options = {})
|
145
|
+
request(:post, uri, data, options)
|
146
|
+
end
|
103
147
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
raise ArgumentError.new("Invalid URI: #{uri}") unless uri.is_a?(URI::HTTP)
|
108
|
-
uri.path = '/' if uri.path == ''
|
109
|
-
uri
|
110
|
-
end
|
148
|
+
def put(uri, data, options = {})
|
149
|
+
request(:put, uri, data, options)
|
150
|
+
end
|
111
151
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
152
|
+
def patch(uri, data, options = {})
|
153
|
+
request(:patch, uri, data, options)
|
154
|
+
end
|
155
|
+
|
156
|
+
def delete(uri, data, options = {})
|
157
|
+
request(:delete, uri, data, options)
|
158
|
+
end
|
159
|
+
|
160
|
+
def request(method, url, data = {}, options = {})
|
161
|
+
Client.init(url, options).request(method, url, data, options)
|
119
162
|
end
|
120
|
-
end
|
121
163
|
|
122
|
-
def self.append_key(root_key, key)
|
123
|
-
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
|
124
164
|
end
|
125
165
|
|
126
166
|
end
|
data/lib/dagger/ox_extension.rb
CHANGED
@@ -1,8 +1,32 @@
|
|
1
1
|
require 'ox'
|
2
2
|
|
3
3
|
XMLNode = Struct.new(:name, :text, :attributes, :children) do
|
4
|
+
# this lets us traverse an parsed object like this:
|
5
|
+
# doc[:child][:grandchild].value
|
4
6
|
def [](key)
|
5
|
-
children.select { |node| node.name.to_s == key.to_s }
|
7
|
+
found = children.select { |node| node.name.to_s == key.to_s }
|
8
|
+
found.empty? ? nil : found.size == 1 ? found.first : found
|
9
|
+
end
|
10
|
+
|
11
|
+
# returns first matching node
|
12
|
+
def first(key)
|
13
|
+
if found = self[key]
|
14
|
+
found.is_a?(XMLNode) ? found : found.first
|
15
|
+
else
|
16
|
+
children.find do |ch|
|
17
|
+
if res = ch.first(key)
|
18
|
+
return res
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# returns all matching nodes
|
25
|
+
def all(key)
|
26
|
+
found = self[key]
|
27
|
+
direct = found.is_a?(XMLNode) ? [found] : found || []
|
28
|
+
indirect = children.map { |ch| ch.all(key) }.flatten.compact
|
29
|
+
direct + indirect
|
6
30
|
end
|
7
31
|
end
|
8
32
|
|
data/lib/dagger/version.rb
CHANGED
data/test/parsers_spec.rb
CHANGED
@@ -6,7 +6,7 @@ require 'rspec/expectations'
|
|
6
6
|
describe 'Parsers' do
|
7
7
|
|
8
8
|
def send_request
|
9
|
-
Dagger.
|
9
|
+
Dagger.post('http://foobar.com/test', { foo: 'bar'})
|
10
10
|
end
|
11
11
|
|
12
12
|
let(:fake_http) { double('Net::HTTP') }
|
@@ -15,7 +15,7 @@ describe 'Parsers' do
|
|
15
15
|
before do
|
16
16
|
allow(Net::HTTP).to receive(:new).and_return(fake_http)
|
17
17
|
allow(fake_http).to receive(:verify_mode=).and_return(true)
|
18
|
-
allow(fake_http).to receive(:
|
18
|
+
allow(fake_http).to receive(:post).and_return(fake_resp)
|
19
19
|
end
|
20
20
|
|
21
21
|
describe 'json' do
|
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: 0.
|
4
|
+
version: 0.6.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: 2016-
|
11
|
+
date: 2016-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -114,7 +114,6 @@ files:
|
|
114
114
|
- lib/dagger/response.rb
|
115
115
|
- lib/dagger/version.rb
|
116
116
|
- test/parsers_spec.rb
|
117
|
-
- test/requests_spec.rb
|
118
117
|
homepage: https://github.com/tomas/dagger
|
119
118
|
licenses: []
|
120
119
|
metadata: {}
|
data/test/requests_spec.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require './lib/dagger'
|
2
|
-
|
3
|
-
require 'rspec/mocks'
|
4
|
-
require 'rspec/expectations'
|
5
|
-
|
6
|
-
describe 'Requests' do
|
7
|
-
|
8
|
-
describe '.get' do
|
9
|
-
|
10
|
-
def send_request(url)
|
11
|
-
Dagger.get(url)
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'empty url' do
|
15
|
-
|
16
|
-
it 'raises error' do
|
17
|
-
expect { send_request('') }.to raise_error(ArgumentError)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'invalid URL' do
|
23
|
-
|
24
|
-
it 'raises error' do
|
25
|
-
expect { send_request('asd123.rewqw') }.to raise_error(SocketError)
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
describe 'nonexisting host' do
|
31
|
-
|
32
|
-
it 'raises error' do
|
33
|
-
expect { send_request('http://www.foobar1234567890foobar.com/hello') }.to raise_error(SocketError)
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
describe 'valid host' do
|
39
|
-
|
40
|
-
it 'works' do
|
41
|
-
expect(send_request('http://www.google.com')).to be_a(Net::HTTPResponse)
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|