webmachine 1.2.2 → 1.3.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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +13 -11
  5. data/README.md +85 -89
  6. data/Rakefile +0 -1
  7. data/documentation/adapters.md +39 -0
  8. data/documentation/authentication-and-authorization.md +37 -0
  9. data/documentation/configurator.md +19 -0
  10. data/documentation/error-handling.md +86 -0
  11. data/documentation/examples.md +215 -0
  12. data/documentation/how-it-works.md +76 -0
  13. data/documentation/routes.md +97 -0
  14. data/documentation/validation.md +159 -0
  15. data/documentation/versioning-apis.md +74 -0
  16. data/documentation/visual-debugger.md +38 -0
  17. data/examples/application.rb +2 -2
  18. data/examples/debugger.rb +1 -1
  19. data/lib/webmachine.rb +3 -1
  20. data/lib/webmachine/adapter.rb +7 -13
  21. data/lib/webmachine/adapters.rb +1 -2
  22. data/lib/webmachine/adapters/httpkit.rb +74 -0
  23. data/lib/webmachine/adapters/lazy_request_body.rb +1 -2
  24. data/lib/webmachine/adapters/rack.rb +37 -21
  25. data/lib/webmachine/adapters/reel.rb +21 -23
  26. data/lib/webmachine/adapters/webrick.rb +16 -16
  27. data/lib/webmachine/application.rb +2 -2
  28. data/lib/webmachine/chunked_body.rb +3 -4
  29. data/lib/webmachine/constants.rb +75 -0
  30. data/lib/webmachine/decision/conneg.rb +12 -10
  31. data/lib/webmachine/decision/flow.rb +31 -21
  32. data/lib/webmachine/decision/fsm.rb +10 -18
  33. data/lib/webmachine/decision/helpers.rb +9 -37
  34. data/lib/webmachine/dispatcher.rb +13 -10
  35. data/lib/webmachine/dispatcher/route.rb +18 -8
  36. data/lib/webmachine/errors.rb +7 -1
  37. data/lib/webmachine/header_negotiation.rb +25 -0
  38. data/lib/webmachine/headers.rb +7 -2
  39. data/lib/webmachine/locale/en.yml +7 -5
  40. data/lib/webmachine/media_type.rb +10 -8
  41. data/lib/webmachine/request.rb +44 -15
  42. data/lib/webmachine/resource.rb +1 -1
  43. data/lib/webmachine/resource/callbacks.rb +6 -4
  44. data/lib/webmachine/spec/IO_response.body +1 -0
  45. data/lib/webmachine/spec/adapter_lint.rb +70 -36
  46. data/lib/webmachine/spec/test_resource.rb +10 -4
  47. data/lib/webmachine/streaming/fiber_encoder.rb +1 -5
  48. data/lib/webmachine/streaming/io_encoder.rb +6 -0
  49. data/lib/webmachine/trace.rb +1 -0
  50. data/lib/webmachine/trace/fsm.rb +20 -10
  51. data/lib/webmachine/trace/resource_proxy.rb +2 -0
  52. data/lib/webmachine/translation.rb +2 -1
  53. data/lib/webmachine/version.rb +3 -3
  54. data/memory_test.rb +37 -0
  55. data/spec/spec_helper.rb +9 -9
  56. data/spec/webmachine/adapter_spec.rb +14 -15
  57. data/spec/webmachine/adapters/httpkit_spec.rb +10 -0
  58. data/spec/webmachine/adapters/rack_spec.rb +6 -6
  59. data/spec/webmachine/adapters/reel_spec.rb +15 -11
  60. data/spec/webmachine/adapters/webrick_spec.rb +2 -2
  61. data/spec/webmachine/application_spec.rb +18 -17
  62. data/spec/webmachine/chunked_body_spec.rb +3 -3
  63. data/spec/webmachine/configuration_spec.rb +5 -5
  64. data/spec/webmachine/cookie_spec.rb +13 -13
  65. data/spec/webmachine/decision/conneg_spec.rb +48 -42
  66. data/spec/webmachine/decision/falsey_spec.rb +4 -4
  67. data/spec/webmachine/decision/flow_spec.rb +194 -144
  68. data/spec/webmachine/decision/fsm_spec.rb +17 -17
  69. data/spec/webmachine/decision/helpers_spec.rb +20 -20
  70. data/spec/webmachine/dispatcher/route_spec.rb +73 -27
  71. data/spec/webmachine/dispatcher_spec.rb +34 -24
  72. data/spec/webmachine/errors_spec.rb +1 -1
  73. data/spec/webmachine/etags_spec.rb +19 -19
  74. data/spec/webmachine/events_spec.rb +6 -6
  75. data/spec/webmachine/headers_spec.rb +14 -14
  76. data/spec/webmachine/media_type_spec.rb +36 -36
  77. data/spec/webmachine/request_spec.rb +33 -33
  78. data/spec/webmachine/resource/authentication_spec.rb +6 -6
  79. data/spec/webmachine/response_spec.rb +12 -12
  80. data/spec/webmachine/trace/fsm_spec.rb +8 -8
  81. data/spec/webmachine/trace/resource_proxy_spec.rb +9 -9
  82. data/spec/webmachine/trace/trace_store_spec.rb +5 -5
  83. data/spec/webmachine/trace_spec.rb +3 -3
  84. data/webmachine.gemspec +2 -6
  85. metadata +48 -206
  86. data/lib/webmachine/adapters/hatetepe.rb +0 -108
  87. data/lib/webmachine/adapters/mongrel.rb +0 -127
  88. data/lib/webmachine/dispatcher/not_found_resource.rb +0 -5
  89. data/lib/webmachine/fiber18.rb +0 -88
  90. data/spec/webmachine/adapters/hatetepe_spec.rb +0 -60
  91. data/spec/webmachine/adapters/mongrel_spec.rb +0 -16
