webmachine 1.0.0 → 1.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.
- data/Gemfile +9 -0
- data/README.md +65 -2
- data/lib/webmachine.rb +1 -0
- data/lib/webmachine/adapters.rb +4 -1
- data/lib/webmachine/adapters/hatetepe.rb +104 -0
- data/lib/webmachine/adapters/lazy_request_body.rb +32 -0
- data/lib/webmachine/adapters/rack.rb +2 -1
- data/lib/webmachine/adapters/reel.rb +45 -0
- data/lib/webmachine/adapters/webrick.rb +1 -30
- data/lib/webmachine/decision/falsey.rb +10 -0
- data/lib/webmachine/decision/flow.rb +28 -26
- data/lib/webmachine/decision/fsm.rb +22 -12
- data/lib/webmachine/decision/helpers.rb +17 -23
- data/lib/webmachine/etags.rb +69 -0
- data/lib/webmachine/headers.rb +42 -0
- data/lib/webmachine/quoted_string.rb +39 -0
- data/lib/webmachine/resource.rb +17 -0
- data/lib/webmachine/resource/callbacks.rb +1 -1
- data/lib/webmachine/resource/entity_tags.rb +17 -0
- data/lib/webmachine/streaming.rb +9 -61
- data/lib/webmachine/streaming/callable_encoder.rb +21 -0
- data/lib/webmachine/streaming/encoder.rb +24 -0
- data/lib/webmachine/streaming/enumerable_encoder.rb +20 -0
- data/lib/webmachine/streaming/fiber_encoder.rb +25 -0
- data/lib/webmachine/streaming/io_encoder.rb +65 -0
- data/lib/webmachine/trace/fsm.rb +9 -4
- data/lib/webmachine/trace/resource_proxy.rb +2 -4
- data/lib/webmachine/trace/static/tracelist.erb +2 -2
- data/lib/webmachine/trace/trace_resource.rb +3 -2
- data/lib/webmachine/version.rb +1 -1
- data/spec/webmachine/adapters/hatetepe_spec.rb +64 -0
- data/spec/webmachine/adapters/rack_spec.rb +18 -8
- data/spec/webmachine/adapters/reel_spec.rb +23 -0
- data/spec/webmachine/decision/falsey_spec.rb +8 -0
- data/spec/webmachine/decision/flow_spec.rb +12 -0
- data/spec/webmachine/decision/fsm_spec.rb +101 -0
- data/spec/webmachine/decision/helpers_spec.rb +68 -8
- data/spec/webmachine/dispatcher/route_spec.rb +1 -1
- data/spec/webmachine/dispatcher_spec.rb +1 -1
- data/spec/webmachine/errors_spec.rb +1 -1
- data/spec/webmachine/etags_spec.rb +75 -0
- data/spec/webmachine/headers_spec.rb +72 -0
- data/spec/webmachine/trace/fsm_spec.rb +5 -0
- data/spec/webmachine/trace/resource_proxy_spec.rb +1 -3
- data/webmachine.gemspec +1 -2
- metadata +49 -20
data/Gemfile
CHANGED
@@ -6,6 +6,15 @@ gemspec
|
|
6
6
|
|
7
7
|
gem 'bundler'
|
8
8
|
|
9
|
+
group :webservers do
|
10
|
+
gem 'mongrel', '~> 1.2.beta', :platform => [:mri, :rbx]
|
11
|
+
if RUBY_VERSION >= '1.9'
|
12
|
+
gem 'reel', '>= 0.1.0', :platform => [:ruby_19, :jruby]
|
13
|
+
gem 'nio4r'
|
14
|
+
end
|
15
|
+
gem 'hatetepe', '~> 0.5'
|
16
|
+
end
|
17
|
+
|
9
18
|
group :guard do
|
10
19
|
gem 'guard-rspec'
|
11
20
|
case RbConfig::CONFIG['host_os']
|
data/README.md
CHANGED
@@ -100,6 +100,19 @@ end
|
|
100
100
|
Webmachine.application.run
|
101
101
|
```
|
102
102
|
|
103
|
+
Webmachine includes adapters for [Webrick][webrick], [Mongrel][mongrel],
|
104
|
+
[Reel][reel], and [Hatetepe]. Additionally, the [Rack][rack] adapter lets it
|
105
|
+
run on any webserver that provides a Rack interface. It also lets it run on
|
106
|
+
[Shotgun][shotgun] ([example][shotgun_example]).
|
107
|
+
|
108
|
+
[webrick]: http://rubydoc.info/stdlib/webrick
|
109
|
+
[mongrel]: https://github.com/evan/mongrel
|
110
|
+
[reel]: https://github.com/celluloid/reel
|
111
|
+
[hatetepe]: https://github.com/lgierth/hatetepe
|
112
|
+
[rack]: https://github.com/rack/rack
|
113
|
+
[shotgun]: https://github.com/rtomayko/shotgun
|
114
|
+
[shotgun_example]: https://gist.github.com/4389220
|
115
|
+
|
103
116
|
### Visual debugger
|
104
117
|
|
105
118
|
It can be hard to understand all of the decisions that Webmachine
|
@@ -156,9 +169,24 @@ for an example of how to enable the debugger.
|
|
156
169
|
* Includes the visual debugger so you can look through the decision
|
157
170
|
graph to determine how your resources are behaving.
|
158
171
|
|
159
|
-
##
|
172
|
+
## Caveats
|
173
|
+
|
174
|
+
* The [Reel](https://github.com/celluloid/reel) adapter might fail with a
|
175
|
+
`SystemStackError` on MRI (< 2.0) due to its limited fiber stack size.
|
176
|
+
The only known solution is to switch to JRuby, Rubinius or MRI 2.0.
|
177
|
+
|
178
|
+
|
179
|
+
## Documentation & Finding Help
|
160
180
|
|
161
|
-
*
|
181
|
+
* [API documentation](http://rubydoc.info/gems/webmachine/frames/file/README.md)
|
182
|
+
* IRC channel #webmachine on freenode
|
183
|
+
|
184
|
+
## Related libraries
|
185
|
+
|
186
|
+
* [irwebmachine](https://github.com/robgleeson/irwebmachine) - IRB/Pry debugging of Webmachine applications
|
187
|
+
* [webmachine-test](https://github.com/bernd/webmachine-test) - Helpers for testing Webmachine applications
|
188
|
+
- [webmachine-linking](https://github.com/petejohanson/webmachine-linking) - Helpers for linking between Resources, and Web Linking
|
189
|
+
- [webmachine-sprockets](https://github.com/lgierth/webmachine-sprockets) - Integration with Sprockets assets packaging system
|
162
190
|
|
163
191
|
## LICENSE
|
164
192
|
|
@@ -168,6 +196,41 @@ LICENSE for details.
|
|
168
196
|
|
169
197
|
## Changelog
|
170
198
|
|
199
|
+
### 1.1.0 January 12, 2013
|
200
|
+
|
201
|
+
1.1.0 is a major feature release that adds the Reel and Hatetepe
|
202
|
+
adapters, support for "weak" entity tags, streaming IO response
|
203
|
+
bodies, better error handling, a shortcut for spinning up specific
|
204
|
+
resources, and a bunch of bugfixes. Added Tony Arcieri, Sebastian
|
205
|
+
Edwards, Russell Garner, Justin McPherson, Paweł Pacana, and Nicholas
|
206
|
+
Young as contributors. Thank you for your contributions!
|
207
|
+
|
208
|
+
* Added Reel adapter.
|
209
|
+
* The trace resource now opens static files in binary mode to ensure
|
210
|
+
compatibility on Windows.
|
211
|
+
* The trace resource uses absolute URIs for its traces.
|
212
|
+
* Added Hatetepe adapter.
|
213
|
+
* Added direct weak entity tag support.
|
214
|
+
* Related libraries are linked from the README.
|
215
|
+
* Removed some circular requires.
|
216
|
+
* Fixed documentation for the `valid_content_headers?` callback.
|
217
|
+
* Fixed `Headers` initialization by downcasing incoming header names.
|
218
|
+
* Added a `Headers#fetch` method.
|
219
|
+
* Conventionally "truthy" and "falsey" values (non-nil, non-false) can
|
220
|
+
now be returned from callbacks that expect a boolean return value.
|
221
|
+
* Updated to the latest RSpec.
|
222
|
+
* Added support for IO response bodies (minimal).
|
223
|
+
* Moved streaming encoders to their own module for clarity.
|
224
|
+
* Added `Resource#run` that starts up a web server with default
|
225
|
+
configuration options and the catch-all route to the resource.
|
226
|
+
* The exception handling flow was improved, clarifying the
|
227
|
+
`handle_exception` and `finish_request` callbacks.
|
228
|
+
* Fix incompatibilities with Rack.
|
229
|
+
* The request URI will not be initialized with parts that are not
|
230
|
+
present in the HTTP request.
|
231
|
+
* The tracing will now commit to storage after the response has been
|
232
|
+
traced.
|
233
|
+
|
171
234
|
### 1.0.0 July 7, 2012
|
172
235
|
|
173
236
|
1.0.0 is a major feature release that finally includes the visual
|
data/lib/webmachine.rb
CHANGED
data/lib/webmachine/adapters.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'webmachine/adapters/lazy_request_body'
|
1
2
|
require 'webmachine/adapters/webrick'
|
2
3
|
|
3
4
|
module Webmachine
|
4
5
|
# Contains classes and modules that connect Webmachine to Ruby
|
5
6
|
# application servers.
|
6
7
|
module Adapters
|
7
|
-
autoload :Mongrel,
|
8
|
+
autoload :Mongrel, 'webmachine/adapters/mongrel'
|
9
|
+
autoload :Reel, 'webmachine/adapters/reel'
|
10
|
+
autoload :Hatetepe, 'webmachine/adapters/hatetepe'
|
8
11
|
end
|
9
12
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'hatetepe/server'
|
2
|
+
|
3
|
+
unless Hatetepe::VERSION >= '0.5.0'
|
4
|
+
raise LoadError, 'webmachine only supports hatetepe >= 0.5.0'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'webmachine/version'
|
8
|
+
require 'webmachine/headers'
|
9
|
+
require 'webmachine/request'
|
10
|
+
require 'webmachine/response'
|
11
|
+
require 'webmachine/dispatcher'
|
12
|
+
require 'webmachine/chunked_body'
|
13
|
+
|
14
|
+
module Webmachine
|
15
|
+
module Adapters
|
16
|
+
class Hatetepe < Adapter
|
17
|
+
def options
|
18
|
+
{
|
19
|
+
:host => configuration.ip,
|
20
|
+
:port => configuration.port,
|
21
|
+
:app => [
|
22
|
+
::Hatetepe::Server::Pipeline,
|
23
|
+
::Hatetepe::Server::KeepAlive,
|
24
|
+
method(:call)
|
25
|
+
]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
EM.epoll
|
31
|
+
EM.synchrony do
|
32
|
+
::Hatetepe::Server.start(options)
|
33
|
+
trap("INT") { EM.stop }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def call(request, &respond)
|
38
|
+
response = Webmachine::Response.new
|
39
|
+
dispatcher.dispatch(convert_request(request), response)
|
40
|
+
|
41
|
+
respond.call(convert_response(response))
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def convert_request(request)
|
47
|
+
args = [
|
48
|
+
request.verb,
|
49
|
+
build_request_uri(request),
|
50
|
+
Webmachine::Headers[request.headers.dup],
|
51
|
+
Body.new(request.body)
|
52
|
+
]
|
53
|
+
Webmachine::Request.new(*args)
|
54
|
+
end
|
55
|
+
|
56
|
+
def convert_response(response)
|
57
|
+
response.headers["Server"] = [
|
58
|
+
Webmachine::SERVER_STRING,
|
59
|
+
"hatetepe/#{::Hatetepe::VERSION}"
|
60
|
+
].join(" ")
|
61
|
+
|
62
|
+
args = [
|
63
|
+
response.code.to_i,
|
64
|
+
response.headers,
|
65
|
+
convert_body(response.body)
|
66
|
+
]
|
67
|
+
::Hatetepe::Response.new(*args)
|
68
|
+
end
|
69
|
+
|
70
|
+
def convert_body(body)
|
71
|
+
if body.respond_to?(:call)
|
72
|
+
[ body.call ]
|
73
|
+
elsif body.respond_to?(:to_s)
|
74
|
+
[ body.to_s ]
|
75
|
+
else
|
76
|
+
body
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_request_uri(request)
|
81
|
+
uri = URI.parse(request.uri)
|
82
|
+
uri.scheme = "http"
|
83
|
+
|
84
|
+
host = request.headers.fetch("Host", "").split(":")
|
85
|
+
uri.host = host[0] || configuration.ip
|
86
|
+
uri.port = host[1].to_i || configuration.port
|
87
|
+
|
88
|
+
URI.parse(uri.to_s)
|
89
|
+
end
|
90
|
+
|
91
|
+
class Body < Struct.new(:body)
|
92
|
+
def each(&block)
|
93
|
+
body.rewind
|
94
|
+
body.each(&block)
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_s
|
98
|
+
body.rewind
|
99
|
+
body.read.to_s
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
module Webmachine
|
3
|
+
module Adapters
|
4
|
+
# Wraps a request body so that it can be passed to
|
5
|
+
# {Request} while still lazily evaluating the body.
|
6
|
+
class LazyRequestBody
|
7
|
+
def initialize(request)
|
8
|
+
@request = request
|
9
|
+
end
|
10
|
+
|
11
|
+
# Converts the body to a String so you can work with the entire
|
12
|
+
# thing.
|
13
|
+
def to_s
|
14
|
+
@value ? @value.join : @request.body
|
15
|
+
end
|
16
|
+
|
17
|
+
# Iterates over the body in chunks. If the body has previously
|
18
|
+
# been read, this method can be called again and get the same
|
19
|
+
# sequence of chunks.
|
20
|
+
# @yield [chunk]
|
21
|
+
# @yieldparam [String] chunk a chunk of the request body
|
22
|
+
def each
|
23
|
+
if @value
|
24
|
+
@value.each {|chunk| yield chunk }
|
25
|
+
else
|
26
|
+
@value = []
|
27
|
+
@request.body {|chunk| @value << chunk; yield chunk }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end # class RequestBody
|
31
|
+
end # module Adapters
|
32
|
+
end # module Webmachine
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'reel'
|
2
|
+
require 'webmachine/version'
|
3
|
+
require 'webmachine/headers'
|
4
|
+
require 'webmachine/request'
|
5
|
+
require 'webmachine/response'
|
6
|
+
require 'webmachine/dispatcher'
|
7
|
+
require 'webmachine/chunked_body'
|
8
|
+
|
9
|
+
module Webmachine
|
10
|
+
module Adapters
|
11
|
+
class Reel < Adapter
|
12
|
+
def run
|
13
|
+
options = {
|
14
|
+
:port => configuration.port,
|
15
|
+
:host => configuration.ip
|
16
|
+
}.merge(configuration.adapter_options)
|
17
|
+
server = ::Reel::Server.supervise(options[:host], options[:port], &method(:process))
|
18
|
+
trap("INT"){ server.terminate; exit 0 }
|
19
|
+
sleep
|
20
|
+
end
|
21
|
+
|
22
|
+
def process(connection)
|
23
|
+
while wreq = connection.request
|
24
|
+
header = Webmachine::Headers[wreq.headers.dup]
|
25
|
+
host_parts = header.fetch('Host').split(':')
|
26
|
+
path_parts = wreq.url.split('?')
|
27
|
+
requri = URI::HTTP.build({}.tap do |h|
|
28
|
+
h[:host] = host_parts.first
|
29
|
+
h[:port] = host_parts.last.to_i if host_parts.length == 2
|
30
|
+
h[:path] = path_parts.first
|
31
|
+
h[:query] = path_parts.last if path_parts.length == 2
|
32
|
+
end)
|
33
|
+
request = Webmachine::Request.new(wreq.method.to_s.upcase,
|
34
|
+
requri,
|
35
|
+
header,
|
36
|
+
LazyRequestBody.new(wreq))
|
37
|
+
response = Webmachine::Response.new
|
38
|
+
@dispatcher.dispatch(request,response)
|
39
|
+
|
40
|
+
connection.respond ::Reel::Response.new(response.code, response.headers, response.body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -35,7 +35,7 @@ module Webmachine
|
|
35
35
|
request = Webmachine::Request.new(wreq.request_method,
|
36
36
|
wreq.request_uri,
|
37
37
|
header,
|
38
|
-
|
38
|
+
LazyRequestBody.new(wreq))
|
39
39
|
response = Webmachine::Response.new
|
40
40
|
@dispatcher.dispatch(request, response)
|
41
41
|
wres.status = response.code.to_i
|
@@ -61,35 +61,6 @@ module Webmachine
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end # class Server
|
64
|
-
|
65
|
-
# Wraps the WEBrick request body so that it can be passed to
|
66
|
-
# {Request} while still lazily evaluating the body.
|
67
|
-
class RequestBody
|
68
|
-
def initialize(request)
|
69
|
-
@request = request
|
70
|
-
end
|
71
|
-
|
72
|
-
# Converts the body to a String so you can work with the entire
|
73
|
-
# thing.
|
74
|
-
def to_s
|
75
|
-
@value ? @value.join : @request.body
|
76
|
-
end
|
77
|
-
|
78
|
-
# Iterates over the body in chunks. If the body has previously
|
79
|
-
# been read, this method can be called again and get the same
|
80
|
-
# sequence of chunks.
|
81
|
-
# @yield [chunk]
|
82
|
-
# @yieldparam [String] chunk a chunk of the request body
|
83
|
-
def each
|
84
|
-
if @value
|
85
|
-
@value.each {|chunk| yield chunk }
|
86
|
-
else
|
87
|
-
@value = []
|
88
|
-
@request.body {|chunk| @value << chunk; yield chunk }
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end # class RequestBody
|
92
|
-
|
93
64
|
end # module WEBrick
|
94
65
|
end # module Adapters
|
95
66
|
end # module Webmachine
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'time'
|
2
2
|
require 'digest/md5'
|
3
3
|
require 'webmachine/decision/conneg'
|
4
|
+
require 'webmachine/decision/falsey'
|
4
5
|
require 'webmachine/translation'
|
6
|
+
require 'webmachine/etags'
|
5
7
|
|
6
8
|
module Webmachine
|
7
9
|
module Decision
|
@@ -27,30 +29,30 @@ module Webmachine
|
|
27
29
|
include Translation
|
28
30
|
|
29
31
|
# Handles standard decisions where halting is allowed
|
30
|
-
def decision_test(test,
|
32
|
+
def decision_test(test, iftrue, iffalse)
|
31
33
|
case test
|
32
|
-
when value
|
33
|
-
iftrue
|
34
34
|
when Fixnum # Allows callbacks to "halt" with a given response code
|
35
35
|
test
|
36
|
-
|
36
|
+
when Falsey
|
37
37
|
iffalse
|
38
|
+
else
|
39
|
+
iftrue
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
# Service available?
|
42
44
|
def b13
|
43
|
-
decision_test(resource.service_available?,
|
45
|
+
decision_test(resource.service_available?, :b12, 503)
|
44
46
|
end
|
45
47
|
|
46
48
|
# Known method?
|
47
49
|
def b12
|
48
|
-
decision_test(resource.known_methods.include?(request.method),
|
50
|
+
decision_test(resource.known_methods.include?(request.method), :b11, 501)
|
49
51
|
end
|
50
52
|
|
51
53
|
# URI too long?
|
52
54
|
def b11
|
53
|
-
decision_test(resource.uri_too_long?(request.uri),
|
55
|
+
decision_test(resource.uri_too_long?(request.uri), 414, :b10)
|
54
56
|
end
|
55
57
|
|
56
58
|
# Method allowed?
|
@@ -90,7 +92,7 @@ module Webmachine
|
|
90
92
|
|
91
93
|
# Malformed?
|
92
94
|
def b9b
|
93
|
-
decision_test(resource.malformed_request?,
|
95
|
+
decision_test(resource.malformed_request?, 400, :b8)
|
94
96
|
end
|
95
97
|
|
96
98
|
# Authorized?
|
@@ -111,22 +113,22 @@ module Webmachine
|
|
111
113
|
|
112
114
|
# Forbidden?
|
113
115
|
def b7
|
114
|
-
decision_test(resource.forbidden?,
|
116
|
+
decision_test(resource.forbidden?, 403, :b6)
|
115
117
|
end
|
116
118
|
|
117
119
|
# Okay Content-* Headers?
|
118
120
|
def b6
|
119
|
-
decision_test(resource.valid_content_headers?(request.headers.grep(/content-/)),
|
121
|
+
decision_test(resource.valid_content_headers?(request.headers.grep(/content-/)), :b5, 501)
|
120
122
|
end
|
121
123
|
|
122
124
|
# Known Content-Type?
|
123
125
|
def b5
|
124
|
-
decision_test(resource.known_content_type?(request.content_type),
|
126
|
+
decision_test(resource.known_content_type?(request.content_type), :b4, 415)
|
125
127
|
end
|
126
128
|
|
127
129
|
# Req Entity Too Large?
|
128
130
|
def b4
|
129
|
-
decision_test(resource.valid_entity_length?(request.content_length),
|
131
|
+
decision_test(resource.valid_entity_length?(request.content_length), :b3, 413)
|
130
132
|
end
|
131
133
|
|
132
134
|
# OPTIONS?
|
@@ -223,7 +225,7 @@ module Webmachine
|
|
223
225
|
def g7
|
224
226
|
# This is the first place after all conneg, so set Vary here
|
225
227
|
response.headers['Vary'] = variances.join(", ") if variances.any?
|
226
|
-
decision_test(resource.resource_exists?,
|
228
|
+
decision_test(resource.resource_exists?, :g8, :h7)
|
227
229
|
end
|
228
230
|
|
229
231
|
# If-Match exists?
|
@@ -233,18 +235,18 @@ module Webmachine
|
|
233
235
|
|
234
236
|
# If-Match: * exists?
|
235
237
|
def g9
|
236
|
-
request.if_match == "*" ? :h10 : :g11
|
238
|
+
quote(request.if_match) == '"*"' ? :h10 : :g11
|
237
239
|
end
|
238
240
|
|
239
241
|
# ETag in If-Match
|
240
242
|
def g11
|
241
|
-
request_etags = request.if_match.split(/\s*,\s*/).map {|etag|
|
242
|
-
request_etags.include?(resource.generate_etag) ? :h10 : 412
|
243
|
+
request_etags = request.if_match.split(/\s*,\s*/).map {|etag| ETag.new(etag) }
|
244
|
+
request_etags.include?(ETag.new(resource.generate_etag)) ? :h10 : 412
|
243
245
|
end
|
244
246
|
|
245
247
|
# If-Match exists?
|
246
248
|
def h7
|
247
|
-
(request.if_match &&
|
249
|
+
(request.if_match && unquote(request.if_match) == '*') ? 412 : :i7
|
248
250
|
end
|
249
251
|
|
250
252
|
# If-Unmodified-Since exists?
|
@@ -292,7 +294,7 @@ module Webmachine
|
|
292
294
|
|
293
295
|
# If-none-match: * exists?
|
294
296
|
def i13
|
295
|
-
request.if_none_match == "*" ? :j18 : :k13
|
297
|
+
quote(request.if_none_match) == '"*"' ? :j18 : :k13
|
296
298
|
end
|
297
299
|
|
298
300
|
# GET or HEAD?
|
@@ -315,13 +317,13 @@ module Webmachine
|
|
315
317
|
|
316
318
|
# Previously existed?
|
317
319
|
def k7
|
318
|
-
decision_test(resource.previously_existed?,
|
320
|
+
decision_test(resource.previously_existed?, :k5, :l7)
|
319
321
|
end
|
320
322
|
|
321
323
|
# Etag in if-none-match?
|
322
324
|
def k13
|
323
|
-
request_etags = request.if_none_match.split(/\s*,\s*/).map {|etag|
|
324
|
-
request_etags.include?(resource.generate_etag) ? :j18 : :l13
|
325
|
+
request_etags = request.if_none_match.split(/\s*,\s*/).map {|etag| ETag.new(etag) }
|
326
|
+
request_etags.include?(ETag.new(resource.generate_etag)) ? :j18 : :l13
|
325
327
|
end
|
326
328
|
|
327
329
|
# Moved temporarily?
|
@@ -374,7 +376,7 @@ module Webmachine
|
|
374
376
|
|
375
377
|
# Server allows POST to missing resource?
|
376
378
|
def m7
|
377
|
-
decision_test(resource.allow_missing_post?,
|
379
|
+
decision_test(resource.allow_missing_post?, :n11, 404)
|
378
380
|
end
|
379
381
|
|
380
382
|
# DELETE?
|
@@ -384,17 +386,17 @@ module Webmachine
|
|
384
386
|
|
385
387
|
# DELETE enacted immediately? (Also where DELETE is forced.)
|
386
388
|
def m20
|
387
|
-
decision_test(resource.delete_resource,
|
389
|
+
decision_test(resource.delete_resource, :m20b, 500)
|
388
390
|
end
|
389
391
|
|
390
392
|
# Did the DELETE complete?
|
391
393
|
def m20b
|
392
|
-
decision_test(resource.delete_completed?,
|
394
|
+
decision_test(resource.delete_completed?, :o20, 202)
|
393
395
|
end
|
394
396
|
|
395
397
|
# Server allows POST to missing resource?
|
396
398
|
def n5
|
397
|
-
decision_test(resource.allow_missing_post?,
|
399
|
+
decision_test(resource.allow_missing_post?, :n11, 410)
|
398
400
|
end
|
399
401
|
|
400
402
|
# Redirect?
|
@@ -475,7 +477,7 @@ module Webmachine
|
|
475
477
|
|
476
478
|
# Multiple choices?
|
477
479
|
def o18b
|
478
|
-
decision_test(resource.multiple_choices?,
|
480
|
+
decision_test(resource.multiple_choices?, 300, 200)
|
479
481
|
end
|
480
482
|
|
481
483
|
# Response includes an entity?
|