rest-core 3.3.0 → 3.3.1

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: 2aa111679bf7c7b75c113cea9c30e4c52c709ed0
4
- data.tar.gz: fe0dda1aea907ef4141f7125a7dfb9a881d42441
3
+ metadata.gz: b544b95ad58c9315600c3951222e0aea815d0418
4
+ data.tar.gz: 35eece46344f61ed05425d7572195b61a0b4f2b5
5
5
  SHA512:
6
- metadata.gz: 4e634ba680b5cca9604ea54a5182e0afe161bf44e80b1f7748d8ffc922429023fb99fd009aea9a3c4b001b5531e9de315947de3db6229020de30c2bc88b8d9c7
7
- data.tar.gz: 1a110e340a1f5e64e5ede750e6bca7a9ef38fa2137d27c53e900be9026b0d8d8f61664e7fc7032954bcb975ea45a6eea221e74ea7e01c9a62b3ca89c19f0b225
6
+ metadata.gz: 9f093b4836251cec01ecb5b467d6d51eefeebc4dd62a35b1a08b6d9ffbe30ad579007cbda0fb821554562012385fa94955abe4cf99450b1aa79001e73560da7b
7
+ data.tar.gz: 1de6772803cf5d8771b2ad32cc0ea80daae686ae53ed46516e9aabf526174199fa7dec7540d3b858c1789d1dba16ec61bbe9c233d3651ac47bc89fa6ff71eec7
data/CHANGES.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-core 3.3.1 -- 2014-10-08
4
+
5
+ * `RC::Oauth1Header` would now properly encode queries in oauth_callback.
6
+ rest-more#6 khoa nguyen (@khoan)
7
+
8
+ * Made all literal regular expression UTF-8 encoded, fixing encoding issue
9
+ on JRuby. #10 Joe Chen (@joe1chen)
10
+
11
+ * Now `RC::DefaultSite` would use `URI.join` to prepend the default site,
12
+ therefore eliminating duplicated / or missing /. #11 Man Vuong (@kidlab)
13
+
14
+ * Fixed deprecation warnings from `URI.escape`. Lin Jen-Shin (@godfat)
15
+
16
+ * Now we properly wait for the callback to be called to consider the request
17
+ is done. Lin Jen-Shin (@godfat)
18
+
3
19
  ## rest-core 3.3.0 -- 2014-08-25
4
20
 
5
21
  ### Incompatible changes
