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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 554b365474524830ac1017cac8b57354d8fed85a
4
- data.tar.gz: be62ee9a3bab4868326fb4cf15db03776e0591bf
3
+ metadata.gz: 212d001704ff60792d0e250469c8271d0ccbdc77
4
+ data.tar.gz: fecce54d5ca8b521df7ee101d1a7f01797562034
5
5
  SHA512:
6
- metadata.gz: f03630f6ccd2603de2aa87cca29987a08dd3de8190ea4eb85820b0a46a3735287a1da5b9c704cd8d6d6d644a7e209c7b4d4c56144117839fb6b71ab630b66937
7
- data.tar.gz: 4dbc25a2e30be77ec37e29e2ecd240a01871e2fa56420524a21aa48c643892289f9f16715e433e7c2cab36bf5bb1616be4109fb57deaf972f18432ebf94dc970
6
+ metadata.gz: 10e9e8a85477e41656a1b7c28b797092903fa017fbe0764504d3bbc5271e170b62929915e24744203c37cbd5f1f2622814dc63395d7d277acad556ca42ca5ff3
7
+ data.tar.gz: a0aafed3e61cdf7e720436fd48ce1ee8dcd203d9806bec82746d4a4e09d8cb6379c5c61911468edbffd0a0f3da6d8a4d67d38c43d3d98a758a1c83269a8427fb
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # specified in tuktuk.gemspec
4
4
  gemspec
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
- def self.get(uri, query = nil, opts = {})
18
- opts[:follow] = 10 if opts[:follow] == true
17
+ module Utils
19
18
 
20
- uri = parse_uri(uri)
21
- uri.query = encode(query) if query
22
- http = client(uri, opts)
23
- request = Net::HTTP::Get.new(uri.request_uri, DEFAULT_HEADERS.merge(opts[:headers] || {}))
24
-
25
- if opts[:username] # && opts[:password]
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
- resp, data = http.request(request)
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
- if REDIRECT_CODES.include?(resp.code.to_i) && resp['Location'] && (opts[:follow] && opts[:follow] > 0)
32
- opts[:follow] -= 1
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
- def self.post(uri, params = {}, options = {})
40
- send_request('post', uri, params, options)
41
- end
43
+ class Client
42
44
 
43
- def self.put(uri, params = {}, options = {})
44
- send_request('put', uri, params, options)
45
- end
45
+ def self.init(uri, opts)
46
+ uri = Utils.parse_uri(uri)
47
+ http = Net::HTTP.new(uri.host, uri.port)
46
48
 
47
- def self.delete(uri, params = {}, options = {})
48
- send_request('delete', uri, params, options)
49
- end
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
- def self.request(method, url, params = {}, options = {})
52
- return get(url, params, options) if method.to_s.downcase == 'get'
53
- send_request(method.to_s.downcase, url, params, options)
54
- end
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
- private
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
- def self.send_request(method, uri, params, opts = {})
59
- uri = parse_uri(uri)
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
- query = if params.is_a?(String)
63
- params
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
- if opts[:username] # opts[:password] is optional
72
- str = [opts[:username], opts[:password]].compact.join(':')
73
- headers['Authorization'] = "Basic " + Base64.encode64(str)
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
- args = [method, uri.path, query, headers]
77
- args.delete_at(2) if method.to_s == 'delete' # Net::HTTP's delete does not accept data
116
+ private
78
117
 
79
- resp, data = client(uri, opts).send(*args)
80
- build_response(resp, data || resp.body) # 1.8 vs 1.9 style responses
81
- end
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
- def self.client(uri, opts = {})
90
- http = Net::HTTP.new(uri.host, uri.port)
126
+ class << self
91
127
 
92
- if uri.port == 443
93
- http.use_ssl = true
94
- http.verify_mode = opts[:verify_ssl] === false ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
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
- [:open_timeout, :read_timeout, :ssl_version, :ciphers].each do |key|
98
- http.send("#{key}=", opts[key]) if opts.has_key?(key)
140
+ def get(uri, options = {})
141
+ request(:get, uri, nil, options)
99
142
  end
100
143
 
101
- http
102
- end
144
+ def post(uri, data, options = {})
145
+ request(:post, uri, data, options)
146
+ end
103
147
 
104
- def self.parse_uri(uri)
105
- uri = 'http://' + uri unless uri.to_s['http']
106
- uri = URI.parse(uri)
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
- def self.encode(value, key = nil)
113
- case value
114
- when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
115
- when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
116
- when nil then ''
117
- else
118
- "#{key}=#{URI.escape(value.to_s)}"
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
@@ -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 }.first
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
 
@@ -1,7 +1,7 @@
1
1
  module Dagger
2
2
  MAJOR = 0
3
- MINOR = 5
4
- PATCH = 1
3
+ MINOR = 6
4
+ PATCH = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
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.get('http://foobar.com/test')
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(:request).and_return(fake_resp)
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.5.1
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-24 00:00:00.000000000 Z
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: {}
@@ -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