rufus-verbs 0.9 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +6 -0
- data/lib/rufus/verbs.rb +2 -2
- data/lib/rufus/verbs/conditional.rb +1 -1
- data/lib/rufus/verbs/cookies.rb +1 -1
- data/lib/rufus/verbs/endpoint.rb +47 -30
- data/lib/rufus/verbs/version.rb +3 -3
- data/test/items.rb +24 -8
- data/test/simple_test.rb +19 -0
- data/test/test.rb +5 -0
- data/test/timeout_test.rb +38 -0
- metadata +3 -2
data/README.txt
CHANGED
@@ -288,6 +288,12 @@ the resource (or the middle) of a full resource path (see :base)
|
|
288
288
|
* <b>:ssl_verify_peer</b> (boolean, RE)
|
289
289
|
by default, rufus-verbs doesn't verify ssl certificates. With this option set to true, it will.
|
290
290
|
|
291
|
+
* <b>:timeout</b> (integer, RE)
|
292
|
+
sets the timeout (both open_ and read_timeout) for the request (and the endpoint), expects a value expressed in seconds.
|
293
|
+
|
294
|
+
* <b>:to</b> (integer, RE)
|
295
|
+
shortcut for :timeout
|
296
|
+
|
291
297
|
* <b>:u</b> (uri, string, RE)
|
292
298
|
the short version of :uri
|
293
299
|
|
data/lib/rufus/verbs.rb
CHANGED
@@ -8,10 +8,10 @@
|
|
8
8
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
9
|
# copies of the Software, and to permit persons to whom the Software is
|
10
10
|
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# The above copyright notice and this permission notice shall be included in
|
13
13
|
# all copies or substantial portions of the Software.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
16
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
17
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
data/lib/rufus/verbs/cookies.rb
CHANGED
data/lib/rufus/verbs/endpoint.rb
CHANGED
@@ -8,10 +8,10 @@
|
|
8
8
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
9
|
# copies of the Software, and to permit persons to whom the Software is
|
10
10
|
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# The above copyright notice and this permission notice shall be included in
|
13
13
|
# all copies or substantial portions of the Software.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
16
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
17
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
@@ -49,12 +49,12 @@ module Verbs
|
|
49
49
|
USER_AGENT = "Ruby rufus-verbs #{VERSION}"
|
50
50
|
|
51
51
|
#
|
52
|
-
# An EndPoint can be used to share common options among a set of
|
52
|
+
# An EndPoint can be used to share common options among a set of
|
53
53
|
# requests.
|
54
54
|
#
|
55
55
|
# ep = EndPoint.new(
|
56
|
-
# :host => "restful.server",
|
57
|
-
# :port => 7080,
|
56
|
+
# :host => "restful.server",
|
57
|
+
# :port => 7080,
|
58
58
|
# :resource => "inventory/tools")
|
59
59
|
#
|
60
60
|
# res = ep.get :id => 1
|
@@ -63,7 +63,7 @@ module Verbs
|
|
63
63
|
# res = ep.get :id => 0
|
64
64
|
# # where did the hammer go ?
|
65
65
|
#
|
66
|
-
# When a request gets prepared, the option values will be looked up
|
66
|
+
# When a request gets prepared, the option values will be looked up
|
67
67
|
# in (1) its local (request) options, then (2) in the EndPoint options.
|
68
68
|
#
|
69
69
|
class EndPoint
|
@@ -83,7 +83,7 @@ module Verbs
|
|
83
83
|
|
84
84
|
compute_target @opts
|
85
85
|
|
86
|
-
@opts[:http_basic_authentication] =
|
86
|
+
@opts[:http_basic_authentication] =
|
87
87
|
opts[:http_basic_authentication] || opts[:hba]
|
88
88
|
|
89
89
|
@opts[:user_agent] ||= USER_AGENT
|
@@ -126,7 +126,7 @@ module Verbs
|
|
126
126
|
#
|
127
127
|
# This is the method called by the module methods verbs.
|
128
128
|
#
|
129
|
-
# For example,
|
129
|
+
# For example,
|
130
130
|
#
|
131
131
|
# RufusVerbs.get(args)
|
132
132
|
#
|
@@ -264,10 +264,10 @@ module Verbs
|
|
264
264
|
elsif u
|
265
265
|
|
266
266
|
u = URI.parse u.to_s unless u.is_a?(URI)
|
267
|
-
[ u.scheme,
|
268
|
-
u.host,
|
269
|
-
u.port,
|
270
|
-
u.path,
|
267
|
+
[ u.scheme,
|
268
|
+
u.host,
|
269
|
+
u.port,
|
270
|
+
u.path,
|
271
271
|
query_to_h(u.query) ]
|
272
272
|
else
|
273
273
|
|
@@ -279,18 +279,18 @@ module Verbs
|
|
279
279
|
opts[:port] = r[2] || @opts[:port]
|
280
280
|
opts[:path] = r[3] || @opts[:path]
|
281
281
|
|
282
|
-
opts[:query] =
|
283
|
-
r[4] ||
|
282
|
+
opts[:query] =
|
283
|
+
r[4] ||
|
284
284
|
opts[:params] || opts[:query] ||
|
285
|
-
@opts[:query] || @opts[:params] ||
|
285
|
+
@opts[:query] || @opts[:params] ||
|
286
286
|
{}
|
287
287
|
|
288
288
|
opts.delete :path if opts[:path] == ""
|
289
289
|
|
290
|
-
opts[:c_uri] = [
|
291
|
-
opts[:scheme],
|
292
|
-
opts[:host],
|
293
|
-
opts[:port],
|
290
|
+
opts[:c_uri] = [
|
291
|
+
opts[:scheme],
|
292
|
+
opts[:host],
|
293
|
+
opts[:port],
|
294
294
|
opts[:path],
|
295
295
|
opts[:query] ].inspect
|
296
296
|
#
|
@@ -303,7 +303,7 @@ module Verbs
|
|
303
303
|
# Creates the Net::HTTP request instance.
|
304
304
|
#
|
305
305
|
# If :fake_put is set, will use Net::HTTP::Post
|
306
|
-
# and make sure the query string contains '_method=put' (or
|
306
|
+
# and make sure the query string contains '_method=put' (or
|
307
307
|
# '_method=delete').
|
308
308
|
#
|
309
309
|
# This call will also advertise this rufus-verbs as
|
@@ -311,7 +311,7 @@ module Verbs
|
|
311
311
|
#
|
312
312
|
def create_request (method, opts)
|
313
313
|
|
314
|
-
if (o(opts, :fake_put) and
|
314
|
+
if (o(opts, :fake_put) and
|
315
315
|
(method == :put or method == :delete))
|
316
316
|
|
317
317
|
opts[:query][:_method] = method.to_s
|
@@ -362,7 +362,7 @@ module Verbs
|
|
362
362
|
end
|
363
363
|
|
364
364
|
#
|
365
|
-
# In that base class, it's empty.
|
365
|
+
# In that base class, it's empty.
|
366
366
|
# It's implemented in ConditionalEndPoint.
|
367
367
|
#
|
368
368
|
# Only called for a GET.
|
@@ -381,10 +381,12 @@ module Verbs
|
|
381
381
|
compute_proxy opts
|
382
382
|
|
383
383
|
http = Net::HTTP.new(
|
384
|
-
opts[:host], opts[:port],
|
384
|
+
opts[:host], opts[:port],
|
385
385
|
opts[:proxy_host], opts[:proxy_port],
|
386
386
|
opts[:proxy_user], opts[:proxy_pass])
|
387
387
|
|
388
|
+
set_timeout http, opts
|
389
|
+
|
388
390
|
return http unless opts[:scheme] == 'https'
|
389
391
|
|
390
392
|
require 'net/https'
|
@@ -393,9 +395,9 @@ module Verbs
|
|
393
395
|
http.enable_post_connection_check = true
|
394
396
|
|
395
397
|
http.verify_mode = if o(opts, :ssl_verify_peer)
|
396
|
-
OpenSSL::SSL::VERIFY_NONE
|
397
|
-
else
|
398
398
|
OpenSSL::SSL::VERIFY_PEER
|
399
|
+
else
|
400
|
+
OpenSSL::SSL::VERIFY_NONE
|
399
401
|
end
|
400
402
|
|
401
403
|
store = OpenSSL::X509::Store.new
|
@@ -405,6 +407,21 @@ module Verbs
|
|
405
407
|
http
|
406
408
|
end
|
407
409
|
|
410
|
+
#
|
411
|
+
# Sets both the open_timeout and the read_timeout for the http
|
412
|
+
# instance
|
413
|
+
#
|
414
|
+
def set_timeout (http, opts)
|
415
|
+
|
416
|
+
to = o(opts, :timeout) || o(opts, :to)
|
417
|
+
to = to.to_i
|
418
|
+
|
419
|
+
return if to == 0
|
420
|
+
|
421
|
+
http.open_timeout = to
|
422
|
+
http.read_timeout = to
|
423
|
+
end
|
424
|
+
|
408
425
|
#
|
409
426
|
# Makes sure the request opts hold the proxy information.
|
410
427
|
#
|
@@ -466,7 +483,7 @@ module Verbs
|
|
466
483
|
|
467
484
|
return nil unless q
|
468
485
|
|
469
|
-
q.split("&").inject({}) do |r, e|
|
486
|
+
q.split("&").inject({}) do |r, e|
|
470
487
|
s = e.split("=")
|
471
488
|
r[s[0]] = s[1]
|
472
489
|
r
|
@@ -474,11 +491,11 @@ module Verbs
|
|
474
491
|
end
|
475
492
|
|
476
493
|
#
|
477
|
-
# { "a" => "A", "b" => "B" } -> "a=A&b=B"
|
494
|
+
# { "a" => "A", "b" => "B" } -> "a=A&b=B"
|
478
495
|
#
|
479
496
|
def h_to_query (h, opts)
|
480
497
|
|
481
|
-
h.entries.collect { |k, v|
|
498
|
+
h.entries.collect { |k, v|
|
482
499
|
unless o(opts, :no_escape)
|
483
500
|
k = URI.escape k.to_s
|
484
501
|
v = URI.escape v.to_s
|
@@ -502,7 +519,7 @@ module Verbs
|
|
502
519
|
req.set_form_data fd, sep
|
503
520
|
elsif block
|
504
521
|
req.body = block.call req
|
505
|
-
else
|
522
|
+
else
|
506
523
|
req.body = ""
|
507
524
|
end
|
508
525
|
end
|
@@ -544,7 +561,7 @@ module Verbs
|
|
544
561
|
opts[:path], opts[:query] = location.split "?"
|
545
562
|
end
|
546
563
|
|
547
|
-
if (authentication_is_on?(opts) and
|
564
|
+
if (authentication_is_on?(opts) and
|
548
565
|
[ opts[:scheme], opts[:host] ] != prev_host)
|
549
566
|
|
550
567
|
raise(
|
data/lib/rufus/verbs/version.rb
CHANGED
@@ -8,10 +8,10 @@
|
|
8
8
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
9
|
# copies of the Software, and to permit persons to whom the Software is
|
10
10
|
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# The above copyright notice and this permission notice shall be included in
|
13
13
|
# all copies or substantial portions of the Software.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
16
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
17
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
@@ -39,7 +39,7 @@ module Verbs
|
|
39
39
|
#
|
40
40
|
# The version of this rufus-verbs [gem]
|
41
41
|
#
|
42
|
-
VERSION = '0.
|
42
|
+
VERSION = '0.10'
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
data/test/items.rb
CHANGED
@@ -58,6 +58,7 @@ end
|
|
58
58
|
class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
59
59
|
|
60
60
|
@@items = {}
|
61
|
+
@@last_item_id = -1
|
61
62
|
|
62
63
|
@@lastmod = LastModifiedHash.new
|
63
64
|
|
@@ -80,7 +81,7 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
80
81
|
|
81
82
|
WEBrick::HTTPAuth.basic_auth(req, res, "items") do |u, p|
|
82
83
|
(u != nil and u == p)
|
83
|
-
end
|
84
|
+
end
|
84
85
|
|
85
86
|
elsif @auth == :digest
|
86
87
|
|
@@ -127,6 +128,9 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
127
128
|
return do_DELETE(req, res) if m == 'delete'
|
128
129
|
|
129
130
|
i = item_id req
|
131
|
+
|
132
|
+
i = (@@last_item_id += 1) unless i
|
133
|
+
|
130
134
|
items[i] = req.body
|
131
135
|
lastmod.touch i
|
132
136
|
|
@@ -138,7 +142,7 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
138
142
|
|
139
143
|
i = item_id req
|
140
144
|
|
141
|
-
return reply(res, 404, "no item '#{i}'") unless items[i]
|
145
|
+
return reply(res, 404, "no item '#{i}'") unless items[i]
|
142
146
|
|
143
147
|
items[i] = req.body
|
144
148
|
lastmod.touch i
|
@@ -150,7 +154,7 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
150
154
|
|
151
155
|
i = item_id req
|
152
156
|
|
153
|
-
return reply(res, 404, "no item '#{i}'") unless items[i]
|
157
|
+
return reply(res, 404, "no item '#{i}'") unless items[i]
|
154
158
|
|
155
159
|
items.delete i
|
156
160
|
lastmod.delete i
|
@@ -172,7 +176,7 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
172
176
|
def items
|
173
177
|
@@items
|
174
178
|
end
|
175
|
-
|
179
|
+
|
176
180
|
def lastmod
|
177
181
|
@@lastmod
|
178
182
|
end
|
@@ -202,7 +206,7 @@ class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
202
206
|
items
|
203
207
|
end
|
204
208
|
|
205
|
-
[ representation,
|
209
|
+
[ representation,
|
206
210
|
representation.inspect.hash.to_s,
|
207
211
|
lastmod.last_modified(key) ]
|
208
212
|
end
|
@@ -230,7 +234,7 @@ class ThingServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
230
234
|
def do_GET (req, res)
|
231
235
|
|
232
236
|
res.set_redirect(
|
233
|
-
WEBrick::HTTPStatus[303],
|
237
|
+
WEBrick::HTTPStatus[303],
|
234
238
|
"http://localhost:7777/items")
|
235
239
|
end
|
236
240
|
end
|
@@ -271,6 +275,17 @@ class CookieServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
271
275
|
end
|
272
276
|
end
|
273
277
|
|
278
|
+
#
|
279
|
+
# a servlet that doesn't reply (for timeout testing)
|
280
|
+
#
|
281
|
+
class LostServlet < WEBrick::HTTPServlet::AbstractServlet
|
282
|
+
|
283
|
+
def do_GET (req, res)
|
284
|
+
|
285
|
+
sleep 200
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
274
289
|
#
|
275
290
|
# Serving items, a dummy resource...
|
276
291
|
# Also serving things, which just redirect to items...
|
@@ -281,7 +296,7 @@ class ItemServer
|
|
281
296
|
|
282
297
|
port = args[:port] || 7777
|
283
298
|
|
284
|
-
#al = [
|
299
|
+
#al = [
|
285
300
|
# [ "", WEBrick::AccessLog::COMMON_LOG_FORMAT ],
|
286
301
|
# [ "", WEBrick::AccessLog::REFERER_LOG_FORMAT ]]
|
287
302
|
|
@@ -296,9 +311,10 @@ class ItemServer
|
|
296
311
|
@server.mount "/items", ItemServlet
|
297
312
|
@server.mount "/things", ThingServlet
|
298
313
|
@server.mount "/cookie", CookieServlet
|
314
|
+
@server.mount "/lost", LostServlet
|
299
315
|
|
300
316
|
[ 'INT', 'TERM' ].each do |signal|
|
301
|
-
trap(signal) { shutdown }
|
317
|
+
trap(signal) { shutdown }
|
302
318
|
end
|
303
319
|
end
|
304
320
|
|
data/test/simple_test.rb
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
# Sun Jan 13 12:33:03 JST 2008
|
8
8
|
#
|
9
9
|
|
10
|
+
require 'rubygems'
|
11
|
+
|
10
12
|
require 'test/unit'
|
11
13
|
require 'testbase'
|
12
14
|
|
@@ -47,6 +49,23 @@ class SimpleTest < Test::Unit::TestCase
|
|
47
49
|
expect 200, { 0 => "Toto3" }, get(:uri => "http://localhost:7777/items")
|
48
50
|
end
|
49
51
|
|
52
|
+
def test_0b
|
53
|
+
|
54
|
+
expect 200, {}, get(:uri => "http://localhost:7777/items")
|
55
|
+
|
56
|
+
res = post :uri => "http://localhost:7777/items", :d => "Toto"
|
57
|
+
assert_equal 201, res.code.to_i
|
58
|
+
assert_equal "http://localhost:7777/items/0", res['Location']
|
59
|
+
|
60
|
+
expect 200, "\"Toto\"", get(:uri => "http://localhost:7777/items/0")
|
61
|
+
|
62
|
+
res = post :uri => "http://localhost:7777/items", :d => "Smurf"
|
63
|
+
assert_equal 201, res.code.to_i
|
64
|
+
assert_equal "http://localhost:7777/items/1", res['Location']
|
65
|
+
|
66
|
+
expect 200, "\"Smurf\"", get(:uri => "http://localhost:7777/items/1")
|
67
|
+
end
|
68
|
+
|
50
69
|
def test_1
|
51
70
|
|
52
71
|
ep = EndPoint.new(:host => "localhost", :port => 7777)
|
data/test/test.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-verbs
|
4
|
+
#
|
5
|
+
# jmettraux@gmail.com
|
6
|
+
#
|
7
|
+
# Mon May 26 17:04:25 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
require 'testbase'
|
14
|
+
|
15
|
+
require 'rufus/verbs'
|
16
|
+
|
17
|
+
|
18
|
+
class TimeoutTest < Test::Unit::TestCase
|
19
|
+
include TestBaseMixin
|
20
|
+
|
21
|
+
include Rufus::Verbs
|
22
|
+
|
23
|
+
|
24
|
+
def test_0
|
25
|
+
|
26
|
+
error = nil
|
27
|
+
t = Time.now
|
28
|
+
|
29
|
+
begin
|
30
|
+
get :uri => "http://localhost:7777/lost", :to => 1
|
31
|
+
rescue Timeout::Error => e
|
32
|
+
error = e
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_not_nil error
|
36
|
+
assert (Time.now - t < 2)
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-verbs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.10"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-05-28 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- test/test.htdigest
|
59
59
|
- test/test.rb
|
60
60
|
- test/testbase.rb
|
61
|
+
- test/timeout_test.rb
|
61
62
|
- test/uri_test.rb
|
62
63
|
- README.txt
|
63
64
|
has_rdoc: true
|