This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
rufus-verbs / test / items.rb
| 922ca113 » | jmettraux | 2008-03-31 | 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 | 22 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 23 | @hash = {} | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 24 | touch | |
| 25 | end | ||||
| 26 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 27 | def touch (key=nil) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 28 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 29 | now = Time.now.httpdate | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 30 | @hash[key] = now if key | |
| 31 | @hash['__self'] = now | ||||
| 32 | end | ||||
| 33 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 34 | def delete (key) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 35 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 36 | @hash.delete key | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 37 | @hash['__self'] = Time.now.httpdate | |
| 38 | end | ||||
| 39 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 40 | def last_modified (key) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 41 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 42 | key = key || '__self' | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 43 | @hash[key] | |
| 44 | end | ||||
| 45 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 46 | def clear | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 47 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 48 | @hash.clear | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 49 | @hash['__self'] = Time.now.httpdate | |
| 50 | end | ||||
| 51 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 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 | 60 | @@last_item_id = -1 | |
| 61 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 62 | @@lastmod = LastModifiedHash.new | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 63 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 64 | @@authenticator = WEBrick::HTTPAuth::DigestAuth.new( | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 65 | :UserDB => WEBrick::HTTPAuth::Htdigest.new('test/test.htdigest'), | |
| 66 | :Realm => 'test_realm') | ||||
| 67 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 68 | def initialize (server, *options) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 69 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 70 | super | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 71 | @auth = server.auth | |
| 72 | end | ||||
| 73 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 74 | # | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 75 | # Overriding the service() method to perform a potential auth check | |
| 76 | # | ||||
| 77 | def service (req, res) | ||||
| 78 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 79 | if @auth == :basic | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 80 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 81 | WEBrick::HTTPAuth.basic_auth(req, res, "items") do |u, p| | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 82 | (u != nil and u == p) | |
| 83 | end | ||||
| 84 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 85 | elsif @auth == :digest | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 86 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 87 | $dcount += 1 | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 88 | @@authenticator.authenticate(req, res) | |
| 89 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 90 | ||
| 91 | super | ||||
| 3159e3a1 » | jmettraux | 2009-03-23 | 92 | end | |
| 93 | |||||
| 94 | def do_GET (req, res) | ||||
| 95 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 96 | i = item_id req | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 97 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 98 | return reply(res, 404, "no item '#{i}'") \ | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 99 | if i and not items[i] | |
| 100 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 101 | representation, et, lm = fetch_representation i | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 102 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 103 | since = req['If-Modified-Since'] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 104 | since = DateTime.parse(since) if since | |
| 105 | match = req['If-None-Match'] | ||||
| 106 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 107 | if ((not since and not match) or | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 108 | (since and (since > DateTime.parse(lm))) or | |
| 109 | (match and (match != et))) | ||||
| 110 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 111 | res['Etag'] = et | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 112 | res['Last-Modified'] = lm | |
| 113 | res.body = representation.inspect + "\n" | ||||
| 114 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 115 | else | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 116 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 117 | reply(res, 304, "Not Modified") | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 118 | end | |
| 922ca113 » | jmettraux | 2008-03-31 | 119 | end | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 120 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 121 | def do_POST (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 122 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 123 | query = WEBrick::HTTPUtils::parse_query(req.query_string) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 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 | 129 | i = item_id req | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 130 | ||
| 9a7742c3 » | jmettraux | 2008-05-26 | 131 | i = (@@last_item_id += 1) unless i | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 132 | ||
| 9a7742c3 » | jmettraux | 2008-05-26 | 133 | items[i] = req.body | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 134 | lastmod.touch i | |
| 135 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 136 | res['Location'] = "#{@host}/items/#{i}" | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 137 | reply res, 201, "item created" | |
| 138 | end | ||||
| 139 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 140 | def do_PUT (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 141 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 142 | i = item_id req | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 143 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 144 | return reply(res, 404, "no item '#{i}'") unless items[i] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 145 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 146 | items[i] = req.body | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 147 | lastmod.touch i | |
| 148 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 149 | reply res, 200, "item updated" | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 150 | end | |
| 151 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 152 | def do_DELETE (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 153 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 154 | i = item_id req | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 155 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 156 | return reply(res, 404, "no item '#{i}'") unless items[i] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 157 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 158 | items.delete i | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 159 | lastmod.delete i | |
| 160 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 161 | reply res, 200, "item deleted" | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 162 | end | |
| 163 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 164 | # | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 165 | # clears the items | |
| 166 | # | ||||
| 167 | def self.flush | ||||
| 168 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 169 | @@items.clear | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 170 | @@lastmod.clear | |
| 171 | end | ||||
| 172 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 173 | protected | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 174 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 175 | def items | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 176 | @@items | |
| 177 | end | ||||
| 178 | |||||
| 9a7742c3 » | jmettraux | 2008-05-26 | 179 | def lastmod | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 180 | @@lastmod | |
| 181 | end | ||||
| 182 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 183 | def is_modified (req, key) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 184 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 185 | since = req['If-Modified-Since'] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 186 | match = req['If-None-Match'] | |
| 187 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 188 | return true unless since or match | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 189 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 190 | #puts | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 191 | #p [ since, match ] | |
| 192 | #puts | ||||
| 193 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 194 | (since or match) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 195 | end | |
| 196 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 197 | # | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 198 | # Returns representation, etag, last_modified | |
| 199 | # | ||||
| 200 | def fetch_representation (key=nil) | ||||
| 201 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 202 | representation = if key | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 203 | items[key] | |
| 204 | else | ||||
| 205 | items | ||||
| 206 | end | ||||
| 207 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 208 | [ representation, | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 209 | representation.inspect.hash.to_s, | |
| 210 | lastmod.last_modified(key) ] | ||||
| 211 | end | ||||
| 212 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 213 | def reply (res, code, message) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 214 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 215 | res.status = code | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 216 | res.body = message + "\n" | |
| 217 | res['Content-type'] = "text/plain" | ||||
| 218 | end | ||||
| 219 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 220 | def item_id (req) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 221 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 222 | p = req.path_info[1..-1] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 223 | return nil if not p or p == '' | |
| 224 | p.to_i | ||||
| 225 | end | ||||
| 226 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 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 | 234 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 235 | res.set_redirect( | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 236 | WEBrick::HTTPStatus[303], | |
| 237 | "http://localhost:7777/items") | ||||
| 238 | end | ||||
| 239 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 240 | ||
| 241 | # | ||||
| 242 | # testing Rufus::Verbs cookies... | ||||
| 243 | # | ||||
| 244 | class CookieServlet < WEBrick::HTTPServlet::AbstractServlet | ||||
| 245 | |||||
| 246 | @@sessions = {} | ||||
| 3159e3a1 » | jmettraux | 2009-03-23 | 247 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 248 | def do_GET (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 249 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 250 | res.body = get_session(req, res).inspect | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 251 | end | |
| 252 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 253 | def do_POST (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 254 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 255 | get_session(req, res) << req.body.strip | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 256 | res.body = "ok." | |
| 257 | end | ||||
| 258 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 259 | protected | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 260 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 261 | def get_session (req, res) | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 262 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 263 | c = req.cookies.find { |c| c.name == 'tcookie' } | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 264 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 265 | if c | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 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 | 276 | ||
| 277 | # | ||||
| 278 | # a servlet that doesn't reply (for timeout testing) | ||||
| a8e7dc8b » | jmettraux | 2008-05-26 | 279 | # | |
| 280 | class LostServlet < WEBrick::HTTPServlet::AbstractServlet | ||||
| 281 | |||||
| 282 | def do_GET (req, res) | ||||
| 3159e3a1 » | jmettraux | 2009-03-23 | 283 | ||
| a8e7dc8b » | jmettraux | 2008-05-26 | 284 | sleep 200 | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 285 | end | |
| 286 | end | ||||
| a8e7dc8b » | jmettraux | 2008-05-26 | 287 | ||
| 288 | # | ||||
| 289 | # Serving items, a dummy resource... | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 290 | # Also serving things, which just redirect to items... | |
| 291 | # | ||||
| 292 | class ItemServer | ||||
| 293 | |||||
| 294 | def initialize (args={}) | ||||
| 3159e3a1 » | jmettraux | 2009-03-23 | 295 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 296 | port = args[:port] || 7777 | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 297 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 298 | #al = [ | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 299 | # [ "", WEBrick::AccessLog::COMMON_LOG_FORMAT ], | |
| 300 | # [ "", WEBrick::AccessLog::REFERER_LOG_FORMAT ]] | ||||
| 301 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 302 | @server = WEBrick::HTTPServer.new :Port => port, :AccessLog => nil | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 303 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 304 | class << @server | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 305 | attr_accessor :auth | |
| 306 | end | ||||
| 307 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 308 | @server.auth = args[:auth] | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 309 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 310 | @server.mount "/items", ItemServlet | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 311 | @server.mount "/things", ThingServlet | |
| 312 | @server.mount "/cookie", CookieServlet | ||||
| 313 | @server.mount "/lost", LostServlet | ||||
| 314 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 315 | [ 'INT', 'TERM' ].each do |signal| | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 316 | trap(signal) { shutdown } | |
| 317 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 318 | end | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 319 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 320 | def start | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 321 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 322 | Thread.new { @server.start } | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 323 | # else the server and the test lock each other | |
| 324 | end | ||||
| 325 | |||||
| 922ca113 » | jmettraux | 2008-03-31 | 326 | def shutdown | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 327 | ||
| 922ca113 » | jmettraux | 2008-03-31 | 328 | ItemServlet.flush | |
| 3159e3a1 » | jmettraux | 2009-03-23 | 329 | @server.shutdown | |
| 330 | end | ||||
| 331 | end | ||||
| 922ca113 » | jmettraux | 2008-03-31 | 332 | ||
| 333 | |||||