data/README.md CHANGED
@@ -14,7 +14,6 @@ talk is in Mandarin.
14
14
  * [github](https://github.com/godfat/rest-core)
15
15
  * [rubygems](https://rubygems.org/gems/rest-core)
16
16
  * [rdoc](http://rdoc.info/projects/godfat/rest-core)
17
- * [mailing list](http://groups.google.com/group/rest-core/topics)
18
17
 
19
18
  ## DESCRIPTION:
20
19
 
@@ -714,10 +713,12 @@ and complete.
714
713
  * Ethan Czahor (@ethanz5)
715
714
  * Florent Vaucelle (@florent)
716
715
  * Jaime Cham (@jcham)
716
+ * Joe Chen (@joe1chen)
717
717
  * John Fan (@johnfan)
718
718
  * khoa nguyen (@khoan)
719
719
  * Lin Jen-Shin (@godfat)
720
720
  * lulalala (@lulalala)
721
+ * Man Vuong (@kidlab)
721
722
  * Mariusz Pruszynski (@snicky)
722
723
  * Mr. Big Cat (@miaout17)
723
724
  * Nicolas Fouché (@nfo)
data/Rakefile CHANGED
@@ -12,5 +12,5 @@ Gemgem.init(dir) do |s|
12
12
  s.version = RestCore::VERSION
13
13
  s.homepage = 'https://github.com/godfat/rest-core'
14
14
  %w[httpclient mime-types].each{ |g| s.add_runtime_dependency(g) }
15
- s.add_runtime_dependency('timers', '<4')
15
+ s.add_runtime_dependency('timers', '>=4.0.1')
16
16
  end
data/lib/rest-core.rb CHANGED
@@ -90,7 +90,7 @@ module RestCore
90
90
  c = const.const_get(n)
91
91
  rescue LoadError, NameError => e
92
92
  warn "RestCore: WARN: #{e} for #{const}\n" \
93
- " from #{e.backtrace.grep(/top.+required/).first}"
93
+ " from #{e.backtrace.grep(/top.+required/u).first}"
94
94
  end
95
95
  eagerload(c, loaded) if c.respond_to?(:constants) && !loaded[n]
96
96
  }
@@ -37,13 +37,8 @@ class RestCore::Builder
37
37
  end
38
38
 
39
39
  def members
40
- middles.map{ |(middle, args, block)|
41
- if middle.public_method_defined?(:wrapped)
42
- # TODO: this is hacky... try to avoid calling new!
43
- middle.members + middle.new(Dry.new, *args, &block).members
44
- else
45
- middle.members
46
- end if middle.respond_to?(:members)
40
+ middles.map{ |(middle, _, _)|
41
+ middle.members if middle.respond_to?(:members)
47
42
  }.flatten.compact
48
43
  end
49
44
 
@@ -25,9 +25,6 @@ module RestCore::Client
25
25
  self.class.default_#{name} # old class default style
26
26
  elsif app.respond_to?(:#{name})
27
27
  app.#{name}({}) # middleware instance value
28
- elsif app.respond_to?(:wrapped)
29
- default_#{name}(app.wrapped) || # wrapper value
30
- default_#{name}(app.app) # walk into it
31
28
  elsif app.respond_to?(:app)
32
29
  default_#{name}(app.app) # walk into next app
33
30
  else
@@ -60,7 +57,7 @@ module RestCore::Client
60
57
  def inspect
61
58
  fields = if size > 0
62
59
  ' ' + attributes.map{ |k, v|
63
- "#{k}=#{v.inspect.sub(/(?<=.{12}).{4,}/, '...')}"
60
+ "#{k}=#{v.inspect.sub(/(?<=.{12}).{4,}/u, '...')}"
64
61
  }.join(', ')
65
62
  else
66
63
  ''
@@ -249,14 +246,7 @@ module RestCore::Client
249
246
  end
250
247
 
251
248
  if app.respond_to?(:app) && app.app
252
- wrapped = if app.respond_to?(:wrapped) && app.wrapped
253
- lighten_app(app.wrapped)
254
- else
255
- nil
256
- end
257
- app.class.new(lighten_app(app.app), *members){
258
- @wrapped = wrapped if wrapped
259
- }
249
+ app.class.new(lighten_app(app.app), *members)
260
250
  else
261
251
  app.class.new(*members)
262
252
  end
@@ -5,7 +5,7 @@ module RestCore
5
5
 
6
6
  class Event < EventStruct
7
7
  # self.class.name[/(?<=::)\w+$/] if RUBY_VERSION >= '1.9.2'
8
- def name; self.class.name[/::(\w+)$/, 1] ; end
8
+ def name; self.class.name[/::(\w+)$/u, 1] ; end
9
9
  def to_s; "spent #{duration} #{name} #{message}"; end
10
10
  end
11
11
  class Event::MultiDone < Event; end
@@ -64,7 +64,7 @@ module RestCore::Middleware
64
64
  if (query = (env[REQUEST_QUERY] || {}).select{ |k, v| v }).empty?
65
65
  env[REQUEST_PATH].to_s
66
66
  else
67
- q = if env[REQUEST_PATH] =~ /\?/ then '&' else '?' end
67
+ q = if env[REQUEST_PATH] =~ /\?/u then '&' else '?' end
68
68
  "#{env[REQUEST_PATH]}#{q}#{percent_encode(query)}"
69
69
  end
70
70
  end
@@ -81,9 +81,11 @@ module RestCore::Middleware
81
81
  end
82
82
  public :percent_encode
83
83
 
84
- UNRESERVED = /[^a-zA-Z0-9\-\.\_\~]/
84
+ UNRESERVED = /[^a-zA-Z0-9\-\.\_\~]+/u
85
85
  def escape string
86
- URI.escape(string, UNRESERVED)
86
+ string.gsub(UNRESERVED) do |s|
87
+ "%#{s.unpack('H2' * s.bytesize).join('%')}".upcase
88
+ end
87
89
  end
88
90
  public :escape
89
91
 
@@ -99,10 +99,10 @@ class RestCore::Cache
99
99
 
100
100
  def data_extract data, env, k
101
101
  _, status, headers, body =
102
- data.match(/\A(\d+)\n((?:[^\n]+\n)*)\n\n(.*)\Z/m).to_a
102
+ data.match(/\A(\d+)\n((?:[^\n]+\n)*)\n\n(.*)\Z/um).to_a
103
103
 
104
104
  Promise.claim(env, k, body,status.to_i,
105
- Hash[(headers||'').scan(/([^:]+): ([^\n]+)\n/)]).future_response
105
+ Hash[(headers||'').scan(/([^:]+): ([^\n]+)\n/u)]).future_response
106
106
  end
107
107
 
108
108
  def cache_for? env
@@ -6,8 +6,10 @@ class RestCore::DefaultSite
6
6
  include RestCore::Middleware
7
7
 
8
8
  def call env, &k
9
- path = if env[REQUEST_PATH].to_s.start_with?('http')
9
+ path = if env[REQUEST_PATH].to_s.include?('://')
10
10
  env[REQUEST_PATH]
11
+ elsif site(env).to_s.include?('://')
12
+ URI.join(site(env), env[REQUEST_PATH]).to_s
11
13
  else
12
14
  "#{site(env)}#{env[REQUEST_PATH]}"
13
15
  end
@@ -30,7 +30,7 @@ class RestCore::JsonResponse
30
30
  def process response
31
31
  # StackExchange returns the problematic BOM! in UTF-8, so we need to
32
32
  # strip it or it would break JSON parsers (i.e. yajl-ruby and json)
33
- body = response[RESPONSE_BODY].to_s.sub(/\A\xEF\xBB\xBF/, '')
33
+ body = response[RESPONSE_BODY].to_s.sub(/\A\xEF\xBB\xBF/u, '')
34
34
  response.merge(RESPONSE_BODY => Json.decode("[#{body}]").first)
35
35
  # [this].first is not needed for yajl-ruby
36
36
  rescue Json.const_get(:ParseError) => error
@@ -26,7 +26,7 @@ class RestCore::Oauth1Header
26
26
  end
27
27
 
28
28
  def oauth_header env
29
- header = attach_signature(env,
29
+ oauth = attach_signature(env,
30
30
  'oauth_consumer_key' => consumer_key(env),
31
31
  'oauth_signature_method' => 'HMAC-SHA1',
32
32
  'oauth_timestamp' => Time.now.to_i.to_s,
@@ -34,14 +34,15 @@ class RestCore::Oauth1Header
34
34
  'oauth_version' => '1.0',
35
35
  'oauth_callback' => oauth_callback(env),
36
36
  'oauth_verifier' => oauth_verifier(env),
37
- 'oauth_token' => oauth_token(env))
37
+ 'oauth_token' => oauth_token(env)).
38
+ map{ |(k, v)| "#{k}=\"#{escape(v)}\"" }.join(', ')
38
39
 
39
- "OAuth #{header.map{ |(k, v)| "#{k}=\"#{v}\"" }.join(', ')}"
40
+ "OAuth #{oauth}"
40
41
  end
41
42
 
42
43
  def attach_signature env, oauth_params
43
44
  params = reject_blank(oauth_params)
44
- params.merge('oauth_signature' => escape(signature(env, params)))
45
+ params.merge('oauth_signature' => signature(env, params))
45
46
  end
46
47
 
47
48
  def signature env, params
@@ -9,7 +9,7 @@ module RestClient
9
9
  # Follow a redirection
10
10
  def follow_redirection request = nil, result = nil, & block
11
11
  url = headers[:location]
12
- if url !~ /^http/
12
+ if url !~ /^http/u
13
13
  url = URI.parse(args[:url]).merge(url).to_s
14
14
  end
15
15
  args[:url] = url
@@ -26,8 +26,8 @@ class RestCore::Promise
26
26
  self.k = [k]
27
27
  self.immediate = immediate
28
28
 
29
- self.body, self.status, self.headers,
30
- self.socket, self.response, self.error, = nil
29
+ self.body, self.status, self.headers, self.socket,
30
+ self.response, self.error, self.called = nil
31
31
 
32
32
  self.condv = ConditionVariable.new
33
33
  self.mutex = Mutex.new
@@ -70,7 +70,7 @@ class RestCore::Promise
70
70
  # called in client thread (client.wait)
71
71
  def wait
72
72
  # it might be awaken by some other futures!
73
- mutex.synchronize{ condv.wait(mutex) until !!status } unless !!status
73
+ mutex.synchronize{ condv.wait(mutex) until done? } unless done?
74
74
  end
75
75
 
76
76
  # called in client thread (from the future (e.g. body))
@@ -107,9 +107,18 @@ class RestCore::Promise
107
107
  self
108
108
  end
109
109
 
110
+ # It's considered done only if the HTTP request is done, and we're not
111
+ # in asynchronous mode otherwise the callback should be called first.
112
+ # For synchronous mode, since we're waiting for the callback anyway,
113
+ # we don't really have to check if it's called.
114
+ def done?
115
+ !!status && !(immediate && !called)
116
+ end
117
+
110
118
  protected
111
119
  attr_accessor :env, :k, :immediate,
112
- :response, :body, :status, :headers, :socket, :error,
120
+ :body, :status, :headers, :socket,
121
+ :response, :error, :called,
113
122
  :condv, :mutex, :task
114
123
 
115
124
  private
@@ -127,13 +136,16 @@ class RestCore::Promise
127
136
 
128
137
  # called in client thread, when yield is called
129
138
  def callback
130
- self.response ||= k.inject(
139
+ return response if called
140
+ self.response = k.inject(
131
141
  env.merge(RESPONSE_BODY => body ,
132
142
  RESPONSE_STATUS => status,
133
143
  RESPONSE_HEADERS => headers,
134
144
  RESPONSE_SOCKET => socket,
135
145
  FAIL => ((env[FAIL]||[]) + [error]).compact,
136
146
  LOG => env[LOG] ||[])){ |r, i| i.call(r) }
147
+ self.called = true
148
+ response
137
149
  end
138
150
 
139
151
  # called in requesting thread, whenever the request is done
@@ -4,12 +4,12 @@ module RestCore::ParseLink
4
4
  module_function
5
5
  # http://tools.ietf.org/html/rfc5988
6
6
  parname = '"?([^"]+)"?'
7
- LINKPARAM = /#{parname}=#{parname}/
7
+ LINKPARAM = /#{parname}=#{parname}/u
8
8
  def parse_link link
9
9
  link.split(',').inject({}) do |r, value|
10
10
  uri, *pairs = value.split(';')
11
11
  params = Hash[pairs.map{ |p| p.strip.match(LINKPARAM)[1..2] }]
12
- r[params['rel']] = params.merge('uri' => uri[/<([^>]+)>/, 1])
12
+ r[params['rel']] = params.merge('uri' => uri[/<([^>]+)>/u, 1])
13
13
  r
14
14
  end
15
15
  end
@@ -12,7 +12,7 @@ module RestCore::ParseQuery
12
12
  def parse_query(qs, d = nil)
13
13
  params = {}
14
14
 
15
- (qs || '').split(d ? /[#{d}] */n : /[&;] */n).each do |p|
15
+ (qs || '').split(d ? /[#{d}] */un : /[&;] */un).each do |p|
16
16
  k, v = p.split('=', 2).map { |x| URI.decode_www_form_component(x) }
17
17
  if cur = params[k]
18
18
  if cur.class == Array
@@ -1,4 +1,4 @@
1
1
 
2
2
  module RestCore
3
- VERSION = '3.3.0'
3
+ VERSION = '3.3.1'
4
4
  end
data/rest-core.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: rest-core 3.3.0 ruby lib
2
+ # stub: rest-core 3.3.1 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rest-core"
6
- s.version = "3.3.0"
6
+ s.version = "3.3.1"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Lin Jen-Shin (godfat)"]
11
- s.date = "2014-08-25"
11
+ s.date = "2014-10-08"
12
12
  s.description = "Modular Ruby clients interface for REST APIs.\n\nThere has been an explosion in the number of REST APIs available today.\nTo address the need for a way to access these APIs easily and elegantly,\nwe have developed rest-core, which consists of composable middleware\nthat allows you to build a REST client for any REST API. Or in the case of\ncommon APIs such as Facebook, Github, and Twitter, you can simply use the\ndedicated clients provided by [rest-more][].\n\n[rest-more]: https://github.com/godfat/rest-more"
13
13
  s.email = ["godfat (XD) godfat.org"]
14
14
  s.files = [
@@ -91,6 +91,7 @@ Gem::Specification.new do |s|
91
91
  "test/test_default_headers.rb",
92
92
  "test/test_default_payload.rb",
93
93
  "test/test_default_query.rb",
94
+ "test/test_default_site.rb",
94
95
  "test/test_error_detector.rb",
95
96
  "test/test_error_detector_http.rb",
96
97
  "test/test_error_handler.rb",
@@ -114,7 +115,7 @@ Gem::Specification.new do |s|
114
115
  "test/test_universal.rb"]
115
116
  s.homepage = "https://github.com/godfat/rest-core"
116
117
  s.licenses = ["Apache License 2.0"]
117
- s.rubygems_version = "2.4.1"
118
+ s.rubygems_version = "2.4.2"
118
119
  s.summary = "Modular Ruby clients interface for REST APIs."
119
120
  s.test_files = [
120
121
  "test/test_auth_basic.rb",
@@ -128,6 +129,7 @@ Gem::Specification.new do |s|
128
129
  "test/test_default_headers.rb",
129
130
  "test/test_default_payload.rb",
130
131
  "test/test_default_query.rb",
132
+ "test/test_default_site.rb",
131
133
  "test/test_error_detector.rb",
132
134
  "test/test_error_detector_http.rb",
133
135
  "test/test_error_handler.rb",
@@ -156,15 +158,15 @@ Gem::Specification.new do |s|
156
158
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
157
159
  s.add_runtime_dependency(%q<httpclient>, [">= 0"])
158
160
  s.add_runtime_dependency(%q<mime-types>, [">= 0"])
159
- s.add_runtime_dependency(%q<timers>, ["< 4"])
161
+ s.add_runtime_dependency(%q<timers>, [">= 4.0.1"])
160
162
  else
161
163
  s.add_dependency(%q<httpclient>, [">= 0"])
162
164
  s.add_dependency(%q<mime-types>, [">= 0"])
163
- s.add_dependency(%q<timers>, ["< 4"])
165
+ s.add_dependency(%q<timers>, [">= 4.0.1"])
164
166
  end
165
167
  else
166
168
  s.add_dependency(%q<httpclient>, [">= 0"])
167
169
  s.add_dependency(%q<mime-types>, [">= 0"])
168
- s.add_dependency(%q<timers>, ["< 4"])
170
+ s.add_dependency(%q<timers>, [">= 4.0.1"])
169
171
  end
170
172
  end
data/test/test_cache.rb CHANGED
@@ -130,7 +130,7 @@ describe RC::Cache do
130
130
 
131
131
  would 'preserve promise and preserve wrapped call' do
132
132
  c = json_client
133
- stub_request(:get, 'http://me').to_return(:body => body = '{"a":"b"}')
133
+ stub_request(:get, 'http://me').to_return(:body => '{"a":"b"}')
134
134
  args = ['http://me', {}, {RC::RESPONSE_KEY => RC::PROMISE}]
135
135
  2.times do
136
136
  c.get(*args).then{ |r| r[RC::RESPONSE_BODY].should.eq 'a' => 'b' }.yield
data/test/test_client.rb CHANGED
@@ -58,6 +58,26 @@ describe RC::Simple do
58
58
  i.should.eq t
59
59
  end
60
60
 
61
+ would 'wait for callback' do
62
+ rd, wr = IO.pipe
63
+ called = false
64
+ stub_request(:get, url).to_return(:body => 'nnf')
65
+ client = RC::Builder.client.new.get(url) do |nnf|
66
+ wr.puts
67
+ sleep 0.001 # make sure our callback is slow enough,
68
+ # so that if `wait` is not waiting for the callback,
69
+ # it would leave before the callback is completely done.
70
+ # without sleeping, the callback is very likely to be
71
+ # done first than `wait` anyway. raising the sleeping time
72
+ # would make this test more reliable...
73
+ called = true
74
+ nil # test against returning nil, so that Promise#response is not set
75
+ end
76
+ rd.gets
77
+ client.wait
78
+ called.should.eq true
79
+ end
80
+
61
81
  would 'cleanup promises' do
62
82
  stub_request(:get, url)
63
83
  client = RC::Builder.client
@@ -0,0 +1,24 @@
1
+
2
+ require 'rest-core/test'
3
+
4
+ describe RC::DefaultSite do
5
+ app = RC::DefaultSite.new(RC::Dry.new, 'http://example.com/')
6
+
7
+ would 'leave site along if it already has a protocol' do
8
+ app.call(RC::REQUEST_PATH => 'http://nnf.tw') do |res|
9
+ res[RC::REQUEST_PATH].should.eq 'http://nnf.tw'
10
+ end
11
+ end
12
+
13
+ would 'prepend the site if there is no protocol' do
14
+ app.call(RC::REQUEST_PATH => 'nnf.tw') do |res|
15
+ res[RC::REQUEST_PATH].should.eq 'http://example.com/nnf.tw'
16
+ end
17
+ end
18
+
19
+ would 'not prepend duplicated /' do
20
+ app.call(RC::REQUEST_PATH => '/nnf.tw') do |res|
21
+ res[RC::REQUEST_PATH].should.eq 'http://example.com/nnf.tw'
22
+ end
23
+ end
24
+ end
@@ -24,9 +24,28 @@ describe RC::Oauth1Header do
24
24
  'GDdmIQH6jhtmLUypg82g',
25
25
  'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98')
26
26
 
27
+ sig = '8wUi7m5HFQy76nowoCThusfgB+Q='
28
+
29
+ after do
30
+ Muack.verify
31
+ end
32
+
27
33
  would 'have correct signature' do
28
- auth.signature(env, oauth_params).should.eq(
29
- '8wUi7m5HFQy76nowoCThusfgB+Q=')
34
+ auth.signature(env, oauth_params).should.eq(sig)
35
+ end
36
+
37
+ would 'escape keys and values' do
38
+ mock(Time).now{
39
+ mock.to_i{
40
+ mock.to_s{
41
+ oauth_params['oauth_timestamp'] }.object }.object }
42
+ mock(auth).nonce{ oauth_params['oauth_nonce'] }
43
+
44
+ oauth = auth.oauth_header(env.merge(oauth_params))
45
+ oauth.should.
46
+ include?("oauth_callback=\"#{RC::Middleware.escape(callback)}\"")
47
+ oauth.should.
48
+ include?("oauth_signature=\"#{RC::Middleware.escape(sig)}\"")
30
49
  end
31
50
 
32
51
  describe 'base_string' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lin Jen-Shin (godfat)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-25 00:00:00.000000000 Z
11
+ date: 2014-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: timers
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "<"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '4'
47
+ version: 4.0.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "<"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '4'
54
+ version: 4.0.1
55
55
  description: |-
56
56
  Modular Ruby clients interface for REST APIs.
57
57
 
@@ -148,6 +148,7 @@ files:
148
148
  - test/test_default_headers.rb
149
149
  - test/test_default_payload.rb
150
150
  - test/test_default_query.rb
151
+ - test/test_default_site.rb
151
152
  - test/test_error_detector.rb
152
153
  - test/test_error_detector_http.rb
153
154
  - test/test_error_handler.rb
@@ -189,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
190
  version: '0'
190
191
  requirements: []
191
192
  rubyforge_project:
192
- rubygems_version: 2.4.1
193
+ rubygems_version: 2.4.2
193
194
  signing_key:
194
195
  specification_version: 4
195
196
  summary: Modular Ruby clients interface for REST APIs.
@@ -205,6 +206,7 @@ test_files:
205
206
  - test/test_default_headers.rb
206
207
  - test/test_default_payload.rb
207
208
  - test/test_default_query.rb
209
+ - test/test_default_site.rb
208
210
  - test/test_error_detector.rb
209
211
  - test/test_error_detector_http.rb
210
212
  - test/test_error_handler.rb