@@ -1,9 +1,11 @@
1
+ require 'webmachine/adapter'
1
2
  require 'webrick'
2
- require 'webmachine/version'
3
+ require 'webmachine/constants'
3
4
  require 'webmachine/headers'
5
+ require 'webmachine/adapters/lazy_request_body'
4
6
  require 'webmachine/request'
5
7
  require 'webmachine/response'
6
- require 'webmachine/dispatcher'
8
+ require 'webmachine/version'
7
9
 
8
10
  module Webmachine
9
11
  module Adapters
@@ -15,22 +17,19 @@ module Webmachine
15
17
  # Starts the WEBrick adapter
16
18
  def run
17
19
  options = DEFAULT_OPTIONS.merge({
18
- :Port => configuration.port,
19
- :BindAddress => configuration.ip
20
- }).merge(configuration.adapter_options)
21
- @server = Server.new(dispatcher, options)
22
- trap("INT") { shutdown }
20
+ :Port => application.configuration.port,
21
+ :BindAddress => application.configuration.ip,
22
+ :application => application
23
+ }).merge(application.configuration.adapter_options)
24
+ @server = Server.new(options)
23
25
  @server.start
24
26
  end
25
27
 
26
- def shutdown
27
- @server.shutdown if @server
28
- end
29
-
30
28
  # WEBRick::HTTPServer that is run by the WEBrick adapter.
31
29
  class Server < ::WEBrick::HTTPServer
32
- def initialize(dispatcher, options)
33
- @dispatcher = dispatcher
30
+
31
+ def initialize(options)
32
+ @application = options[:application]
34
33
  super(options)
35
34
  end
36
35
 
@@ -42,8 +41,9 @@ module Webmachine
42
41
  wreq.request_uri,
43
42
  header,
44
43
  LazyRequestBody.new(wreq))
44
+
45
45
  response = Webmachine::Response.new
