public
Description: GET, POST, PUT, DELETE, with something around (ruby)
Homepage: http://rufus.rubyforge.org/rufus-verbs
Clone URL: git://github.com/jmettraux/rufus-verbs.git
rufus-verbs / test / items.rb
922ca113 » jmettraux 2008-03-31 first commit 1 #
2 # an in-memory resource set for testing rufus-verbs
3 #
4 # jmettraux@gmail.com
5 #
6 # Fri Jan 11 12:36:45 JST 2008
7 #
8
9 require 'date'
10 require 'webrick'
11
12
13 $dcount = 0 # tracking the number of hits when doing digest auth
14
15
16 #
17 # the hash for the /items resource (collection)
18 #
19 class LastModifiedHash
20
21 def initialize
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 22
922ca113 » jmettraux 2008-03-31 first commit 23 @hash = {}
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 24 touch
25 end
26
922ca113 » jmettraux 2008-03-31 first commit 27 def touch (key=nil)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 28
922ca113 » jmettraux 2008-03-31 first commit 29 now = Time.now.httpdate
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 30 @hash[key] = now if key
31 @hash['__self'] = now
32 end
33
922ca113 » jmettraux 2008-03-31 first commit 34 def delete (key)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 35
922ca113 » jmettraux 2008-03-31 first commit 36 @hash.delete key
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 37 @hash['__self'] = Time.now.httpdate
38 end
39
922ca113 » jmettraux 2008-03-31 first commit 40 def last_modified (key)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 41
922ca113 » jmettraux 2008-03-31 first commit 42 key = key || '__self'
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 43 @hash[key]
44 end
45
922ca113 » jmettraux 2008-03-31 first commit 46 def clear
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 47
922ca113 » jmettraux 2008-03-31 first commit 48 @hash.clear
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 49 @hash['__self'] = Time.now.httpdate
50 end
51 end
922ca113 » jmettraux 2008-03-31 first commit 52
53
54 #
55 # This servlet provides a RESTful in-memory resource "/items".
56 #
57 class ItemServlet < WEBrick::HTTPServlet::AbstractServlet
58
59 @@items = {}
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 60 @@last_item_id = -1
61
922ca113 » jmettraux 2008-03-31 first commit 62 @@lastmod = LastModifiedHash.new
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 63
922ca113 » jmettraux 2008-03-31 first commit 64 @@authenticator = WEBrick::HTTPAuth::DigestAuth.new(
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 65 :UserDB => WEBrick::HTTPAuth::Htdigest.new('test/test.htdigest'),
66 :Realm => 'test_realm')
67
922ca113 » jmettraux 2008-03-31 first commit 68 def initialize (server, *options)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 69
922ca113 » jmettraux 2008-03-31 first commit 70 super
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 71 @auth = server.auth
72 end
73
922ca113 » jmettraux 2008-03-31 first commit 74 #
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 75 # Overriding the service() method to perform a potential auth check
76 #
77 def service (req, res)
78
922ca113 » jmettraux 2008-03-31 first commit 79 if @auth == :basic
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 80
922ca113 » jmettraux 2008-03-31 first commit 81 WEBrick::HTTPAuth.basic_auth(req, res, "items") do |u, p|
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 82 (u != nil and u == p)
83 end
84
922ca113 » jmettraux 2008-03-31 first commit 85 elsif @auth == :digest
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 86
922ca113 » jmettraux 2008-03-31 first commit 87 $dcount += 1
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 88 @@authenticator.authenticate(req, res)
89 end
922ca113 » jmettraux 2008-03-31 first commit 90
91 super
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 92 end
93
94 def do_GET (req, res)
95
922ca113 » jmettraux 2008-03-31 first commit 96 i = item_id req
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 97
922ca113 » jmettraux 2008-03-31 first commit 98 return reply(res, 404, "no item '#{i}'") \
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 99 if i and not items[i]
100
922ca113 » jmettraux 2008-03-31 first commit 101 representation, et, lm = fetch_representation i
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 102
922ca113 » jmettraux 2008-03-31 first commit 103 since = req['If-Modified-Since']
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 104 since = DateTime.parse(since) if since
105 match = req['If-None-Match']
106
922ca113 » jmettraux 2008-03-31 first commit 107 if ((not since and not match) or
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 108 (since and (since > DateTime.parse(lm))) or
109 (match and (match != et)))
110
922ca113 » jmettraux 2008-03-31 first commit 111 res['Etag'] = et
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 112 res['Last-Modified'] = lm
113 res.body = representation.inspect + "\n"
114
922ca113 » jmettraux 2008-03-31 first commit 115 else
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 116
922ca113 » jmettraux 2008-03-31 first commit 117 reply(res, 304, "Not Modified")
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 118 end
922ca113 » jmettraux 2008-03-31 first commit 119 end
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 120
922ca113 » jmettraux 2008-03-31 first commit 121 def do_POST (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 122
922ca113 » jmettraux 2008-03-31 first commit 123 query = WEBrick::HTTPUtils::parse_query(req.query_string)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 124 m = query['_method']
125 m = m.downcase if m
126 return do_PUT(req, res) if m == 'put'
127 return do_DELETE(req, res) if m == 'delete'
128
922ca113 » jmettraux 2008-03-31 first commit 129 i = item_id req
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 130
9a7742c3 » jmettraux 2008-05-26 bug #20362 : Items test ser... 131 i = (@@last_item_id += 1) unless i
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 132
9a7742c3 » jmettraux 2008-05-26 bug #20362 : Items test ser... 133 items[i] = req.body
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 134 lastmod.touch i
135
922ca113 » jmettraux 2008-03-31 first commit 136 res['Location'] = "#{@host}/items/#{i}"
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 137 reply res, 201, "item created"
138 end
139
922ca113 » jmettraux 2008-03-31 first commit 140 def do_PUT (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 141
922ca113 » jmettraux 2008-03-31 first commit 142 i = item_id req
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 143
922ca113 » jmettraux 2008-03-31 first commit 144 return reply(res, 404, "no item '#{i}'") unless items[i]
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 145
922ca113 » jmettraux 2008-03-31 first commit 146 items[i] = req.body
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 147 lastmod.touch i
148
922ca113 » jmettraux 2008-03-31 first commit 149 reply res, 200, "item updated"
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 150 end
151
922ca113 » jmettraux 2008-03-31 first commit 152 def do_DELETE (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 153
922ca113 » jmettraux 2008-03-31 first commit 154 i = item_id req
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 155
922ca113 » jmettraux 2008-03-31 first commit 156 return reply(res, 404, "no item '#{i}'") unless items[i]
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 157
922ca113 » jmettraux 2008-03-31 first commit 158 items.delete i
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 159 lastmod.delete i
160
922ca113 » jmettraux 2008-03-31 first commit 161 reply res, 200, "item deleted"
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 162 end
163
922ca113 » jmettraux 2008-03-31 first commit 164 #
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 165 # clears the items
166 #
167 def self.flush
168
922ca113 » jmettraux 2008-03-31 first commit 169 @@items.clear
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 170 @@lastmod.clear
171 end
172
922ca113 » jmettraux 2008-03-31 first commit 173 protected
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 174
922ca113 » jmettraux 2008-03-31 first commit 175 def items
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 176 @@items
177 end
178
9a7742c3 » jmettraux 2008-05-26 bug #20362 : Items test ser... 179 def lastmod
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 180 @@lastmod
181 end
182
922ca113 » jmettraux 2008-03-31 first commit 183 def is_modified (req, key)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 184
922ca113 » jmettraux 2008-03-31 first commit 185 since = req['If-Modified-Since']
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 186 match = req['If-None-Match']
187
922ca113 » jmettraux 2008-03-31 first commit 188 return true unless since or match
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 189
922ca113 » jmettraux 2008-03-31 first commit 190 #puts
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 191 #p [ since, match ]
192 #puts
193
922ca113 » jmettraux 2008-03-31 first commit 194 (since or match)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 195 end
196
922ca113 » jmettraux 2008-03-31 first commit 197 #
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 198 # Returns representation, etag, last_modified
199 #
200 def fetch_representation (key=nil)
201
922ca113 » jmettraux 2008-03-31 first commit 202 representation = if key
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 203 items[key]
204 else
205 items
206 end
207
922ca113 » jmettraux 2008-03-31 first commit 208 [ representation,
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 209 representation.inspect.hash.to_s,
210 lastmod.last_modified(key) ]
211 end
212
922ca113 » jmettraux 2008-03-31 first commit 213 def reply (res, code, message)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 214
922ca113 » jmettraux 2008-03-31 first commit 215 res.status = code
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 216 res.body = message + "\n"
217 res['Content-type'] = "text/plain"
218 end
219
922ca113 » jmettraux 2008-03-31 first commit 220 def item_id (req)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 221
922ca113 » jmettraux 2008-03-31 first commit 222 p = req.path_info[1..-1]
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 223 return nil if not p or p == ''
224 p.to_i
225 end
226 end
922ca113 » jmettraux 2008-03-31 first commit 227
228 #
229 # just redirecting to the ItemServlet...
230 #
231 class ThingServlet < WEBrick::HTTPServlet::AbstractServlet
232
233 def do_GET (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 234
922ca113 » jmettraux 2008-03-31 first commit 235 res.set_redirect(
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 236 WEBrick::HTTPStatus[303],
237 "http://localhost:7777/items")
238 end
239 end
922ca113 » jmettraux 2008-03-31 first commit 240
241 #
242 # testing Rufus::Verbs cookies...
243 #
244 class CookieServlet < WEBrick::HTTPServlet::AbstractServlet
245
246 @@sessions = {}
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 247
922ca113 » jmettraux 2008-03-31 first commit 248 def do_GET (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 249
922ca113 » jmettraux 2008-03-31 first commit 250 res.body = get_session(req, res).inspect
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 251 end
252
922ca113 » jmettraux 2008-03-31 first commit 253 def do_POST (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 254
922ca113 » jmettraux 2008-03-31 first commit 255 get_session(req, res) << req.body.strip
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 256 res.body = "ok."
257 end
258
922ca113 » jmettraux 2008-03-31 first commit 259 protected
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 260
922ca113 » jmettraux 2008-03-31 first commit 261 def get_session (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 262
922ca113 » jmettraux 2008-03-31 first commit 263 c = req.cookies.find { |c| c.name == 'tcookie' }
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 264
922ca113 » jmettraux 2008-03-31 first commit 265 if c
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 266 @@sessions[c.value]
267 else
268 s = []
269 key = (Time.now.to_f * 100000).to_i.to_s
270 @@sessions[key] = s
271 res.cookies << WEBrick::Cookie.new('tcookie', key)
272 s
273 end
274 end
275 end
922ca113 » jmettraux 2008-03-31 first commit 276
277 #
278 # a servlet that doesn't reply (for timeout testing)
a8e7dc8b » jmettraux 2008-05-26 todo #18981 : added timeout... 279 #
280 class LostServlet < WEBrick::HTTPServlet::AbstractServlet
281
282 def do_GET (req, res)
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 283
a8e7dc8b » jmettraux 2008-05-26 todo #18981 : added timeout... 284 sleep 200
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 285 end
286 end
a8e7dc8b » jmettraux 2008-05-26 todo #18981 : added timeout... 287
288 #
289 # Serving items, a dummy resource...
922ca113 » jmettraux 2008-03-31 first commit 290 # Also serving things, which just redirect to items...
291 #
292 class ItemServer
293
294 def initialize (args={})
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 295
922ca113 » jmettraux 2008-03-31 first commit 296 port = args[:port] || 7777
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 297
922ca113 » jmettraux 2008-03-31 first commit 298 #al = [
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 299 # [ "", WEBrick::AccessLog::COMMON_LOG_FORMAT ],
300 # [ "", WEBrick::AccessLog::REFERER_LOG_FORMAT ]]
301
922ca113 » jmettraux 2008-03-31 first commit 302 @server = WEBrick::HTTPServer.new :Port => port, :AccessLog => nil
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 303
922ca113 » jmettraux 2008-03-31 first commit 304 class << @server
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 305 attr_accessor :auth
306 end
307
922ca113 » jmettraux 2008-03-31 first commit 308 @server.auth = args[:auth]
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 309
922ca113 » jmettraux 2008-03-31 first commit 310 @server.mount "/items", ItemServlet
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 311 @server.mount "/things", ThingServlet
312 @server.mount "/cookie", CookieServlet
313 @server.mount "/lost", LostServlet
314
922ca113 » jmettraux 2008-03-31 first commit 315 [ 'INT', 'TERM' ].each do |signal|
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 316 trap(signal) { shutdown }
317 end
922ca113 » jmettraux 2008-03-31 first commit 318 end
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 319
922ca113 » jmettraux 2008-03-31 first commit 320 def start
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 321
922ca113 » jmettraux 2008-03-31 first commit 322 Thread.new { @server.start }
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 323 # else the server and the test lock each other
324 end
325
922ca113 » jmettraux 2008-03-31 first commit 326 def shutdown
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 327
922ca113 » jmettraux 2008-03-31 first commit 328 ItemServlet.flush
3159e3a1 » jmettraux 2009-03-23 spring 2009 cleanup 329 @server.shutdown
330 end
331 end
922ca113 » jmettraux 2008-03-31 first commit 332
333