httpi 2.2.5 → 2.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NTg1OTVkMjUyODliYTU2NTE1YTk4ZTVmM2MwODczOTM2YWIyN2VmNg==
5
- data.tar.gz: !binary |-
6
- NWJhMGMyMzljNmUxNGNlYWE1OTllNWNhZDhiNTgwNjAxNDJjMmIyNg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NDQ4MjVjMWUxNzZiOWViMWY1YjJkZTZlOWQ1ZDRjNWM0NTlmNWM3MDA3NWU1
10
- N2Q2M2EzMDE5Nzc5MDAxZWMyZGFlZjM1NDM0NTQxNzM1YzVjOWUxZTYxZWRk
11
- Njc4NmM1ZWQxNmYwMzU2NjkzY2I1NzYzMTA5NGFhZjU4Mjg3Y2E=
12
- data.tar.gz: !binary |-
13
- MzM3ZjZmOWJhOWNmZjgwMTA0MzcxZmJiNjQ1MDlmODk1MjlmN2Q3MWU4YWNj
14
- NzNhMDYyNzJjZGQxNGU2ZGYwZDEyMDdiYjI5ZDc4M2RhOTI1MTE0Mjc2NGY4
15
- NTU5YWRmYjFkODc1MWFkOWU3NTYxMzhkNzJjYWU5ZTQwYTE0Yzg=
2
+ SHA1:
3
+ metadata.gz: b2a6ca966957f93efb1b07b859d41b08539b9af8
4
+ data.tar.gz: 1f6e86b25d395cb9c2865d3983eb3a270d345cd9
5
+ SHA512:
6
+ metadata.gz: b824b5b23daff84b3440b16fd56576a377ce5c02e5178d9f6994ad88fac05aeac465999a80e293083a351aa8658eca4388159e3f5545b185f2369eb31521b4e0
7
+ data.tar.gz: b7d465a83a459e33e4cd6aca4fe3921f88c431825c8aa8a764ab382873c6f1404082b71f976c6d813d970f1e92d6c6b4fea2133fd4ba8a9eed7e9b04f043712a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### 2.2.6
2
+
3
+ * Fix: [#128](https://github.com/savonrb/httpi/pull/128) Fix for libcURL crash on some ssystems.
4
+
1
5
  ### 2.2.5
2
6
 
3
7
  * Feature: [#123](https://github.com/savonrb/httpi/pull/123) Don't warn about missing rubyntlm gem if it is optional. Thanks to [PChambino](https://github.com/PChambino)
data/httpi.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.version = HTTPI::VERSION
9
9
  s.authors = ['Daniel Harrington', 'Martin Tepper']
10
10
  s.email = 'me@rubiii.com'
11
- s.homepage = 'http://github.com/savonrb/#{s.name}'
11
+ s.homepage = "http://github.com/savonrb/#{s.name}"
12
12
  s.summary = "Common interface for Ruby's HTTP libraries"
13
13
  s.description = s.summary
14
14
 
data/lib/httpi.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "httpi/version"
2
2
  require "httpi/logger"
3
3
  require "httpi/request"
4
+ require "httpi/query_builder"
4
5
 
5
6
  require "httpi/adapter/httpclient"
6
7
  require "httpi/adapter/curb"
@@ -99,6 +100,25 @@ module HTTPI
99
100
 
100
101
  class << self
101
102
 
103
+ def query_builder
104
+ @query_builder || HTTPI::QueryBuilder::Flat
105
+ end
106
+
107
+ def query_builder=(builder)
108
+ if builder.is_a?(Symbol)
109
+ builder_name = builder.to_s.capitalize
110
+ begin
111
+ builder = HTTPI::QueryBuilder.const_get(builder_name)
112
+ rescue NameError => ex
113
+ raise ArgumentError, "Invalid builder. Available builders are: [:flat, :nested]"
114
+ end
115
+ end
116
+ unless builder.respond_to?(:build)
117
+ raise ArgumentError, "Query builder object should respond to build method"
118
+ end
119
+ @query_builder = builder
120
+ end
121
+
102
122
  # Executes an HTTP GET request.
103
123
  def get(request, adapter = nil, &block)
104
124
  request = Request.new(request) if request.kind_of? String
@@ -75,6 +75,10 @@ module HTTPI
75
75
  @client.connect_timeout = @request.open_timeout if @request.open_timeout
76
76
  @client.headers = @request.headers.to_hash
77
77
  @client.verbose = false
78
+ # cURL workaround
79
+ # see: http://stackoverflow.com/a/10755612/102920
80
+ # https://github.com/typhoeus/typhoeus/issues/260
81
+ @client.set(:NOSIGNAL, true)
78
82
  end
79
83
 
80
84
  def setup_http_auth
@@ -105,7 +109,7 @@ module HTTPI
105
109
 
106
110
  @client.ssl_verify_peer = ssl.verify_mode == :peer
107
111
  end
108
-
112
+
109
113
  @client.ssl_version = case ssl.ssl_version
110
114
  when :TLSv1 then 1
111
115
  when :SSLv2 then 2
@@ -0,0 +1,47 @@
1
+ module HTTPI
2
+ module QueryBuilder
3
+
4
+ class Flat
5
+
6
+ # Returns a +query+ string given a +Hash+.
7
+ # Example:
8
+ #
9
+ # build({names => ['Bruno', 'Samantha', 'Alexandre']})
10
+ # # => "names=Bruno&names=Samantha&names=Alexandre"
11
+ def self.build(query)
12
+ Rack::Utils.build_query(query)
13
+ end
14
+
15
+ end
16
+
17
+ class Nested
18
+
19
+ # Returns a +query+ string given a +Hash+.
20
+ # Example:
21
+ #
22
+ # build({names => ['Bruno', 'Samantha', 'Alexandre']})
23
+ # # => "names[]=Bruno&names[]=Samantha&names[]=Alexandre"
24
+ def self.build(query)
25
+ stringfied_query = stringify_hash_values(query)
26
+ Rack::Utils.build_nested_query(stringfied_query)
27
+ end
28
+
29
+ private
30
+
31
+ # Changes Hash values into Strings
32
+ def self.stringify_hash_values(query)
33
+ query.each do |param, value|
34
+ if value.kind_of?(Hash)
35
+ query[param] = stringify_hash_values(value)
36
+ elsif value.kind_of?(Array)
37
+ query[param] = value.map(&:to_s)
38
+ else
39
+ query[param] = value.to_s
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
data/lib/httpi/request.rb CHANGED
@@ -35,7 +35,7 @@ module HTTPI
35
35
  def query=(query)
36
36
  raise ArgumentError, "Invalid URL: #{self.url}" unless self.url.respond_to?(:query)
37
37
  if query.kind_of?(Hash)
38
- query = Rack::Utils.build_query(query)
38
+ query = build_query_from_hash(query)
39
39
  end
40
40
  query = query.to_s unless query.is_a?(String)
41
41
  self.url.query = query
@@ -96,7 +96,7 @@ module HTTPI
96
96
 
97
97
  # Sets a body request given a String or a Hash.
98
98
  def body=(params)
99
- @body = params.kind_of?(Hash) ? Rack::Utils.build_query(params) : params
99
+ @body = params.kind_of?(Hash) ? build_query_from_hash(params) : params
100
100
  end
101
101
 
102
102
  # Sets the block to be called while processing the response. The block
@@ -143,5 +143,10 @@ module HTTPI
143
143
  url.kind_of?(URI) ? url : URI(url)
144
144
  end
145
145
 
146
+ # Returns a +query+ string given a +Hash+
147
+ def build_query_from_hash(query)
148
+ HTTPI.query_builder.build(query)
149
+ end
150
+
146
151
  end
147
152
  end
data/lib/httpi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module HTTPI
2
- VERSION = "2.2.5"
2
+ VERSION = '2.2.6'
3
3
  end
@@ -34,6 +34,33 @@ describe HTTPI do
34
34
  end
35
35
  end
36
36
 
37
+ describe ".query_builder" do
38
+ it "gets flat builder by default" do
39
+ expect(client.query_builder).to eq(HTTPI::QueryBuilder::Flat)
40
+ end
41
+ context "setter" do
42
+ after { client.query_builder = HTTPI::QueryBuilder::Flat }
43
+ it "looks up for class if symbol" do
44
+ client.query_builder = :nested
45
+ expect(client.query_builder).to eq(HTTPI::QueryBuilder::Nested)
46
+ end
47
+ it "validates if symbol is a valid option" do
48
+ expect do
49
+ client.query_builder = :xxx
50
+ end.to raise_error(ArgumentError)
51
+ end
52
+ it "validates if value respond to build" do
53
+ expect do
54
+ client.query_builder = nil
55
+ end.to raise_error(ArgumentError)
56
+ end
57
+ it "accepts valid class" do
58
+ client.query_builder = HTTPI::QueryBuilder::Nested
59
+ expect(client.query_builder).to eq(HTTPI::QueryBuilder::Nested)
60
+ end
61
+ end
62
+ end
63
+
37
64
  describe ".get(request)" do
38
65
  it "executes a GET request using the default adapter" do
39
66
  request = HTTPI::Request.new("http://example.com")
@@ -47,28 +47,57 @@ describe HTTPI::Request do
47
47
  it "raises an ArgumentError if url not respond to query" do
48
48
  expect { request.query = "q=query" }.to raise_error(ArgumentError)
49
49
  end
50
- it "lets you specify query parameter as String" do
51
- request.url = "http://example.com"
52
- request.query = "q=query"
53
- expect(request.url.to_s).to eq("http://example.com?q=query")
54
- end
55
- it "lets you specify query parameter as Hash" do
56
- request.url = "http://example.com"
57
- request.query = {:q => "query"}
58
- expect(request.url.to_s).to eq("http://example.com?q=query")
59
- end
50
+
60
51
  it "getter return nil for invalid url" do
61
52
  expect(request.query).to be_nil
62
53
  end
63
- it "getter return String for query parameter as String" do
64
- request.url = "http://example.com"
65
- request.query = "q=query"
66
- expect(request.query).to eq("q=query")
54
+
55
+ context "with query parameter as String" do
56
+ it "lets you specify query parameter as String" do
57
+ request.url = "http://example.com"
58
+ request.query = "q=query"
59
+ expect(request.url.to_s).to eq("http://example.com?q=query")
60
+ end
61
+
62
+ it "getter return String for query parameter as String" do
63
+ request.url = "http://example.com"
64
+ request.query = "q=query"
65
+ expect(request.query).to eq("q=query")
66
+ end
67
67
  end
68
- it "getter return String for query parameter as Hash" do
69
- request.url = "http://example.com"
70
- request.query = {:q => "query"}
71
- expect(request.query).to eq("q=query")
68
+
69
+ context "with query parameter as Hash" do
70
+ context "with flat query builder" do
71
+ before do
72
+ request.url = "http://example.com"
73
+ request.query = {:q => ["nested", "query"]}
74
+ end
75
+
76
+ it "lets you specify query parameter as Hash" do
77
+ expect(request.url.to_s).to eq("http://example.com?q=nested&q=query")
78
+ end
79
+
80
+ it "getter return String for query parameter as Hash" do
81
+ expect(request.query).to eq("q=nested&q=query")
82
+ end
83
+ end
84
+ context "with nested query builder" do
85
+ before do
86
+ HTTPI.query_builder = :nested
87
+
88
+ request.url = "http://example.com"
89
+ request.query = {:q => ["nested", "query"]}
90
+ end
91
+ after { HTTPI.query_builder = :flat }
92
+
93
+ it "lets you specify query parameter as Hash" do
94
+ expect(request.url.to_s).to eq("http://example.com?q[]=nested&q[]=query")
95
+ end
96
+
97
+ it "getter return String for query parameter as Hash" do
98
+ expect(request.query).to eq("q[]=nested&q[]=query")
99
+ end
100
+ end
72
101
  end
73
102
  end
74
103
 
@@ -168,14 +197,41 @@ describe HTTPI::Request do
168
197
  end
169
198
 
170
199
  describe "#body" do
171
- it "lets you specify the HTTP request body using a String" do
172
- request.body = "<some>xml</some>"
173
- expect(request.body).to eq("<some>xml</some>")
200
+ context "with query parameter as String" do
201
+ it "lets you specify the HTTP request body using a String" do
202
+ request.body = "<some>xml</some>"
203
+ expect(request.body).to eq("<some>xml</some>")
204
+ end
174
205
  end
175
-
176
- it "lets you specify the HTTP request body using a Hash" do
177
- request.body = {:foo => :bar, :baz => :foo}
178
- expect(request.body.split("&")).to match_array(["foo=bar", "baz=foo"])
206
+ context "with flat query builder" do
207
+ it "lets you specify the HTTP request body using a Hash" do
208
+ request.body = {:foo => :bar, :baz => :foo}
209
+ expect(request.body.split("&")).to match_array(["foo=bar", "baz=foo"])
210
+ end
211
+ end
212
+ context "with query parameter as Hash" do
213
+ context "with flat query builder" do
214
+ it "request body using a Hash" do
215
+ request.body = {:foo => :bar, :baz => :foo}
216
+ expect(request.body.split("&")).to match_array(["foo=bar", "baz=foo"])
217
+ end
218
+ it "request body using a Hash with Array" do
219
+ request.body = {:foo => :bar, :baz => [:foo, :tst]}
220
+ expect(request.body.split("&")).to match_array(["foo=bar", "baz=foo", "baz=tst"])
221
+ end
222
+ end
223
+ context "with nested query builder" do
224
+ before { HTTPI.query_builder = :nested }
225
+ after { HTTPI.query_builder = :flat }
226
+ it "request body using a Hash" do
227
+ request.body = {:foo => :bar, :baz => :foo}
228
+ expect(request.body.split("&")).to match_array(["foo=bar", "baz=foo"])
229
+ end
230
+ it "request body using a Hash with Array" do
231
+ request.body = {:foo => :bar, :baz => [:foo, :tst]}
232
+ expect(request.body.split("&")).to match_array(["foo=bar", "baz[]=foo", "baz[]=tst"])
233
+ end
234
+ end
179
235
  end
180
236
  end
181
237
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
4
+ version: 2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -9,90 +9,90 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-03 00:00:00.000000000 Z
12
+ date: 2014-09-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ! '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ! '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rubyntlm
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ~>
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
34
  version: 0.3.2
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ~>
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: 0.3.2
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ~>
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '10.0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ~>
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '10.0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rspec
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ~>
60
+ - - "~>"
61
61
  - !ruby/object:Gem::Version
62
62
  version: '2.14'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '2.14'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: mocha
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - ~>
74
+ - - "~>"
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0.13'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - ~>
81
+ - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0.13'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: puma
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ~>
88
+ - - "~>"
89
89
  - !ruby/object:Gem::Version
90
90
  version: 2.3.2
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - ~>
95
+ - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: 2.3.2
98
98
  description: Common interface for Ruby's HTTP libraries
@@ -101,9 +101,9 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
- - .gitignore
105
- - .rspec
106
- - .travis.yml
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
107
  - CHANGELOG.md
108
108
  - Gemfile
109
109
  - LICENSE
@@ -126,6 +126,7 @@ files:
126
126
  - lib/httpi/cookie_store.rb
127
127
  - lib/httpi/dime.rb
128
128
  - lib/httpi/logger.rb
129
+ - lib/httpi/query_builder.rb
129
130
  - lib/httpi/request.rb
130
131
  - lib/httpi/response.rb
131
132
  - lib/httpi/version.rb
@@ -167,7 +168,7 @@ files:
167
168
  - spec/support/error_helper.rb
168
169
  - spec/support/fixture.rb
169
170
  - spec/support/matchers.rb
170
- homepage: http://github.com/savonrb/#{s.name}
171
+ homepage: http://github.com/savonrb/httpi
171
172
  licenses:
172
173
  - MIT
173
174
  metadata: {}
@@ -177,17 +178,17 @@ require_paths:
177
178
  - lib
178
179
  required_ruby_version: !ruby/object:Gem::Requirement
179
180
  requirements:
180
- - - ! '>='
181
+ - - ">="
181
182
  - !ruby/object:Gem::Version
182
183
  version: '0'
183
184
  required_rubygems_version: !ruby/object:Gem::Requirement
184
185
  requirements:
185
- - - ! '>='
186
+ - - ">="
186
187
  - !ruby/object:Gem::Version
187
188
  version: '0'
188
189
  requirements: []
189
190
  rubyforge_project: httpi
190
- rubygems_version: 2.0.3
191
+ rubygems_version: 2.2.2
191
192
  signing_key:
192
193
  specification_version: 4
193
194
  summary: Common interface for Ruby's HTTP libraries