46
- @dispatcher.dispatch(request, response)
46
+ @application.dispatcher.dispatch(request, response)
47
47
  wres.status = response.code.to_i
48
48
 
49
49
  headers = response.headers.flattened.reject { |k,v| k == 'Set-Cookie' }
@@ -52,12 +52,12 @@ module Webmachine
52
52
  cookies = [response.headers['Set-Cookie'] || []].flatten
53
53
  cookies.each { |c| wres.cookies << c }
54
54
 
55
- wres['Server'] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(" ")
55
+ wres[SERVER] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(" ")
56
56
  case response.body
57
57
  when String
58
58
  wres.body << response.body
59
59
  when Enumerable
60
- wres.chunked = response.headers['Transfer-Encoding'] == 'chunked'
60
+ wres.chunked = response.headers[TRANSFER_ENCODING] == 'chunked'
61
61
  response.body.each {|part| wres.body << part }
62
62
  else
63
63
  if response.body.respond_to?(:call)
@@ -8,7 +8,7 @@ module Webmachine
8
8
  #
9
9
  # MyApp = Webmachine::Application.new do |app|
10
10
  # app.routes do
11
- # add ['*'], AssetResource
11
+ # add [:*], AssetResource
12
12
  # end
13
13
  #
14
14
  # app.configure do |config|
@@ -56,7 +56,7 @@ module Webmachine
56
56
  # @return an instance of the configured web-server adapter
57
57
  # @see Adapters
58
58
  def adapter
59
- @adapter ||= adapter_class.new(configuration, dispatcher)
59
+ @adapter ||= adapter_class.new(self)
60
60
  end
61
61
 
62
62
  # @return an instance of the configured web-server adapter
@@ -1,3 +1,5 @@
1
+ require 'webmachine/constants'
2
+
1
3
  module Webmachine
2
4
  # {ChunkedBody} is used to wrap an {Enumerable} object (like an enumerable
3
5
  # {Response#body}) so it yields proper chunks for chunked transfer encoding.
@@ -13,11 +15,8 @@ module Webmachine
13
15
  #
14
16
  # This is needed for Ruby webservers which don't do the chunking themselves.
15
17
  class ChunkedBody
16
- # Delimiter for chunked encoding
17
- CRLF = "\r\n"
18
-
19
18
  # Final chunk in any chunked-encoding response
20
- FINAL_CHUNK = "0#{CRLF}#{CRLF}"
19
+ FINAL_CHUNK = "0#{CRLF}#{CRLF}".freeze
21
20
 
22
21
  # Creates a new {ChunkedBody} from the given {Enumerable}.
23
22
  # @param [Enumerable] body the enumerable response body
