Module: Webmachine::Decision::Flow
- Includes:
- Conneg, Translation
- Included in:
- FSM
- Defined in:
- lib/webmachine/decision/flow.rb
Overview
This module encapsulates all of the decisions in Webmachine's flow-chart. These invoke Resource::Callbacks methods to determine the appropriate response code, headers, and body for the response.
This module is included into FSM, which drives the processing of the chart.
Constant Summary
- VERSION =
Version of the flow diagram
3- START =
The first state in flow diagram
:b13
Constants included from Conneg
Instance Method Summary (collapse)
-
- (Object) b10
Method allowed?.
-
- (Object) b11
URI too long?.
-
- (Object) b12
Known method?.
-
- (Object) b13
Service available?.
-
- (Object) b3
OPTIONS?.
-
- (Object) b4
Req Entity Too Large?.
-
- (Object) b5
Known Content-Type?.
-
- (Object) b6
Okay Content-* Headers?.
-
- (Object) b7
Forbidden?.
-
- (Object) b8
Authorized?.
-
- (Object) b9
Content-MD5 present?.
-
- (Object) b9a
Content-MD5 valid?.
-
- (Object) b9b
Malformed?.
-
- (Object) c3
Accept exists?.
-
- (Object) c4
Acceptable media type available?.
-
- (Object) d4
Accept-Language exists?.
-
- (Object) d5
Acceptable language available?.
-
- (Object) decision_test(test, iftrue, iffalse)
Handles standard decisions where halting is allowed.
-
- (Object) e5
Accept-Charset exists?.
-
- (Object) e6
Acceptable Charset available?.
-
- (Object) f6
Accept-Encoding exists? (also, set content-type header here, now that charset is chosen).
-
- (Object) f7
Acceptable encoding available?.
-
- (Object) g11
ETag in If-Match.
-
- (Object) g7
Resource exists?.
-
- (Object) g8
If-Match exists?.
-
- (Object) g9
If-Match: * exists?.
-
- (Object) h10
If-Unmodified-Since exists?.
-
- (Object) h11
If-Unmodified-Since is valid date?.
-
- (Object) h12
Last-Modified > I-UM-S?.
-
- (Object) h7
If-Match exists?.
-
- (Object) i12
If-none-match exists?.
-
- (Object) i13
If-none-match: * exists?.
-
- (Object) i4
Moved permanently? (apply PUT to different URI).
-
- (Object) i7
PUT?.
-
- (Object) j18
GET or HEAD?.
-
- (Object) k13
Etag in if-none-match?.
-
- (Object) k5
Moved permanently?.
-
- (Object) k7
Previously existed?.
-
- (Object) l13
If-Modified-Since exists?.
-
- (Object) l14
IMS is valid date?.
-
- (Object) l15
IMS > Now?.
-
- (Object) l17
Last-Modified > IMS?.
-
- (Object) l5
Moved temporarily?.
-
- (Object) l7
POST?.
-
- (Object) m16
DELETE?.
-
- (Object) m20
DELETE enacted immediately? (Also where DELETE is forced.).
-
- (Object) m20b
Did the DELETE complete?.
-
- (Object) m5
POST?.
-
- (Object) m7
Server allows POST to missing resource?.
-
- (Object) n11
Redirect?.
-
- (Object) n16
POST?.
-
- (Object) n5
Server allows POST to missing resource?.
-
- (Object) o14
Conflict?.
-
- (Object) o16
PUT?.
-
- (Object) o18
Multiple representations? Also where body generation for GET and HEAD is done.
-
- (Object) o18b
Multiple choices?.
-
- (Object) o20
Response includes an entity?.
-
- (Object) p11
New resource?.
-
- (Object) p3
Conflict?.
Methods included from Translation
Methods included from Conneg
#choose_charset, #choose_encoding, #choose_language, #choose_media_type, #do_choose, #language_match
Instance Method Details
- (Object) b10
Method allowed?
59 60 61 62 63 64 65 66 |
# File 'lib/webmachine/decision/flow.rb', line 59 def b10 if resource.allowed_methods.include?(request.method) :b9 else response.headers["Allow"] = resource.allowed_methods.join(", ") 405 end end |
- (Object) b11
URI too long?
54 55 56 |
# File 'lib/webmachine/decision/flow.rb', line 54 def b11 decision_test(resource.uri_too_long?(request.uri), 414, :b10) end |
- (Object) b12
Known method?
49 50 51 |
# File 'lib/webmachine/decision/flow.rb', line 49 def b12 decision_test(resource.known_methods.include?(request.method), :b11, 501) end |
- (Object) b13
Service available?
44 45 46 |
# File 'lib/webmachine/decision/flow.rb', line 44 def b13 decision_test(resource.service_available?, :b12, 503) end |
- (Object) b3
OPTIONS?
135 136 137 138 139 140 141 142 |
# File 'lib/webmachine/decision/flow.rb', line 135 def b3 if request. response.headers.merge!(resource.) 200 else :c3 end end |
- (Object) b4
Req Entity Too Large?
130 131 132 |
# File 'lib/webmachine/decision/flow.rb', line 130 def b4 decision_test(resource.valid_entity_length?(request.content_length), :b3, 413) end |
- (Object) b5
Known Content-Type?
125 126 127 |
# File 'lib/webmachine/decision/flow.rb', line 125 def b5 decision_test(resource.known_content_type?(request.content_type), :b4, 415) end |
- (Object) b6
Okay Content-* Headers?
120 121 122 |
# File 'lib/webmachine/decision/flow.rb', line 120 def b6 decision_test(resource.valid_content_headers?(request.headers.grep(/content-/)), :b5, 501) end |
- (Object) b7
Forbidden?
115 116 117 |
# File 'lib/webmachine/decision/flow.rb', line 115 def b7 decision_test(resource.forbidden?, 403, :b6) end |
- (Object) b8
Authorized?
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/webmachine/decision/flow.rb', line 99 def b8 result = resource.(request.) case result when true :b7 when Fixnum result when String response.headers['WWW-Authenticate'] = result 401 else 401 end end |
- (Object) b9
Content-MD5 present?
69 70 71 |
# File 'lib/webmachine/decision/flow.rb', line 69 def b9 request.content_md5 ? :b9a : :b9b end |
- (Object) b9a
Content-MD5 valid?
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/webmachine/decision/flow.rb', line 74 def b9a case valid = resource.validate_content_checksum when Fixnum valid when true :b9b when false response.body = "Content-MD5 header does not match request body." 400 else # not_validated if request.content_md5 == Digest::MD5.hexdigest(request.body) :b9b else response.body = "Content-MD5 header does not match request body." 400 end end end |
- (Object) b9b
Malformed?
94 95 96 |
# File 'lib/webmachine/decision/flow.rb', line 94 def b9b decision_test(resource.malformed_request?, 400, :b8) end |
- (Object) c3
Accept exists?
145 146 147 148 149 150 151 152 |
# File 'lib/webmachine/decision/flow.rb', line 145 def c3 if !request.accept ['Content-Type'] = MediaType.parse(resource.content_types_provided.first.first) :d4 else :c4 end end |
- (Object) c4
Acceptable media type available?
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/webmachine/decision/flow.rb', line 155 def c4 types = resource.content_types_provided.map {|pair| pair.first } chosen_type = choose_media_type(types, request.accept) if !chosen_type 406 else ['Content-Type'] = chosen_type :d4 end end |
- (Object) d4
Accept-Language exists?
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/webmachine/decision/flow.rb', line 167 def d4 if !request.accept_language if language = choose_language(resource.languages_provided, "*") resource.language_chosen(language) :e5 else 406 end else :d5 end end |
- (Object) d5
Acceptable language available?
181 182 183 184 185 186 187 188 |
# File 'lib/webmachine/decision/flow.rb', line 181 def d5 if language = choose_language(resource.languages_provided, request.accept_language) resource.language_chosen(language) :e5 else 406 end end |
- (Object) decision_test(test, iftrue, iffalse)
Handles standard decisions where halting is allowed
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/webmachine/decision/flow.rb', line 32 def decision_test(test, iftrue, iffalse) case test when Fixnum # Allows callbacks to "halt" with a given response code test when Falsey iffalse else iftrue end end |
- (Object) e5
Accept-Charset exists?
191 192 193 194 195 196 197 |
# File 'lib/webmachine/decision/flow.rb', line 191 def e5 if !request.accept_charset choose_charset(resource.charsets_provided, "*") ? :f6 : 406 else :e6 end end |
- (Object) e6
Acceptable Charset available?
200 201 202 |
# File 'lib/webmachine/decision/flow.rb', line 200 def e6 choose_charset(resource.charsets_provided, request.accept_charset) ? :f6 : 406 end |
- (Object) f6
Accept-Encoding exists? (also, set content-type header here, now that charset is chosen)
206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/webmachine/decision/flow.rb', line 206 def f6 chosen_type = ['Content-Type'] if chosen_charset = ['Charset'] chosen_type.params['charset'] = chosen_charset end response.headers['Content-Type'] = chosen_type.to_s if !request.accept_encoding choose_encoding(resource.encodings_provided, "identity;q=1.0,*;q=0.5") ? :g7 : 406 else :f7 end end |
- (Object) f7
Acceptable encoding available?
220 221 222 |
# File 'lib/webmachine/decision/flow.rb', line 220 def f7 choose_encoding(resource.encodings_provided, request.accept_encoding) ? :g7 : 406 end |
- (Object) g11
ETag in If-Match
242 243 244 245 |
# File 'lib/webmachine/decision/flow.rb', line 242 def g11 = request.if_match.split(/\s*,\s*/).map {|etag| ETag.new(etag) } .include?(ETag.new(resource.generate_etag)) ? :h10 : 412 end |
- (Object) g7
Resource exists?
225 226 227 228 229 |
# File 'lib/webmachine/decision/flow.rb', line 225 def g7 # This is the first place after all conneg, so set Vary here response.headers['Vary'] = variances.join(", ") if variances.any? decision_test(resource.resource_exists?, :g8, :h7) end |
- (Object) g8
If-Match exists?
232 233 234 |
# File 'lib/webmachine/decision/flow.rb', line 232 def g8 request.if_match ? :g9 : :h10 end |
- (Object) g9
If-Match: * exists?
237 238 239 |
# File 'lib/webmachine/decision/flow.rb', line 237 def g9 quote(request.if_match) == '"*"' ? :h10 : :g11 end |
- (Object) h10
If-Unmodified-Since exists?
253 254 255 |
# File 'lib/webmachine/decision/flow.rb', line 253 def h10 request.if_unmodified_since ? :h11 : :i12 end |
- (Object) h11
If-Unmodified-Since is valid date?
258 259 260 261 262 263 264 265 |
# File 'lib/webmachine/decision/flow.rb', line 258 def h11 date = Time.httpdate(request.if_unmodified_since) ['If-Unmodified-Since'] = date rescue ArgumentError :i12 else :h12 end |
- (Object) h12
Last-Modified > I-UM-S?
268 269 270 |
# File 'lib/webmachine/decision/flow.rb', line 268 def h12 resource.last_modified > ['If-Unmodified-Since'] ? 412 : :i12 end |
- (Object) h7
If-Match exists?
248 249 250 |
# File 'lib/webmachine/decision/flow.rb', line 248 def h7 (request.if_match && unquote(request.if_match) == '*') ? 412 : :i7 end |
- (Object) i12
If-none-match exists?
291 292 293 |
# File 'lib/webmachine/decision/flow.rb', line 291 def i12 request.if_none_match ? :i13 : :l13 end |
- (Object) i13
If-none-match: * exists?
296 297 298 |
# File 'lib/webmachine/decision/flow.rb', line 296 def i13 quote(request.if_none_match) == '"*"' ? :j18 : :k13 end |
- (Object) i4
Moved permanently? (apply PUT to different URI)
273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/webmachine/decision/flow.rb', line 273 def i4 case uri = resource.moved_permanently? when String, URI response.headers["Location"] = uri.to_s 301 when Fixnum uri else :p3 end end |
- (Object) i7
PUT?
286 287 288 |
# File 'lib/webmachine/decision/flow.rb', line 286 def i7 request.put? ? :i4 : :k7 end |
- (Object) j18
GET or HEAD?
301 302 303 |
# File 'lib/webmachine/decision/flow.rb', line 301 def j18 (request.get? || request.head?) ? 304 : 412 end |
- (Object) k13
Etag in if-none-match?
324 325 326 327 |
# File 'lib/webmachine/decision/flow.rb', line 324 def k13 = request.if_none_match.split(/\s*,\s*/).map {|etag| ETag.new(etag) } .include?(ETag.new(resource.generate_etag)) ? :j18 : :l13 end |
- (Object) k5
Moved permanently?
306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/webmachine/decision/flow.rb', line 306 def k5 case uri = resource.moved_permanently? when String, URI response.headers["Location"] = uri.to_s 301 when Fixnum uri else :l5 end end |
- (Object) k7
Previously existed?
319 320 321 |
# File 'lib/webmachine/decision/flow.rb', line 319 def k7 decision_test(resource.previously_existed?, :k5, :l7) end |
- (Object) l13
If-Modified-Since exists?
348 349 350 |
# File 'lib/webmachine/decision/flow.rb', line 348 def l13 request.if_modified_since ? :l14 : :m16 end |
- (Object) l14
IMS is valid date?
353 354 355 356 357 358 359 360 |
# File 'lib/webmachine/decision/flow.rb', line 353 def l14 date = Time.httpdate(request.if_modified_since) ['If-Modified-Since'] = date rescue ArgumentError :m16 else :l15 end |
- (Object) l15
IMS > Now?
363 364 365 |
# File 'lib/webmachine/decision/flow.rb', line 363 def l15 ['If-Modified-Since'] > Time.now ? :m16 : :l17 end |
- (Object) l17
Last-Modified > IMS?
368 369 370 |
# File 'lib/webmachine/decision/flow.rb', line 368 def l17 resource.last_modified.nil? || resource.last_modified > ['If-Modified-Since'] ? :m16 : 304 end |
- (Object) l5
Moved temporarily?
330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/webmachine/decision/flow.rb', line 330 def l5 case uri = resource.moved_temporarily? when String, URI response.headers["Location"] = uri.to_s 307 when Fixnum uri else :m5 end end |
- (Object) l7
POST?
343 344 345 |
# File 'lib/webmachine/decision/flow.rb', line 343 def l7 request.post? ? :m7 : 404 end |
- (Object) m16
DELETE?
383 384 385 |
# File 'lib/webmachine/decision/flow.rb', line 383 def m16 request.delete? ? :m20 : :n16 end |
- (Object) m20
DELETE enacted immediately? (Also where DELETE is forced.)
388 389 390 |
# File 'lib/webmachine/decision/flow.rb', line 388 def m20 decision_test(resource.delete_resource, :m20b, 500) end |
- (Object) m20b
Did the DELETE complete?
393 394 395 |
# File 'lib/webmachine/decision/flow.rb', line 393 def m20b decision_test(resource.delete_completed?, :o20, 202) end |
- (Object) m5
POST?
373 374 375 |
# File 'lib/webmachine/decision/flow.rb', line 373 def m5 request.post? ? :n5 : 410 end |
- (Object) m7
Server allows POST to missing resource?
378 379 380 |
# File 'lib/webmachine/decision/flow.rb', line 378 def m7 decision_test(resource.allow_missing_post?, :n11, 404) end |
- (Object) n11
Redirect?
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/webmachine/decision/flow.rb', line 403 def n11 # Stage1 if resource.post_is_create? case uri = resource.create_path when nil raise InvalidResource, t('create_path_nil', :class => resource.class) when URI, String base_uri = resource.base_uri || request.base_uri new_uri = URI.join(base_uri.to_s, uri) request.disp_path = new_uri.path response.headers['Location'] = new_uri.to_s result = accept_helper return result if Fixnum === result end else case result = resource.process_post when true encode_body_if_set when Fixnum return result else raise InvalidResource, t('process_post_invalid', :result => result.inspect) end end if response.is_redirect? if response.headers['Location'] 303 else raise InvalidResource, t('do_redirect') end else :p11 end end |
- (Object) n16
POST?
439 440 441 |
# File 'lib/webmachine/decision/flow.rb', line 439 def n16 request.post? ? :n11 : :o16 end |
- (Object) n5
Server allows POST to missing resource?
398 399 400 |
# File 'lib/webmachine/decision/flow.rb', line 398 def n5 decision_test(resource.allow_missing_post?, :n11, 410) end |
- (Object) o14
Conflict?
444 445 446 447 448 449 450 451 |
# File 'lib/webmachine/decision/flow.rb', line 444 def o14 if resource.is_conflict? 409 else res = accept_helper (Fixnum === res) ? res : :p11 end end |
- (Object) o16
PUT?
454 455 456 |
# File 'lib/webmachine/decision/flow.rb', line 454 def o16 request.put? ? :o14 : :o18 end |
- (Object) o18
Multiple representations? Also where body generation for GET and HEAD is done.
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
# File 'lib/webmachine/decision/flow.rb', line 460 def o18 if request.get? || request.head? add_caching_headers content_type = ['Content-Type'] handler = resource.content_types_provided.find {|ct, _| content_type.type_matches?(MediaType.parse(ct)) }.last result = resource.send(handler) if Fixnum === result result else response.body = result encode_body :o18b end else :o18b end end |
- (Object) o18b
Multiple choices?
479 480 481 |
# File 'lib/webmachine/decision/flow.rb', line 479 def o18b decision_test(resource.multiple_choices?, 300, 200) end |
- (Object) o20
Response includes an entity?
484 485 486 |
# File 'lib/webmachine/decision/flow.rb', line 484 def o20 has_response_body? ? :o18 : 204 end |
- (Object) p11
New resource?
499 500 501 |
# File 'lib/webmachine/decision/flow.rb', line 499 def p11 !response.headers["Location"] ? :o20 : 201 end |
- (Object) p3
Conflict?
489 490 491 492 493 494 495 496 |
# File 'lib/webmachine/decision/flow.rb', line 489 def p3 if resource.is_conflict? 409 else res = accept_helper (Fixnum === res) ? res : :p11 end end |