rest-core 3.0.0 → 3.1.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/.travis.yml +1 -1
- data/CHANGES.md +32 -1
- data/README.md +35 -8
- data/lib/rest-core/builder.rb +2 -1
- data/lib/rest-core/client/universal.rb +1 -0
- data/lib/rest-core/client.rb +15 -12
- data/lib/rest-core/engine/http-client.rb +2 -2
- data/lib/rest-core/engine/net-http-persistent.rb +1 -1
- data/lib/rest-core/engine/rest-client.rb +1 -1
- data/lib/rest-core/engine.rb +4 -3
- data/lib/rest-core/event_source.rb +37 -13
- data/lib/rest-core/middleware/cache.rb +2 -1
- data/lib/rest-core/middleware/follow_redirect.rb +3 -3
- data/lib/rest-core/middleware/query_response.rb +23 -0
- data/lib/rest-core/thread_pool.rb +1 -0
- data/lib/rest-core/util/config.rb +50 -0
- data/lib/rest-core/util/json.rb +1 -1
- data/lib/rest-core/version.rb +1 -1
- data/lib/rest-core.rb +4 -0
- data/rest-core.gemspec +10 -3
- data/test/config/rest-core.yaml +8 -0
- data/test/test_cache.rb +13 -1
- data/test/test_config.rb +28 -0
- data/test/test_error_handler.rb +1 -1
- data/test/test_event_source.rb +72 -15
- data/test/test_follow_redirect.rb +23 -6
- data/test/test_query_response.rb +49 -0
- data/test/test_rest-client.rb +3 -2
- data/test/test_simple.rb +29 -6
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 070bdd0392158ac265903b7e713245a18933aaa8
|
4
|
+
data.tar.gz: 015edd1a6221a2a0b55dc04958dbed0df1729ecf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30bcbb75a17c797b3ebf823d5e46837209bd628df0abc0190f9d67823f4367b1556a1f11461befb176400aba3863ec920561f503da32dd1edc00682e9e2b44a9
|
7
|
+
data.tar.gz: fd18d5ecd9cb318c9b8ce3616c3f7432bd55ea43b6c517ea0bbc21a8d33670b0fca238678b08faf25b6c80b95f3c9d6be449a69a6b74ecb929ea90995b49b4ce
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
-
## rest-core 3.
|
3
|
+
## rest-core 3.1.0 -- 2014-05-09
|
4
|
+
|
5
|
+
### Incompatible changes
|
6
|
+
|
7
|
+
* Now that the second argument `key` in `RC::Client#request` is replaced by
|
8
|
+
`RC::RESPONSE_KEY` passed in env. This would make it easier to use and
|
9
|
+
more consistent internally.
|
10
|
+
* Now RC::EventSource#onmessage would receive the event in the first argument,
|
11
|
+
and the data in the second argument instead of a hash in the first argument.
|
12
|
+
|
13
|
+
### Enhancement
|
14
|
+
|
15
|
+
* Added RC::REQUEST_URI in the env so that we could access the requesting
|
16
|
+
URI easily.
|
17
|
+
* Added middleware RC::QueryResponse which could parse query in response.
|
18
|
+
* Added RC::Client.event_source_class which we could easily swap the class
|
19
|
+
used for event_source. Used in Firebase client to parse data in JSON.
|
20
|
+
* Now methods in RC::EventSource would return itself so that we could chain
|
21
|
+
callbacks.
|
22
|
+
* Added RC::EventSource#onreconnect callback to handle if we're going to
|
23
|
+
reconnect automatically or not.
|
24
|
+
* RC::Config was extracted from rest-more, which could help us manage config
|
25
|
+
files.
|
26
|
+
* RC::Json using JSON would now parse in quirks_mode, so that it could parse
|
27
|
+
not only JSON but also a single value.
|
28
|
+
|
29
|
+
### Bugs Fixes
|
30
|
+
|
31
|
+
* We should never cache hijacked requests.
|
32
|
+
* Now we preserve payload and properly ignore query for RC::FollowRedirect.
|
33
|
+
|
34
|
+
## rest-core 3.0.0 -- 2014-05-04
|
4
35
|
|
5
36
|
Highlights:
|
6
37
|
|
data/README.md
CHANGED
@@ -280,17 +280,44 @@ Not only JavaScript could receive server-sent events, any languages could.
|
|
280
280
|
Doing so would establish a keep-alive connection to the server, and receive
|
281
281
|
data periodically. We'll take Firebase as an example:
|
282
282
|
|
283
|
+
If you are using Firebase, please consider the pre-built client in
|
284
|
+
[rest-more][] instead.
|
285
|
+
|
283
286
|
``` ruby
|
284
|
-
|
285
|
-
|
287
|
+
require 'rest-core'
|
288
|
+
|
289
|
+
# Streaming over 'users/tom.json'
|
290
|
+
cl = RC::Universal.new(:site => 'https://SampleChat.firebaseIO-demo.com/')
|
291
|
+
es = cl.event_source('users/tom.json', {}, # this is query, none here
|
292
|
+
:headers => {'Accept' => 'text/event-stream'})
|
293
|
+
|
294
|
+
@reconnect = true
|
295
|
+
|
296
|
+
es.onopen { |sock| p sock } # Called when connected
|
297
|
+
es.onmessage{ |event, data, sock| p event, data } # Called for each message
|
298
|
+
es.onerror { |error, sock| p error } # Called whenever there's an error
|
299
|
+
# Extra: If we return true in onreconnect callback, it would automatically
|
300
|
+
# reconnect the node for us if disconnected.
|
301
|
+
es.onreconnect{ |error, sock| p error; @reconnect }
|
302
|
+
|
303
|
+
# Start making the request
|
304
|
+
es.start
|
305
|
+
|
306
|
+
# Try to close the connection and see it reconnects automatically
|
307
|
+
es.close
|
308
|
+
|
309
|
+
# Update users/tom.json
|
310
|
+
p cl.put('users/tom.json', RC::Json.encode(:some => 'data'))
|
311
|
+
p cl.post('users/tom.json', RC::Json.encode(:some => 'other'))
|
312
|
+
p cl.get('users/tom.json')
|
313
|
+
p cl.delete('users/tom.json')
|
286
314
|
|
287
|
-
|
288
|
-
|
289
|
-
|
315
|
+
# Need to tell onreconnect stops reconnecting, or even if we close
|
316
|
+
# the connection manually, it would still try to reconnect again.
|
317
|
+
@reconnect = false
|
290
318
|
|
291
|
-
|
292
|
-
|
293
|
-
es.close # Close the connection when we're done
|
319
|
+
# Close the connection to gracefully shut it down.
|
320
|
+
es.close
|
294
321
|
```
|
295
322
|
|
296
323
|
Those callbacks would be called in a separate background thread,
|
data/lib/rest-core/builder.rb
CHANGED
@@ -26,7 +26,7 @@ class RestCore::Builder
|
|
26
26
|
client.send(:include, Client)
|
27
27
|
class << client
|
28
28
|
attr_reader :builder
|
29
|
-
attr_accessor :pool_size, :pool_idle_time
|
29
|
+
attr_accessor :pool_size, :pool_idle_time, :event_source_class
|
30
30
|
|
31
31
|
def thread_pool
|
32
32
|
RestCore::ThreadPool[self]
|
@@ -35,6 +35,7 @@ class RestCore::Builder
|
|
35
35
|
client.instance_variable_set(:@builder, self)
|
36
36
|
client.instance_variable_set(:@pool_size, 0) # default to no pool
|
37
37
|
client.instance_variable_set(:@pool_idle_time, 60) # default to 60 seconds
|
38
|
+
client.instance_variable_set(:@event_source_class, EventSource)
|
38
39
|
client
|
39
40
|
end
|
40
41
|
|
data/lib/rest-core/client.rb
CHANGED
@@ -111,28 +111,30 @@ module RestCore::Client
|
|
111
111
|
request(
|
112
112
|
{REQUEST_METHOD => :get ,
|
113
113
|
REQUEST_PATH => path ,
|
114
|
-
REQUEST_QUERY => query }.merge(opts),
|
114
|
+
REQUEST_QUERY => query }.merge(opts), &cb)
|
115
115
|
end
|
116
116
|
|
117
117
|
def delete path, query={}, opts={}, &cb
|
118
118
|
request(
|
119
119
|
{REQUEST_METHOD => :delete,
|
120
120
|
REQUEST_PATH => path ,
|
121
|
-
REQUEST_QUERY => query }.merge(opts),
|
121
|
+
REQUEST_QUERY => query }.merge(opts), &cb)
|
122
122
|
end
|
123
123
|
|
124
124
|
def head path, query={}, opts={}, &cb
|
125
125
|
request(
|
126
126
|
{REQUEST_METHOD => :head ,
|
127
127
|
REQUEST_PATH => path ,
|
128
|
-
REQUEST_QUERY => query
|
128
|
+
REQUEST_QUERY => query ,
|
129
|
+
RESPONSE_KEY => RESPONSE_HEADERS}.merge(opts), &cb)
|
129
130
|
end
|
130
131
|
|
131
132
|
def options path, query={}, opts={}, &cb
|
132
133
|
request(
|
133
134
|
{REQUEST_METHOD => :options,
|
134
135
|
REQUEST_PATH => path ,
|
135
|
-
REQUEST_QUERY => query
|
136
|
+
REQUEST_QUERY => query ,
|
137
|
+
RESPONSE_KEY => RESPONSE_HEADERS}.merge(opts), &cb)
|
136
138
|
end
|
137
139
|
|
138
140
|
def post path, payload={}, query={}, opts={}, &cb
|
@@ -140,7 +142,7 @@ module RestCore::Client
|
|
140
142
|
{REQUEST_METHOD => :post ,
|
141
143
|
REQUEST_PATH => path ,
|
142
144
|
REQUEST_QUERY => query ,
|
143
|
-
REQUEST_PAYLOAD => payload}.merge(opts),
|
145
|
+
REQUEST_PAYLOAD => payload}.merge(opts), &cb)
|
144
146
|
end
|
145
147
|
|
146
148
|
def put path, payload={}, query={}, opts={}, &cb
|
@@ -148,7 +150,7 @@ module RestCore::Client
|
|
148
150
|
{REQUEST_METHOD => :put ,
|
149
151
|
REQUEST_PATH => path ,
|
150
152
|
REQUEST_QUERY => query ,
|
151
|
-
REQUEST_PAYLOAD => payload}.merge(opts),
|
153
|
+
REQUEST_PAYLOAD => payload}.merge(opts), &cb)
|
152
154
|
end
|
153
155
|
|
154
156
|
def patch path, payload={}, query={}, opts={}, &cb
|
@@ -156,18 +158,18 @@ module RestCore::Client
|
|
156
158
|
{REQUEST_METHOD => :patch ,
|
157
159
|
REQUEST_PATH => path ,
|
158
160
|
REQUEST_QUERY => query ,
|
159
|
-
REQUEST_PAYLOAD => payload}.merge(opts),
|
161
|
+
REQUEST_PAYLOAD => payload}.merge(opts), &cb)
|
160
162
|
end
|
161
163
|
|
162
164
|
def event_source path, query={}, opts={}
|
163
|
-
|
165
|
+
self.class.event_source_class.new(self, path, query, opts)
|
164
166
|
end
|
165
167
|
|
166
|
-
def request env,
|
168
|
+
def request env, app=app
|
167
169
|
if block_given?
|
168
|
-
request_full(env, app){ |response| yield(response[
|
170
|
+
request_full(env, app){ |response| yield(response[response_key(env)]) }
|
169
171
|
else
|
170
|
-
request_full(env, app)[
|
172
|
+
request_full(env, app)[response_key(env)]
|
171
173
|
end
|
172
174
|
end
|
173
175
|
|
@@ -214,7 +216,8 @@ module RestCore::Client
|
|
214
216
|
end
|
215
217
|
|
216
218
|
def response_key opts
|
217
|
-
|
219
|
+
opts[RESPONSE_KEY] ||
|
220
|
+
if opts[HIJACK] then RESPONSE_SOCKET else RESPONSE_BODY end
|
218
221
|
end
|
219
222
|
|
220
223
|
def lighten_hash hash
|
@@ -24,7 +24,7 @@ class RestCore::HttpClient < RestCore::Engine
|
|
24
24
|
client.connect_timeout, client.receive_timeout =
|
25
25
|
calculate_timeout(env[TIMER])
|
26
26
|
|
27
|
-
res = client.request(env[REQUEST_METHOD],
|
27
|
+
res = client.request(env[REQUEST_METHOD], env[REQUEST_URI], nil,
|
28
28
|
payload, {'User-Agent' => 'Ruby'}.merge(headers))
|
29
29
|
|
30
30
|
promise.fulfill(res.content, res.status,
|
@@ -32,7 +32,7 @@ class RestCore::HttpClient < RestCore::Engine
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def request_async client, payload, headers, promise, env
|
35
|
-
res = client.request_async(env[REQUEST_METHOD],
|
35
|
+
res = client.request_async(env[REQUEST_METHOD], env[REQUEST_URI], nil,
|
36
36
|
payload, {'User-Agent' => 'Ruby'}.merge(headers)).pop
|
37
37
|
|
38
38
|
promise.fulfill('', res.status,
|
@@ -8,7 +8,7 @@ class RestCore::NetHttpPersistent < RestCore::Engine
|
|
8
8
|
http.open_timeout, http.read_timeout = calculate_timeout(env[TIMER])
|
9
9
|
payload, headers = payload_and_headers(env)
|
10
10
|
|
11
|
-
uri = ::URI.parse(
|
11
|
+
uri = ::URI.parse(env[REQUEST_URI])
|
12
12
|
req = ::Net::HTTP.const_get(env[REQUEST_METHOD].to_s.capitalize).
|
13
13
|
new(uri, headers)
|
14
14
|
req.body_stream = payload
|
@@ -8,7 +8,7 @@ class RestCore::RestClient < RestCore::Engine
|
|
8
8
|
open_timeout, read_timeout = calculate_timeout(env[TIMER])
|
9
9
|
payload, headers = payload_and_headers(env)
|
10
10
|
res = ::RestClient::Request.execute(:method => env[REQUEST_METHOD],
|
11
|
-
:url =>
|
11
|
+
:url => env[REQUEST_URI] ,
|
12
12
|
:payload => payload ,
|
13
13
|
:headers => headers ,
|
14
14
|
:max_redirects => 0 ,
|
data/lib/rest-core/engine.rb
CHANGED
@@ -6,9 +6,10 @@ class RestCore::Engine
|
|
6
6
|
include RestCore::Middleware
|
7
7
|
|
8
8
|
def call env, &k
|
9
|
-
|
10
|
-
promise.
|
11
|
-
|
9
|
+
req = env.merge(REQUEST_URI => request_uri(env))
|
10
|
+
promise = Promise.new(req, k, req[ASYNC])
|
11
|
+
promise.defer{ request(promise, req) }
|
12
|
+
req.merge(RESPONSE_BODY => promise.future_body,
|
12
13
|
RESPONSE_STATUS => promise.future_status,
|
13
14
|
RESPONSE_HEADERS => promise.future_headers,
|
14
15
|
RESPONSE_SOCKET => promise.future_socket,
|
@@ -8,13 +8,12 @@ class RestCore::EventSource < Struct.new(:client, :path, :query, :opts,
|
|
8
8
|
def start
|
9
9
|
self.mutex = Mutex.new
|
10
10
|
self.condv = ConditionVariable.new
|
11
|
-
@onopen
|
12
|
-
@
|
13
|
-
@onerror
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
client.get(path, query, o){ |sock| onopen(sock) }
|
11
|
+
@onopen ||= nil
|
12
|
+
@onmessage ||= nil
|
13
|
+
@onerror ||= nil
|
14
|
+
@onreconnect ||= nil
|
15
|
+
reconnect
|
16
|
+
self
|
18
17
|
end
|
19
18
|
|
20
19
|
def closed?
|
@@ -29,15 +28,18 @@ class RestCore::EventSource < Struct.new(:client, :path, :query, :opts,
|
|
29
28
|
def wait
|
30
29
|
raise RC::Error.new("Not yet started for: #{self}") unless mutex
|
31
30
|
mutex.synchronize{ condv.wait(mutex) until closed? } unless closed?
|
31
|
+
self
|
32
32
|
end
|
33
33
|
|
34
34
|
def onopen sock=nil, &cb
|
35
35
|
if block_given?
|
36
36
|
@onopen = cb
|
37
37
|
else
|
38
|
+
self.socket = sock # for you to track the socket
|
38
39
|
@onopen.call(sock) if @onopen
|
39
40
|
onmessage_for(sock)
|
40
41
|
end
|
42
|
+
self
|
41
43
|
rescue Exception => e
|
42
44
|
begin # close the socket since we're going to stop anyway
|
43
45
|
sock.close # if we don't close it, client might wait forever
|
@@ -47,12 +49,13 @@ class RestCore::EventSource < Struct.new(:client, :path, :query, :opts,
|
|
47
49
|
onerror(e, sock)
|
48
50
|
end
|
49
51
|
|
50
|
-
def onmessage event=nil, sock=nil, &cb
|
52
|
+
def onmessage event=nil, data=nil, sock=nil, &cb
|
51
53
|
if block_given?
|
52
54
|
@onmessage = cb
|
53
55
|
elsif @onmessage
|
54
|
-
@onmessage.call(event, sock)
|
56
|
+
@onmessage.call(event, data, sock)
|
55
57
|
end
|
58
|
+
self
|
56
59
|
end
|
57
60
|
|
58
61
|
# would also be called upon closing, would always be called at least once
|
@@ -62,10 +65,26 @@ class RestCore::EventSource < Struct.new(:client, :path, :query, :opts,
|
|
62
65
|
else
|
63
66
|
begin
|
64
67
|
@onerror.call(error, sock) if @onerror
|
65
|
-
|
66
|
-
|
68
|
+
onreconnect(error, sock)
|
69
|
+
rescue
|
70
|
+
condv.signal # so we can't be reconnecting, need to try to unblock
|
71
|
+
raise
|
67
72
|
end
|
68
73
|
end
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
# would be called upon closing,
|
78
|
+
# and would try to reconnect if a callback is set and return true
|
79
|
+
def onreconnect error=nil, sock=nil, &cb
|
80
|
+
if block_given?
|
81
|
+
@onreconnect = cb
|
82
|
+
elsif closed? && @onreconnect && @onreconnect.call(error, sock)
|
83
|
+
reconnect
|
84
|
+
else
|
85
|
+
condv.signal # we could be closing, let's try to unblock it
|
86
|
+
end
|
87
|
+
self
|
69
88
|
end
|
70
89
|
|
71
90
|
protected
|
@@ -74,18 +93,23 @@ class RestCore::EventSource < Struct.new(:client, :path, :query, :opts,
|
|
74
93
|
private
|
75
94
|
# called in requesting thread after the request is done
|
76
95
|
def onmessage_for sock
|
77
|
-
self.socket = sock # for you to track the socket
|
78
96
|
until sock.eof?
|
79
97
|
event = sock.readline("\n\n").split("\n").inject({}) do |r, i|
|
80
98
|
k, v = i.split(': ', 2)
|
81
99
|
r[k] = v
|
82
100
|
r
|
83
101
|
end
|
84
|
-
onmessage(event, sock)
|
102
|
+
onmessage(event['event'], event['data'], sock)
|
85
103
|
end
|
86
104
|
sock.close
|
87
105
|
onerror(EOFError.new, sock)
|
88
106
|
rescue IOError => e
|
89
107
|
onerror(e, sock)
|
90
108
|
end
|
109
|
+
|
110
|
+
def reconnect
|
111
|
+
o = {REQUEST_HEADERS => {'Accept' => 'text/event-stream'},
|
112
|
+
HIJACK => true}.merge(opts)
|
113
|
+
client.get(path, query, o){ |sock| onopen(sock) }
|
114
|
+
end
|
91
115
|
end
|
@@ -106,7 +106,8 @@ class RestCore::Cache
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def cache_for? env
|
109
|
-
[:get, :head, :otpions].include?(env[REQUEST_METHOD]) &&
|
109
|
+
[:get, :head, :otpions].include?(env[REQUEST_METHOD]) &&
|
110
|
+
!env[DRY] && !env[HIJACK]
|
110
111
|
end
|
111
112
|
|
112
113
|
def header_cache_key env
|
@@ -30,9 +30,9 @@ class RestCore::FollowRedirect
|
|
30
30
|
res[REQUEST_METHOD]
|
31
31
|
end
|
32
32
|
|
33
|
-
call(res.merge(
|
34
|
-
|
35
|
-
|
33
|
+
call(res.merge(REQUEST_METHOD => meth ,
|
34
|
+
REQUEST_PATH => location,
|
35
|
+
REQUEST_QUERY => {} ,
|
36
36
|
'follow_redirect.max_redirects' =>
|
37
37
|
res['follow_redirect.max_redirects'] - 1), &k)
|
38
38
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
require 'rest-core/middleware'
|
3
|
+
require 'rest-core/util/parse_query'
|
4
|
+
|
5
|
+
class RestCore::QueryResponse
|
6
|
+
def self.members; [:query_response]; end
|
7
|
+
include RestCore::Middleware
|
8
|
+
|
9
|
+
QUERY_RESPONSE_HEADER =
|
10
|
+
{'Accept' => 'application/x-www-form-urlencoded'}.freeze
|
11
|
+
|
12
|
+
def call env, &k
|
13
|
+
return app.call(env, &k) if env[DRY]
|
14
|
+
return app.call(env, &k) unless query_response(env)
|
15
|
+
|
16
|
+
headers = QUERY_RESPONSE_HEADER.merge(env[REQUEST_HEADERS]||{})
|
17
|
+
app.call(env.merge(REQUEST_HEADERS => headers)) do |response|
|
18
|
+
body = ParseQuery.parse_query(response[RESPONSE_BODY])
|
19
|
+
yield(response.merge(RESPONSE_BODY => body))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
require 'erb'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module RestCore; end
|
6
|
+
module RestCore::Config
|
7
|
+
extend self
|
8
|
+
DefaultModuleName = 'DefaultAttributes'
|
9
|
+
|
10
|
+
def load klass, path, env, namespace=nil
|
11
|
+
config = YAML.load(ERB.new(File.read(path)).result(binding))
|
12
|
+
defaults = config[env]
|
13
|
+
return false unless defaults
|
14
|
+
return false unless defaults[namespace] if namespace
|
15
|
+
data = if namespace
|
16
|
+
defaults[namespace]
|
17
|
+
else
|
18
|
+
defaults
|
19
|
+
end
|
20
|
+
raise ArgumentError.new("#{data} is not a hash") unless
|
21
|
+
data.kind_of?(Hash)
|
22
|
+
|
23
|
+
default_attributes_module(klass).module_eval(
|
24
|
+
data.inject(["extend self\n"]){ |r, (k, v)|
|
25
|
+
# quote strings, leave others free (e.g. false, numbers, etc)
|
26
|
+
r << <<-RUBY
|
27
|
+
def default_#{k}
|
28
|
+
#{v.inspect}
|
29
|
+
end
|
30
|
+
RUBY
|
31
|
+
}.join, __FILE__, __LINE__)
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_attributes_module klass
|
35
|
+
mod = if klass.const_defined?(DefaultModuleName)
|
36
|
+
klass.const_get(DefaultModuleName)
|
37
|
+
else
|
38
|
+
klass.send(:const_set, DefaultModuleName, Module.new)
|
39
|
+
end
|
40
|
+
|
41
|
+
singleton_class = if klass.respond_to?(:singleton_class)
|
42
|
+
klass.singleton_class
|
43
|
+
else
|
44
|
+
class << klass; self; end
|
45
|
+
end
|
46
|
+
|
47
|
+
klass.send(:extend, mod) unless singleton_class < mod
|
48
|
+
mod
|
49
|
+
end
|
50
|
+
end
|
data/lib/rest-core/util/json.rb
CHANGED
data/lib/rest-core/version.rb
CHANGED
data/lib/rest-core.rb
CHANGED
@@ -5,11 +5,13 @@ module RestCore
|
|
5
5
|
REQUEST_QUERY = 'REQUEST_QUERY'
|
6
6
|
REQUEST_PAYLOAD = 'REQUEST_PAYLOAD'
|
7
7
|
REQUEST_HEADERS = 'REQUEST_HEADERS'
|
8
|
+
REQUEST_URI = 'REQUEST_URI'
|
8
9
|
|
9
10
|
RESPONSE_BODY = 'RESPONSE_BODY'
|
10
11
|
RESPONSE_STATUS = 'RESPONSE_STATUS'
|
11
12
|
RESPONSE_HEADERS = 'RESPONSE_HEADERS'
|
12
13
|
RESPONSE_SOCKET = 'RESPONSE_SOCKET'
|
14
|
+
RESPONSE_KEY = 'RESPONSE_KEY'
|
13
15
|
|
14
16
|
DRY = 'core.dry'
|
15
17
|
FAIL = 'core.fail'
|
@@ -40,6 +42,7 @@ module RestCore
|
|
40
42
|
autoload :Json , 'rest-core/util/json'
|
41
43
|
autoload :ParseQuery , 'rest-core/util/parse_query'
|
42
44
|
autoload :Payload , 'rest-core/util/payload'
|
45
|
+
autoload :Config , 'rest-core/util/config'
|
43
46
|
|
44
47
|
# middlewares
|
45
48
|
autoload :AuthBasic , 'rest-core/middleware/auth_basic'
|
@@ -57,6 +60,7 @@ module RestCore
|
|
57
60
|
autoload :FollowRedirect, 'rest-core/middleware/follow_redirect'
|
58
61
|
autoload :JsonRequest , 'rest-core/middleware/json_request'
|
59
62
|
autoload :JsonResponse , 'rest-core/middleware/json_response'
|
63
|
+
autoload :QueryResponse , 'rest-core/middleware/query_response'
|
60
64
|
autoload :Oauth1Header , 'rest-core/middleware/oauth1_header'
|
61
65
|
autoload :Oauth2Header , 'rest-core/middleware/oauth2_header'
|
62
66
|
autoload :Oauth2Query , 'rest-core/middleware/oauth2_query'
|
data/rest-core.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: rest-core 3.
|
2
|
+
# stub: rest-core 3.1.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "rest-core"
|
6
|
-
s.version = "3.
|
6
|
+
s.version = "3.1.0"
|
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-05-
|
11
|
+
s.date = "2014-05-09"
|
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 = [
|
@@ -57,6 +57,7 @@ Gem::Specification.new do |s|
|
|
57
57
|
"lib/rest-core/middleware/oauth1_header.rb",
|
58
58
|
"lib/rest-core/middleware/oauth2_header.rb",
|
59
59
|
"lib/rest-core/middleware/oauth2_query.rb",
|
60
|
+
"lib/rest-core/middleware/query_response.rb",
|
60
61
|
"lib/rest-core/middleware/timeout.rb",
|
61
62
|
"lib/rest-core/patch/multi_json.rb",
|
62
63
|
"lib/rest-core/patch/rest-client.rb",
|
@@ -64,6 +65,7 @@ Gem::Specification.new do |s|
|
|
64
65
|
"lib/rest-core/test.rb",
|
65
66
|
"lib/rest-core/thread_pool.rb",
|
66
67
|
"lib/rest-core/timer.rb",
|
68
|
+
"lib/rest-core/util/config.rb",
|
67
69
|
"lib/rest-core/util/hmac.rb",
|
68
70
|
"lib/rest-core/util/json.rb",
|
69
71
|
"lib/rest-core/util/parse_query.rb",
|
@@ -73,11 +75,13 @@ Gem::Specification.new do |s|
|
|
73
75
|
"rest-core.gemspec",
|
74
76
|
"task/README.md",
|
75
77
|
"task/gemgem.rb",
|
78
|
+
"test/config/rest-core.yaml",
|
76
79
|
"test/test_auth_basic.rb",
|
77
80
|
"test/test_builder.rb",
|
78
81
|
"test/test_cache.rb",
|
79
82
|
"test/test_client.rb",
|
80
83
|
"test/test_client_oauth1.rb",
|
84
|
+
"test/test_config.rb",
|
81
85
|
"test/test_default_payload.rb",
|
82
86
|
"test/test_default_query.rb",
|
83
87
|
"test/test_error_detector.rb",
|
@@ -92,6 +96,7 @@ Gem::Specification.new do |s|
|
|
92
96
|
"test/test_oauth2_header.rb",
|
93
97
|
"test/test_payload.rb",
|
94
98
|
"test/test_promise.rb",
|
99
|
+
"test/test_query_response.rb",
|
95
100
|
"test/test_rest-client.rb",
|
96
101
|
"test/test_simple.rb",
|
97
102
|
"test/test_thread_pool.rb",
|
@@ -108,6 +113,7 @@ Gem::Specification.new do |s|
|
|
108
113
|
"test/test_cache.rb",
|
109
114
|
"test/test_client.rb",
|
110
115
|
"test/test_client_oauth1.rb",
|
116
|
+
"test/test_config.rb",
|
111
117
|
"test/test_default_payload.rb",
|
112
118
|
"test/test_default_query.rb",
|
113
119
|
"test/test_error_detector.rb",
|
@@ -122,6 +128,7 @@ Gem::Specification.new do |s|
|
|
122
128
|
"test/test_oauth2_header.rb",
|
123
129
|
"test/test_payload.rb",
|
124
130
|
"test/test_promise.rb",
|
131
|
+
"test/test_query_response.rb",
|
125
132
|
"test/test_rest-client.rb",
|
126
133
|
"test/test_simple.rb",
|
127
134
|
"test/test_thread_pool.rb",
|
data/test/test_cache.rb
CHANGED
@@ -34,7 +34,8 @@ describe RC::Cache do
|
|
34
34
|
c.app.app.tick.should.eq 2
|
35
35
|
c.head('/').should.eq('A' => 'B')
|
36
36
|
c.get('/').should.eq 'response'
|
37
|
-
c.request(
|
37
|
+
c.request(RC::REQUEST_PATH => '/',
|
38
|
+
RC::RESPONSE_KEY => RC::RESPONSE_STATUS).should.eq 200
|
38
39
|
end
|
39
40
|
|
40
41
|
should 'basic 1' do
|
@@ -155,6 +156,17 @@ describe RC::Cache do
|
|
155
156
|
c.cache.should.eq({})
|
156
157
|
end
|
157
158
|
|
159
|
+
should 'not cache hijacking' do
|
160
|
+
stub_request(:get, 'http://a').to_return(:body => 'ok')
|
161
|
+
c = RC::Builder.client{use RC::Cache, {}, nil}.new
|
162
|
+
2.times do
|
163
|
+
c.get('http://a', {}, RC::HIJACK => true,
|
164
|
+
RC::RESPONSE_KEY => RC::RESPONSE_SOCKET).
|
165
|
+
read.should.eq 'ok'
|
166
|
+
end
|
167
|
+
c.cache.should.eq({})
|
168
|
+
end
|
169
|
+
|
158
170
|
should 'update cache if there is cache option set to false' do
|
159
171
|
url, body = "https://cache", 'ok'
|
160
172
|
stub_request(:get, url).to_return(:body => body)
|
data/test/test_config.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
require 'rest-core/test'
|
3
|
+
|
4
|
+
describe RC::Config do
|
5
|
+
before do
|
6
|
+
@klass = RC::Builder.client
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
Muack.verify
|
11
|
+
end
|
12
|
+
|
13
|
+
def check
|
14
|
+
@klass.default_app_id .should.eq 41829
|
15
|
+
@klass.default_secret .should.eq 'r41829'.reverse
|
16
|
+
@klass.default_json_response.should.eq false
|
17
|
+
@klass.default_lang .should.eq 'zh-tw'
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'honor config' do
|
21
|
+
RC::Config.load(
|
22
|
+
@klass,
|
23
|
+
"#{File.dirname(__FILE__)}/config/rest-core.yaml",
|
24
|
+
'test',
|
25
|
+
'facebook')
|
26
|
+
check
|
27
|
+
end
|
28
|
+
end
|
data/test/test_error_handler.rb
CHANGED
@@ -39,6 +39,6 @@ describe RC::ErrorHandler do
|
|
39
39
|
|
40
40
|
should 'no exception but errors' do
|
41
41
|
client.new(:error_handler => lambda{ |res| 1 }).
|
42
|
-
request(
|
42
|
+
request(RC::FAIL => [0], RC::RESPONSE_KEY => RC::FAIL).should.eq [0, 1]
|
43
43
|
end
|
44
44
|
end
|
data/test/test_event_source.rb
CHANGED
@@ -3,7 +3,11 @@ require 'socket'
|
|
3
3
|
require 'rest-core/test'
|
4
4
|
|
5
5
|
describe RC::EventSource do
|
6
|
-
|
6
|
+
after do
|
7
|
+
WebMock.reset!
|
8
|
+
end
|
9
|
+
|
10
|
+
client = RC::Builder.client{use RC::Cache, {}, nil}.new
|
7
11
|
server = lambda do |close=true|
|
8
12
|
serv = TCPServer.new(0)
|
9
13
|
port = serv.addr[1]
|
@@ -39,25 +43,21 @@ SSE
|
|
39
43
|
sock.should.kind_of IO
|
40
44
|
flag.should.eq 0
|
41
45
|
flag += 1
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
event.should.eq(m.shift)
|
46
|
+
end.
|
47
|
+
onmessage do |event, data, sock|
|
48
|
+
{'event' => event, 'data' => data}.should.eq m.shift
|
46
49
|
sock.should.kind_of IO
|
47
50
|
sock.should.not.closed?
|
48
51
|
flag += 1
|
49
|
-
end
|
50
|
-
|
51
|
-
es.onerror do |error, sock|
|
52
|
+
end.
|
53
|
+
onerror do |error, sock|
|
52
54
|
error.should.kind_of EOFError
|
53
|
-
m.should.
|
55
|
+
m.should.empty
|
54
56
|
sock.should.closed?
|
55
57
|
flag.should.eq 3
|
56
58
|
flag += 1
|
57
|
-
end
|
59
|
+
end.start.wait
|
58
60
|
|
59
|
-
es.start
|
60
|
-
es.wait
|
61
61
|
flag.should.eq 4
|
62
62
|
t.join
|
63
63
|
end
|
@@ -68,10 +68,67 @@ SSE
|
|
68
68
|
es.onmessage do
|
69
69
|
es.close
|
70
70
|
flag += 1
|
71
|
-
end
|
72
|
-
|
73
|
-
es.wait
|
71
|
+
end.start.wait
|
72
|
+
|
74
73
|
flag.should.eq 1
|
75
74
|
t.join
|
76
75
|
end
|
76
|
+
|
77
|
+
should 'reconnect' do
|
78
|
+
stub_request(:get, 'https://a?b=c').to_return(:body => <<-SSE)
|
79
|
+
event: put
|
80
|
+
data: 0
|
81
|
+
|
82
|
+
event: put
|
83
|
+
data: 1
|
84
|
+
SSE
|
85
|
+
stub_request(:get, 'https://a?c=d').to_return(:body => <<-SSE)
|
86
|
+
event: put
|
87
|
+
data: 2
|
88
|
+
|
89
|
+
event: put
|
90
|
+
data: 3
|
91
|
+
SSE
|
92
|
+
es = client.event_source('https://a', :b => 'c')
|
93
|
+
m = ('0'..'3').to_a
|
94
|
+
es.onmessage do |event, data|
|
95
|
+
data.should.eq m.shift
|
96
|
+
|
97
|
+
end.onerror do |error|
|
98
|
+
error.should.kind_of EOFError
|
99
|
+
es.query = {:c => 'd'}
|
100
|
+
|
101
|
+
end.onreconnect do |error, sock|
|
102
|
+
error.should.kind_of EOFError
|
103
|
+
sock.should.respond_to :read
|
104
|
+
!m.empty? # not empty to reconnect
|
105
|
+
|
106
|
+
end.start.wait
|
107
|
+
m.should.empty
|
108
|
+
end
|
109
|
+
|
110
|
+
should 'not cache' do
|
111
|
+
stub_request(:get, 'https://a?b=c').to_return(:body => <<-SSE)
|
112
|
+
event: put
|
113
|
+
data: 0
|
114
|
+
|
115
|
+
event: put
|
116
|
+
data: 1
|
117
|
+
SSE
|
118
|
+
es = client.event_source('https://a', :b => 'c')
|
119
|
+
m = %w[0 1 0 1]
|
120
|
+
es.onmessage do |event, data|
|
121
|
+
data.should.eq m.shift
|
122
|
+
|
123
|
+
end.onerror do |error|
|
124
|
+
error.should.kind_of EOFError
|
125
|
+
|
126
|
+
end.onreconnect do |error, sock|
|
127
|
+
error.should.kind_of EOFError
|
128
|
+
sock.should.respond_to :read
|
129
|
+
!m.empty? # not empty to reconnect
|
130
|
+
|
131
|
+
end.start.wait
|
132
|
+
m.should.empty
|
133
|
+
end
|
77
134
|
end
|
@@ -18,25 +18,42 @@ describe RC::FollowRedirect do
|
|
18
18
|
[301, 302, 303, 307].each do |status|
|
19
19
|
should "not follow redirect if reached max_redirects: #{status}" do
|
20
20
|
dry.status = status
|
21
|
-
app.call(RC::REQUEST_METHOD => :get, 'max_redirects' => 0)
|
21
|
+
app.call(RC::REQUEST_METHOD => :get, 'max_redirects' => 0) do |res|
|
22
22
|
res[RC::RESPONSE_HEADERS]['LOCATION'].should.eq 'location'
|
23
|
-
|
23
|
+
end
|
24
24
|
end
|
25
25
|
|
26
26
|
should "follow once: #{status}" do
|
27
27
|
dry.status = status
|
28
|
-
app.call(RC::REQUEST_METHOD => :get)
|
28
|
+
app.call(RC::REQUEST_METHOD => :get) do |res|
|
29
29
|
res[RC::RESPONSE_HEADERS]['LOCATION'].should.eq 'location'
|
30
|
-
|
30
|
+
end
|
31
31
|
end
|
32
|
+
|
33
|
+
should "not carry query string: #{status}" do
|
34
|
+
dry.status = status
|
35
|
+
app.call(RC::REQUEST_METHOD => :get,
|
36
|
+
RC::REQUEST_QUERY => {:a => 'a'}) do |res|
|
37
|
+
res[RC::REQUEST_PATH] .should.eq 'location'
|
38
|
+
res[RC::REQUEST_QUERY].should.empty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should "carry payload for #{status}" do
|
43
|
+
dry.status = status
|
44
|
+
app.call(RC::REQUEST_METHOD => :put,
|
45
|
+
RC::REQUEST_PAYLOAD => {:a => 'a'}) do |res|
|
46
|
+
res[RC::REQUEST_PAYLOAD].should.eq(:a => 'a')
|
47
|
+
end
|
48
|
+
end if status != 303
|
32
49
|
end
|
33
50
|
|
34
51
|
[200, 201, 404, 500].each do |status|
|
35
52
|
should "not follow redirect if it's not a redirect status: #{status}" do
|
36
53
|
dry.status = status
|
37
|
-
app.call(RC::REQUEST_METHOD => :get, 'max_redirects' => 9)
|
54
|
+
app.call(RC::REQUEST_METHOD => :get, 'max_redirects' => 9) do |res|
|
38
55
|
res[RC::RESPONSE_HEADERS]['LOCATION'].should.eq 'location'
|
39
|
-
|
56
|
+
end
|
40
57
|
end
|
41
58
|
end
|
42
59
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
require 'rest-core/test'
|
3
|
+
|
4
|
+
describe RC::QueryResponse do
|
5
|
+
describe 'app' do
|
6
|
+
app = RC::QueryResponse.new(RC::Dry.new, true)
|
7
|
+
expected = {RC::RESPONSE_BODY => {},
|
8
|
+
RC::REQUEST_HEADERS =>
|
9
|
+
{'Accept' => 'application/x-www-form-urlencoded'}}
|
10
|
+
|
11
|
+
should 'give {} for nil' do
|
12
|
+
app.call({}){ |response| response.should.eq(expected) }
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'give {} for ""' do
|
16
|
+
app.call(RC::RESPONSE_BODY => ''){ |r| r.should.eq(expected) }
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'give {"a" => "b"} for "a=b"' do
|
20
|
+
e = expected.merge(RC::RESPONSE_BODY => {'a' => 'b'})
|
21
|
+
app.call(RC::RESPONSE_BODY => 'a=b'){ |r| r.should.eq(e) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'client' do
|
26
|
+
client = RC::Builder.client do
|
27
|
+
use RC::QueryResponse, true
|
28
|
+
run Class.new{
|
29
|
+
def call env
|
30
|
+
yield(env.merge(RC::RESPONSE_BODY => 'a=b&c=d'))
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'do nothing' do
|
36
|
+
expected = 'a=b&c=d'
|
37
|
+
client.new(:query_response => false).get(''){ |response|
|
38
|
+
response.should.eq(expected)
|
39
|
+
}.get('').should.eq(expected)
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'parse' do
|
43
|
+
expected = {'a' => 'b', 'c' => 'd'}
|
44
|
+
client.new.get(''){ |response|
|
45
|
+
response.should.eq(expected)
|
46
|
+
}.get('').should.eq(expected)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/test/test_rest-client.rb
CHANGED
@@ -39,7 +39,7 @@ describe RC::RestClient do
|
|
39
39
|
|
40
40
|
should 'not kill the thread if error was coming from the task' do
|
41
41
|
mock(RestClient::Request).execute{ raise 'boom' }.with_any_args
|
42
|
-
c.request(
|
42
|
+
c.request(RC::RESPONSE_KEY => RC::FAIL).first.message.should.eq 'boom'
|
43
43
|
Muack.verify
|
44
44
|
end
|
45
45
|
|
@@ -54,7 +54,8 @@ describe RC::RestClient do
|
|
54
54
|
stub(c.class.thread_pool).queue{ [] } # don't queue the task
|
55
55
|
mock(RC::ThreadPool::Task).new.with_any_args.
|
56
56
|
peek_return{ |t| mock(t).cancel; t } # the task should be cancelled
|
57
|
-
c.request(
|
57
|
+
c.request(RC::RESPONSE_KEY => RC::FAIL, RC::TIMER => timer).
|
58
|
+
first.message.should.eq 'boom'
|
58
59
|
Muack.verify
|
59
60
|
end
|
60
61
|
end
|
data/test/test_simple.rb
CHANGED
@@ -2,13 +2,36 @@
|
|
2
2
|
require 'rest-core/test'
|
3
3
|
|
4
4
|
describe RC::Simple do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
path = 'http://example.com/'
|
6
|
+
|
7
|
+
after do
|
8
|
+
WebMock.reset!
|
8
9
|
end
|
9
10
|
|
10
|
-
should '
|
11
|
-
|
11
|
+
should 'give RESPONSE_BODY' do
|
12
|
+
stub_request(:get, path).to_return(:body => 'OK')
|
13
|
+
RC::Simple.new.get(path).should.eq 'OK'
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'give RESPONSE_HEADERS' do
|
17
|
+
stub_request(:head, path).to_return(:headers => {'A' => 'B'})
|
18
|
+
RC::Simple.new.head(path).should.eq 'A' => 'B'
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'give RESPONSE_HEADERS' do
|
22
|
+
stub_request(:get, path).to_return(:status => 199)
|
23
|
+
RC::Simple.new.get(path, {},
|
24
|
+
RC::RESPONSE_KEY => RC::RESPONSE_STATUS).should.eq 199
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'give RESPONSE_SOCKET' do
|
28
|
+
stub_request(:get, path).to_return(:body => 'OK')
|
29
|
+
RC::Simple.new.get(path, {}, RC::HIJACK => true).read.should.eq 'OK'
|
12
30
|
end
|
13
|
-
end
|
14
31
|
|
32
|
+
should 'give REQUEST_URI' do
|
33
|
+
stub_request(:get, "#{path}?a=b").to_return(:body => 'OK')
|
34
|
+
RC::Simple.new.get(path, {:a => 'b'},
|
35
|
+
RC::RESPONSE_KEY => RC::REQUEST_URI).should.eq "#{path}?a=b"
|
36
|
+
end
|
37
|
+
end
|
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.
|
4
|
+
version: 3.1.0
|
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-05-
|
11
|
+
date: 2014-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- lib/rest-core/middleware/oauth1_header.rb
|
115
115
|
- lib/rest-core/middleware/oauth2_header.rb
|
116
116
|
- lib/rest-core/middleware/oauth2_query.rb
|
117
|
+
- lib/rest-core/middleware/query_response.rb
|
117
118
|
- lib/rest-core/middleware/timeout.rb
|
118
119
|
- lib/rest-core/patch/multi_json.rb
|
119
120
|
- lib/rest-core/patch/rest-client.rb
|
@@ -121,6 +122,7 @@ files:
|
|
121
122
|
- lib/rest-core/test.rb
|
122
123
|
- lib/rest-core/thread_pool.rb
|
123
124
|
- lib/rest-core/timer.rb
|
125
|
+
- lib/rest-core/util/config.rb
|
124
126
|
- lib/rest-core/util/hmac.rb
|
125
127
|
- lib/rest-core/util/json.rb
|
126
128
|
- lib/rest-core/util/parse_query.rb
|
@@ -130,11 +132,13 @@ files:
|
|
130
132
|
- rest-core.gemspec
|
131
133
|
- task/README.md
|
132
134
|
- task/gemgem.rb
|
135
|
+
- test/config/rest-core.yaml
|
133
136
|
- test/test_auth_basic.rb
|
134
137
|
- test/test_builder.rb
|
135
138
|
- test/test_cache.rb
|
136
139
|
- test/test_client.rb
|
137
140
|
- test/test_client_oauth1.rb
|
141
|
+
- test/test_config.rb
|
138
142
|
- test/test_default_payload.rb
|
139
143
|
- test/test_default_query.rb
|
140
144
|
- test/test_error_detector.rb
|
@@ -149,6 +153,7 @@ files:
|
|
149
153
|
- test/test_oauth2_header.rb
|
150
154
|
- test/test_payload.rb
|
151
155
|
- test/test_promise.rb
|
156
|
+
- test/test_query_response.rb
|
152
157
|
- test/test_rest-client.rb
|
153
158
|
- test/test_simple.rb
|
154
159
|
- test/test_thread_pool.rb
|
@@ -185,6 +190,7 @@ test_files:
|
|
185
190
|
- test/test_cache.rb
|
186
191
|
- test/test_client.rb
|
187
192
|
- test/test_client_oauth1.rb
|
193
|
+
- test/test_config.rb
|
188
194
|
- test/test_default_payload.rb
|
189
195
|
- test/test_default_query.rb
|
190
196
|
- test/test_error_detector.rb
|
@@ -199,6 +205,7 @@ test_files:
|
|
199
205
|
- test/test_oauth2_header.rb
|
200
206
|
- test/test_payload.rb
|
201
207
|
- test/test_promise.rb
|
208
|
+
- test/test_query_response.rb
|
202
209
|
- test/test_rest-client.rb
|
203
210
|
- test/test_simple.rb
|
204
211
|
- test/test_thread_pool.rb
|