@@ -0,0 +1,75 @@
1
+ module Webmachine
2
+ # Universal HTTP delimiter
3
+ CRLF = "\r\n".freeze
4
+
5
+ # HTTP Content-Type
6
+ CONTENT_TYPE = 'Content-Type'.freeze
7
+
8
+ # Default Content-Type
9
+ TEXT_HTML = 'text/html'.freeze
10
+
11
+ # HTTP Date
12
+ DATE = 'Date'.freeze
13
+
14
+ # HTTP Transfer-Encoding
15
+ TRANSFER_ENCODING = 'Transfer-Encoding'.freeze
16
+
17
+ # HTTP Content-Length
18
+ CONTENT_LENGTH = 'Content-Length'.freeze
19
+
20
+ # A underscore
21
+ UNDERSCORE = '_'.freeze
22
+
23
+ # A dash
24
+ DASH = '-'.freeze
25
+
26
+ # A Slash
27
+ SLASH = '/'.freeze
28
+
29
+ MATCHES_ALL = '*/*'.freeze
30
+
31
+ GET_METHOD = "GET"
32
+ HEAD_METHOD = "HEAD"
33
+ POST_METHOD = "POST"
34
+ PUT_METHOD = "PUT"
35
+ DELETE_METHOD = "DELETE"
36
+ OPTIONS_METHOD = "OPTIONS"
37
+ TRACE_METHOD = "TRACE"
38
+ CONNECT_METHOD = "CONNECT"
39
+
40
+ STANDARD_HTTP_METHODS = [
41
+ GET_METHOD, HEAD_METHOD, POST_METHOD,
42
+ PUT_METHOD, DELETE_METHOD, TRACE_METHOD,
43
+ CONNECT_METHOD, OPTIONS_METHOD
44
+ ].map!(&:freeze)
45
+ STANDARD_HTTP_METHODS.freeze
46
+
47
+ # A colon
48
+ COLON = ':'.freeze
49
+
50
+ # http string
51
+ HTTP = 'http'.freeze
52
+
53
+ # Host string
54
+ HOST = 'Host'.freeze
55
+
56
+ # HTTP Content-Encoding
57
+ CONTENT_ENCODING = 'Content-Encoding'.freeze
58
+
59
+ # Charset string
60
+ CHARSET = 'Charset'.freeze
61
+
62
+ # Semicolon split match
63
+ SPLIT_SEMI = /\s*,\s*/.freeze
64
+
65
+ # Star Character
66
+ STAR = '*'.freeze
67
+
68
+ # HTTP Location
69
+ LOCATION = 'Location'.freeze
70
+
71
+ # identity Encoding
72
+ IDENTITY = 'identity'.freeze
73
+
74
+ SERVER = 'Server'.freeze
75
+ end
@@ -1,3 +1,4 @@
1
+ require 'webmachine/constants'
1
2
  require 'webmachine/translation'
2
3
  require 'webmachine/media_type'
3
4
 
@@ -13,7 +14,8 @@ module Webmachine
13
14
  # appropriate media type.
14
15
  # @api private
15
16
  def choose_media_type(provided, header)
16
- requested = MediaTypeList.build(header.split(/\s*,\s*/))
17
+ types = Array(header).map{|h| h.split(SPLIT_SEMI) }.flatten
18
+ requested = MediaTypeList.build(types)
17
19
  provided = provided.map do |p| # normalize_provided
18
20
  MediaType.parse(p)
19
21
  end
@@ -30,9 +32,9 @@ module Webmachine
30
32
  # @api private
31
33
  def choose_encoding(provided, header)
32
34
  encodings = provided.keys
33
- if encoding = do_choose(encodings, header, "identity")
34
- response.headers['Content-Encoding'] = encoding unless encoding == 'identity'
35
- metadata['Content-Encoding'] = encoding
35
+ if encoding = do_choose(encodings, header, IDENTITY)
36
+ response.headers[CONTENT_ENCODING] = encoding unless encoding == IDENTITY
37
+ metadata[CONTENT_ENCODING] = encoding
36
38
  end
37
39
  end
38
40
 
@@ -43,7 +45,7 @@ module Webmachine
43
45
  if provided && !provided.empty?
44
46
  charsets = provided.map {|c| c.first }
45
47
  if charset = do_choose(charsets, header, HAS_ENCODING ? Encoding.default_external.name : kcode_charset)
46
- metadata['Charset'] = charset
48
+ metadata[CHARSET] = charset
47
49
  end
48
50
  else
49
51
  true
@@ -55,8 +57,8 @@ module Webmachine
55
57
  # @api private
56
58
  def choose_language(provided, header)
57
59
  if provided && !provided.empty?
58
- requested = PriorityList.build(header.split(/\s*,\s*/))
59
- star_priority = requested.priority_of("*")
60
+ requested = PriorityList.build(header.split(SPLIT_SEMI))
61
+ star_priority = requested.priority_of(STAR)
60
62
  any_ok = star_priority && star_priority > 0.0
61
63
  accepted = requested.find do |priority, range|
62
64
  if priority == 0.0
@@ -97,9 +99,9 @@ module Webmachine
97
99
  # @api private
98
100
  def do_choose(choices, header, default)
99
101
  choices = choices.dup.map {|s| s.downcase }
100
- accepted = PriorityList.build(header.split(/\s*,\s*/))
102
+ accepted = PriorityList.build(header.split(SPLIT_SEMI))
101
103
  default_priority = accepted.priority_of(default)
102
- star_priority = accepted.priority_of("*")
104
+ star_priority = accepted.priority_of(STAR)
103
105
  default_ok = (default_priority.nil? && star_priority != 0.0) || default_priority
104
106
  any_ok = star_priority && star_priority > 0.0
105
107
  chosen = accepted.find do |priority, acceptable|
@@ -117,7 +119,7 @@ module Webmachine
117
119
 
118
120
  private
119
121
  # Matches acceptable items that include 'q' values
120
- CONNEG_REGEX = /^\s*(\S+);\s*q=(\S*)\s*$/
122
+ CONNEG_REGEX = /^\s*(\S+);\s*q=(\S*)\s*$/.freeze
121
123
 
122
124
  # Matches the requested media type (with potential modifiers)
123
125
  # against the provided types (with potential modifiers).
@@ -1,5 +1,7 @@
1
- require 'time'
1
+ require 'time'
2
2
  require 'digest/md5'
3
+ require 'base64'
4
+ require 'webmachine/constants'
3
5
  require 'webmachine/decision/conneg'
4
6
  require 'webmachine/decision/falsey'
5
7
  require 'webmachine/translation'
@@ -16,6 +18,8 @@ module Webmachine
16
18
  # of the chart.
17
19
  # @see https://raw.github.com/wiki/basho/webmachine/images/http-headers-status-v3.png
18
20
  module Flow
21
+ include Base64
22
+
19
23
  # Version of the flow diagram
20
24
  VERSION = 3
21
25
 
@@ -81,7 +85,7 @@ module Webmachine
81
85
  response.body = "Content-MD5 header does not match request body."
82
86
  400
83
87
  else # not_validated
84
- if request.content_md5 == Digest::MD5.hexdigest(request.body)
88
+ if decode64(request.content_md5) == Digest::MD5.hexdigest(request.body)
85
89
  :b9b
86
90
  else
87
91
  response.body = "Content-MD5 header does not match request body."
@@ -116,9 +120,10 @@ module Webmachine
116
120
  decision_test(resource.forbidden?, 403, :b6)
117
121
  end
118
122
 
123
+ CONTENT = /content-/.freeze
119
124
  # Okay Content-* Headers?
120
125
  def b6
121
- decision_test(resource.valid_content_headers?(request.headers.grep(/content-/)), :b5, 501)
126
+ decision_test(resource.valid_content_headers?(request.headers.grep(CONTENT)), :b5, 501)
122
127
  end
123
128
 
124
129
  # Known Content-Type?
@@ -144,7 +149,7 @@ module Webmachine
144
149
  # Accept exists?
145
150
  def c3
146
151
  if !request.accept
147
- metadata['Content-Type'] = MediaType.parse(resource.content_types_provided.first.first)
152
+ metadata[CONTENT_TYPE] = MediaType.parse(resource.content_types_provided.first.first)
148
153
  :d4
149
154
  else
150
155
  :c4
@@ -158,7 +163,7 @@ module Webmachine
158
163
  if !chosen_type
159
164
  406
160
165
  else
161
- metadata['Content-Type'] = chosen_type
166
+ metadata[CONTENT_TYPE] = chosen_type
162
167
  :d4
163
168
  end
164
169
  end
@@ -166,7 +171,7 @@ module Webmachine
166
171
  # Accept-Language exists?
167
172
  def d4
168
173
  if !request.accept_language
169
- if language = choose_language(resource.languages_provided, "*")
174
+ if language = choose_language(resource.languages_provided, STAR)
170
175
  resource.language_chosen(language)
171
176
  :e5
172
177
  else
@@ -190,7 +195,7 @@ module Webmachine
190
195
  # Accept-Charset exists?
191
196
  def e5
192
197
  if !request.accept_charset
193
- choose_charset(resource.charsets_provided, "*") ? :f6 : 406
198
+ choose_charset(resource.charsets_provided, STAR) ? :f6 : 406
194
199
  else
195
200
  :e6
196
201
  end
@@ -204,11 +209,11 @@ module Webmachine
204
209
  # Accept-Encoding exists?
205
210
  # (also, set content-type header here, now that charset is chosen)
206
211
  def f6
207
- chosen_type = metadata['Content-Type']
208
- if chosen_charset = metadata['Charset']
212
+ chosen_type = metadata[CONTENT_TYPE]
213
+ if chosen_charset = metadata[CHARSET]
209
214
  chosen_type.params['charset'] = chosen_charset
210
215
  end
211
- response.headers['Content-Type'] = chosen_type.to_s
216
+ response.headers[CONTENT_TYPE] = chosen_type.to_s
212
217
  if !request.accept_encoding
213
218
  choose_encoding(resource.encodings_provided, "identity;q=1.0,*;q=0.5") ? :g7 : 406
214
219
  else
@@ -240,13 +245,13 @@ module Webmachine
240
245
 
241
246
  # ETag in If-Match
242
247
  def g11
243
- request_etags = request.if_match.split(/\s*,\s*/).map {|etag| ETag.new(etag) }
248
+ request_etags = request.if_match.split(SPLIT_SEMI).map {|etag| ETag.new(etag) }
244
249
  request_etags.include?(ETag.new(resource.generate_etag)) ? :h10 : 412
245
250
  end
246
251
 
247
252
  # If-Match exists?
248
253
  def h7
249
- (request.if_match && unquote(request.if_match) == '*') ? 412 : :i7
254
+ (request.if_match && unquote(request.if_match) == STAR) ? 412 : :i7
250
255
  end
251
256
 
252
257
  # If-Unmodified-Since exists?
@@ -273,7 +278,7 @@ module Webmachine
273
278
  def i4
274
279
  case uri = resource.moved_permanently?
275
280
  when String, URI
276
- response.headers["Location"] = uri.to_s
281
+ response.headers[LOCATION] = uri.to_s
277
282
  301
278
283
  when Fixnum
279
284
  uri
@@ -306,7 +311,7 @@ module Webmachine
306
311
  def k5
307
312
  case uri = resource.moved_permanently?
308
313
  when String, URI
309
- response.headers["Location"] = uri.to_s
314
+ response.headers[LOCATION] = uri.to_s
310
315
  301
311
316
  when Fixnum
312
317
  uri
@@ -322,15 +327,20 @@ module Webmachine
322
327
 
323
328
  # Etag in if-none-match?
324
329
  def k13
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
330
+ request_etags = request.if_none_match.split(SPLIT_SEMI).map {|etag| ETag.new(etag) }
331
+ resource_etag = resource.generate_etag
332
+ if resource_etag && request_etags.include?(ETag.new(resource_etag))
333
+ :j18
334
+ else
335
+ :l13
336
+ end
327
337
  end
328
338
 
329
339
  # Moved temporarily?
330
340
  def l5
331
341
  case uri = resource.moved_temporarily?
332
342
  when String, URI
333
- response.headers["Location"] = uri.to_s
343
+ response.headers[LOCATION] = uri.to_s
334
344
  307
335
345
  when Fixnum
336
346
  uri
@@ -410,7 +420,7 @@ module Webmachine
410
420
  base_uri = resource.base_uri || request.base_uri
411
421
  new_uri = URI.join(base_uri.to_s, uri)
412
422
  request.disp_path = new_uri.path
413
- response.headers['Location'] = new_uri.to_s
423
+ response.headers[LOCATION] = new_uri.to_s
414
424
  result = accept_helper
415
425
  return result if Fixnum === result
416
426
  end
@@ -425,7 +435,7 @@ module Webmachine
425
435
  end
426
436
  end
427
437
  if response.is_redirect?
428
- if response.headers['Location']
438
+ if response.headers[LOCATION]
429
439
  303
430
440
  else
431
441
  raise InvalidResource, t('do_redirect')
@@ -460,7 +470,7 @@ module Webmachine
460
470
  def o18
461
471
  if request.get? || request.head?
462
472
  add_caching_headers
463
- content_type = metadata['Content-Type']
473
+ content_type = metadata[CONTENT_TYPE]
464
474
  handler = resource.content_types_provided.find {|ct, _| content_type.type_matches?(MediaType.parse(ct)) }.last
465
475
  result = resource.send(handler)
466
476
  if Fixnum === result
@@ -497,7 +507,7 @@ module Webmachine
497
507
 
498
508
  # New resource?
499
509
  def p11
500
- !response.headers["Location"] ? :o20 : 201
510
+ !response.headers[LOCATION] ? :o20 : 201
501
511
  end
502
512
 
503
513
  end # module Flow
@@ -1,5 +1,7 @@
1
- require 'webmachine/decision/helpers'
1
+ require 'webmachine/decision/helpers'
2
+ require 'webmachine/trace'
2
3
  require 'webmachine/translation'
4
+ require 'webmachine/constants'
3
5
 
4
6
  module Webmachine
5
7
  module Decision
@@ -8,6 +10,7 @@ module Webmachine
8
10
  class FSM
9
11
  include Flow
10
12
  include Helpers
13
+ include Trace::FSM
11
14
  include Translation
12
15
 
13
16
  attr_reader :resource, :request, :response, :metadata
@@ -15,7 +18,7 @@ module Webmachine
15
18
  def initialize(resource, request, response)
16
19
  @resource, @request, @response = resource, request, response
17
20
  @metadata = {}
18
- initialize_tracing
21
+ super
19
22
  end
20
23
 
21
24
  # Processes the request, iteratively invoking the decision methods in {Flow}.
@@ -35,7 +38,7 @@ module Webmachine
35
38
  raise InvalidResource, t('fsm_broke', :state => state, :result => result.inspect)
36
39
  end
37
40
  end
38
- rescue Exception => e
41
+ rescue => e
39
42
  Webmachine.render_error(500, request, response, :message => e.message)
40
43
  ensure
41
44
  trace_response(response)
@@ -48,7 +51,7 @@ module Webmachine
48
51
  rescue MalformedRequest => e
49
52
  Webmachine.render_error(400, request, response, :message => e.message)
50
53
  400
51
- rescue Exception => e
54
+ rescue => e
52
55
  resource.handle_exception(e)
53
56
  500
54
57
  end
@@ -60,7 +63,7 @@ module Webmachine
60
63
  when 404
61
64
  Webmachine.render_error(code, request, response)
62
65
  when 304
63
- response.headers.delete('Content-Type')
66
+ response.headers.delete(CONTENT_TYPE)
64
67
  add_caching_headers
65
68
  end
66
69
 
@@ -69,19 +72,8 @@ module Webmachine
69
72
  response.code
70
73
  end
71
74
 
72
- ensure_content_length
73
- ensure_date_header
74
- end
75
-
76
- # When tracing is disabled, this does nothing.
77
- def trace_decision(state); end
78
- # When tracing is disabled, this does nothing.
79
- def trace_request(request); end
80
- # When tracing is disabled, this does nothing.
81
- def trace_response(response); end
82
-
83
- def initialize_tracing
84
- extend Trace::FSM if Trace.trace?(resource)
75
+ ensure_content_length(response)
76
+ ensure_date_header(response)
85
77
  end
86
78
  end # class FSM
87
79
  end # module Decision