deas 0.43.3 → 0.43.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/deas.gemspec +2 -2
- data/lib/deas/error_handler.rb +6 -6
- data/lib/deas/handler_proxy.rb +4 -4
- data/lib/deas/logging.rb +4 -4
- data/lib/deas/request_data.rb +4 -4
- data/lib/deas/router.rb +48 -2
- data/lib/deas/runner.rb +18 -8
- data/lib/deas/server.rb +21 -4
- data/lib/deas/sinatra_app.rb +7 -14
- data/lib/deas/test_runner.rb +2 -2
- data/lib/deas/trailing_slashes.rb +85 -0
- data/lib/deas/url.rb +1 -1
- data/lib/deas/version.rb +1 -1
- data/lib/deas/view_handler.rb +1 -0
- data/test/support/factory.rb +2 -2
- data/test/support/fake_sinatra_call.rb +1 -3
- data/test/support/routes.rb +34 -0
- data/test/system/deas_tests.rb +42 -1
- data/test/unit/error_handler_tests.rb +7 -7
- data/test/unit/handler_proxy_tests.rb +7 -7
- data/test/unit/logging_tests.rb +7 -9
- data/test/unit/request_data_tests.rb +8 -8
- data/test/unit/router_tests.rb +104 -2
- data/test/unit/runner_tests.rb +52 -18
- data/test/unit/server_tests.rb +3 -1
- data/test/unit/sinatra_app_tests.rb +0 -10
- data/test/unit/test_runner_tests.rb +2 -2
- data/test/unit/trailing_slashes_tests.rb +151 -0
- data/test/unit/url_tests.rb +6 -3
- data/test/unit/view_handler_tests.rb +9 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA512:
|
3
|
-
|
4
|
-
|
3
|
+
metadata.gz: 0408c659dda15d5dabe1982e6a062e9d9021d38cdb5068aeb96cd46298341a740b4c73875c59f7d39a538b93152f92b57fbf87dd2d2476d5091905286301976a
|
4
|
+
data.tar.gz: e6af545cc1ed6365fd6825e6ceb5d2490311ca67a86bdb261e42590d72593e20891fde53ebe7b718ccc4bf1ba5b7997aa60a61dbe92f1c4d810838d7390587f9
|
5
5
|
SHA1:
|
6
|
-
|
7
|
-
|
6
|
+
metadata.gz: cccc4cbf0e9a8ee8e5cdfbd597bbb3d348d2bbac
|
7
|
+
data.tar.gz: d29bf90d2085ccaca87d0059e78b2a8a658ad287
|
data/Gemfile
CHANGED
data/deas.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_development_dependency("assert", ["~> 2.16.
|
22
|
-
gem.add_development_dependency("assert-rack-test", ["~> 1.0.
|
21
|
+
gem.add_development_dependency("assert", ["~> 2.16.3"])
|
22
|
+
gem.add_development_dependency("assert-rack-test", ["~> 1.0.5"])
|
23
23
|
|
24
24
|
gem.add_dependency("much-plugin", ["~> 0.2.0"])
|
25
25
|
gem.add_dependency("rack", ["~> 1.1"])
|
data/lib/deas/error_handler.rb
CHANGED
@@ -26,7 +26,7 @@ module Deas
|
|
26
26
|
error_proc.call(@exception, @context)
|
27
27
|
rescue StandardError => proc_exception
|
28
28
|
@exception = proc_exception
|
29
|
-
response
|
29
|
+
response = nil # reset response
|
30
30
|
end
|
31
31
|
response || result
|
32
32
|
end
|
@@ -35,18 +35,18 @@ module Deas
|
|
35
35
|
class Context
|
36
36
|
|
37
37
|
attr_reader :server_data
|
38
|
-
attr_reader :request, :response
|
39
|
-
attr_reader :
|
38
|
+
attr_reader :request, :response
|
39
|
+
attr_reader :route_path, :handler_class, :handler, :params, :splat
|
40
40
|
|
41
41
|
def initialize(args)
|
42
42
|
@server_data = args.fetch(:server_data)
|
43
43
|
@request = args.fetch(:request)
|
44
44
|
@response = args.fetch(:response)
|
45
|
+
@route_path = args.fetch(:route_path)
|
45
46
|
@handler_class = args.fetch(:handler_class)
|
46
47
|
@handler = args.fetch(:handler)
|
47
48
|
@params = args.fetch(:params)
|
48
49
|
@splat = args.fetch(:splat)
|
49
|
-
@route_path = args.fetch(:route_path)
|
50
50
|
end
|
51
51
|
|
52
52
|
def ==(other)
|
@@ -55,10 +55,10 @@ module Deas
|
|
55
55
|
self.handler_class == other.handler_class &&
|
56
56
|
self.request == other.request &&
|
57
57
|
self.response == other.response &&
|
58
|
+
self.route_path == other.route_path &&
|
58
59
|
self.handler == other.handler &&
|
59
60
|
self.params == other.params &&
|
60
|
-
self.splat == other.splat
|
61
|
-
self.route_path == other.route_path
|
61
|
+
self.splat == other.splat
|
62
62
|
else
|
63
63
|
super
|
64
64
|
end
|
data/lib/deas/handler_proxy.rb
CHANGED
@@ -33,8 +33,8 @@ module Deas
|
|
33
33
|
:router => server_data.router,
|
34
34
|
:template_source => server_data.template_source,
|
35
35
|
:request => request_data.request,
|
36
|
-
:
|
37
|
-
:
|
36
|
+
:route_path => request_data.route_path,
|
37
|
+
:params => request_data.params
|
38
38
|
})
|
39
39
|
|
40
40
|
runner.request.env.tap do |env|
|
@@ -42,17 +42,17 @@ module Deas
|
|
42
42
|
# this is specifically needed by the Logging middleware
|
43
43
|
# this is also needed by the Sinatra error handlers so they can provide
|
44
44
|
# error context. This may change when we eventually remove Sinatra.
|
45
|
+
env['deas.route_path'] = runner.route_path
|
45
46
|
env['deas.handler_class'] = self.handler_class
|
46
47
|
env['deas.handler'] = runner.handler
|
47
48
|
env['deas.params'] = runner.params
|
48
49
|
env['deas.splat'] = runner.splat
|
49
|
-
env['deas.route_path'] = runner.route_path
|
50
50
|
|
51
51
|
# this handles the verbose logging (it is a no-op if summary logging)
|
52
|
+
env['deas.logging'].call " Route: #{runner.route_path.inspect}"
|
52
53
|
env['deas.logging'].call " Handler: #{self.handler_class.name}"
|
53
54
|
env['deas.logging'].call " Params: #{runner.params.inspect}"
|
54
55
|
env['deas.logging'].call " Splat: #{runner.splat.inspect}" if !runner.splat.nil?
|
55
|
-
env['deas.logging'].call " Route: #{runner.route_path.inspect}"
|
56
56
|
end
|
57
57
|
|
58
58
|
runner.run
|
data/lib/deas/logging.rb
CHANGED
@@ -4,16 +4,16 @@ require 'sinatra/base'
|
|
4
4
|
module Deas
|
5
5
|
|
6
6
|
module Logging
|
7
|
-
def self.
|
8
|
-
verbose ?
|
7
|
+
def self.middleware_type(verbose)
|
8
|
+
verbose ? VerboseLogging : SummaryLogging
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
class BaseLogging
|
13
13
|
|
14
|
-
def initialize(app)
|
14
|
+
def initialize(app, logger)
|
15
15
|
@app = app
|
16
|
-
@logger =
|
16
|
+
@logger = logger
|
17
17
|
end
|
18
18
|
|
19
19
|
# The Rack call interface. The receiver acts as a prototype and runs
|
data/lib/deas/request_data.rb
CHANGED
@@ -8,21 +8,21 @@ module Deas
|
|
8
8
|
# decouple the rack app from the handlers (we can use any rack app as long
|
9
9
|
# as they provide this data).
|
10
10
|
|
11
|
-
attr_reader :request, :response, :
|
11
|
+
attr_reader :request, :response, :route_path, :params
|
12
12
|
|
13
13
|
def initialize(args)
|
14
14
|
@request = args[:request]
|
15
15
|
@response = args[:response]
|
16
|
-
@params = args[:params]
|
17
16
|
@route_path = args[:route_path]
|
17
|
+
@params = args[:params]
|
18
18
|
end
|
19
19
|
|
20
20
|
def ==(other_request_data)
|
21
21
|
if other_request_data.kind_of?(RequestData)
|
22
22
|
self.request == other_request_data.request &&
|
23
23
|
self.response == other_request_data.response &&
|
24
|
-
self.
|
25
|
-
self.
|
24
|
+
self.route_path == other_request_data.route_path &&
|
25
|
+
self.params == other_request_data.params
|
26
26
|
else
|
27
27
|
super
|
28
28
|
end
|
data/lib/deas/router.rb
CHANGED
@@ -7,9 +7,17 @@ module Deas
|
|
7
7
|
class Router
|
8
8
|
|
9
9
|
DEFAULT_REQUEST_TYPE_NAME = 'default'.freeze
|
10
|
+
ALLOW_TRAILING_SLASHES = 'allow'.freeze
|
11
|
+
REMOVE_TRAILING_SLASHES = 'remove'.freeze
|
12
|
+
SLASH = '/'.freeze
|
13
|
+
|
14
|
+
VALID_TRAILING_SLASHES_VALUES = [
|
15
|
+
ALLOW_TRAILING_SLASHES,
|
16
|
+
REMOVE_TRAILING_SLASHES
|
17
|
+
].freeze
|
10
18
|
|
11
19
|
attr_reader :request_types, :urls, :routes, :definitions
|
12
|
-
attr_reader :escape_query_value_proc
|
20
|
+
attr_reader :trailing_slashes, :escape_query_value_proc
|
13
21
|
|
14
22
|
def initialize(&block)
|
15
23
|
@request_types = []
|
@@ -24,6 +32,26 @@ module Deas
|
|
24
32
|
@view_handler_ns
|
25
33
|
end
|
26
34
|
|
35
|
+
def allow_trailing_slashes
|
36
|
+
@trailing_slashes = ALLOW_TRAILING_SLASHES
|
37
|
+
end
|
38
|
+
|
39
|
+
def allow_trailing_slashes_set?
|
40
|
+
@trailing_slashes == ALLOW_TRAILING_SLASHES
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_trailing_slashes
|
44
|
+
@trailing_slashes = REMOVE_TRAILING_SLASHES
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_trailing_slashes_set?
|
48
|
+
@trailing_slashes == REMOVE_TRAILING_SLASHES
|
49
|
+
end
|
50
|
+
|
51
|
+
def trailing_slashes_set?
|
52
|
+
VALID_TRAILING_SLASHES_VALUES.include?(@trailing_slashes)
|
53
|
+
end
|
54
|
+
|
27
55
|
def escape_query_value(&block)
|
28
56
|
raise(ArgumentError, "no block given") unless block
|
29
57
|
@escape_query_value_proc = block
|
@@ -109,9 +137,26 @@ module Deas
|
|
109
137
|
true
|
110
138
|
end
|
111
139
|
|
140
|
+
def validate_trailing_slashes!
|
141
|
+
if self.trailing_slashes == REMOVE_TRAILING_SLASHES
|
142
|
+
paths = []
|
143
|
+
all_missing = self.routes.inject(true) do |result, route|
|
144
|
+
paths << route.path if route.path[-1..-1] == SLASH
|
145
|
+
result && route.path[-1..-1] != SLASH
|
146
|
+
end
|
147
|
+
if !all_missing
|
148
|
+
msg = "all route paths must *not* end with a \"/\", but these do:\n"\
|
149
|
+
"#{paths.join("\n")}"
|
150
|
+
raise TrailingSlashesError, msg
|
151
|
+
end
|
152
|
+
end
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
112
156
|
def validate!
|
113
157
|
self.apply_definitions!
|
114
158
|
self.routes.each(&:validate!)
|
159
|
+
self.validate_trailing_slashes!
|
115
160
|
true
|
116
161
|
end
|
117
162
|
|
@@ -192,7 +237,8 @@ module Deas
|
|
192
237
|
Deas::Route.new(http_method, path, proxies).tap{ |r| self.routes.push(r) }
|
193
238
|
end
|
194
239
|
|
195
|
-
InvalidSplatError
|
240
|
+
InvalidSplatError = Class.new(ArgumentError)
|
241
|
+
TrailingSlashesError = Class.new(RuntimeError)
|
196
242
|
|
197
243
|
class HandlerProxies
|
198
244
|
|
data/lib/deas/runner.rb
CHANGED
@@ -14,22 +14,22 @@ module Deas
|
|
14
14
|
DEFAULT_BODY = [].freeze
|
15
15
|
|
16
16
|
attr_reader :handler_class, :handler
|
17
|
+
attr_reader :request, :route_path, :params
|
17
18
|
attr_reader :logger, :router, :template_source
|
18
|
-
attr_reader :request, :params, :route_path
|
19
19
|
|
20
20
|
def initialize(handler_class, args = nil)
|
21
21
|
@status, @headers, @body = nil, Rack::Utils::HeaderHash.new, nil
|
22
22
|
|
23
|
+
@handler_class = handler_class
|
24
|
+
@handler = @handler_class.new(self)
|
25
|
+
|
23
26
|
args ||= {}
|
27
|
+
@request = args[:request]
|
28
|
+
@route_path = args[:route_path].to_s
|
29
|
+
@params = args[:params] || {}
|
24
30
|
@logger = args[:logger] || Deas::NullLogger.new
|
25
31
|
@router = args[:router] || Deas::Router.new
|
26
32
|
@template_source = args[:template_source] || Deas::NullTemplateSource.new
|
27
|
-
@request = args[:request]
|
28
|
-
@params = args[:params] || {}
|
29
|
-
@route_path = args[:route_path].to_s
|
30
|
-
|
31
|
-
@handler_class = handler_class
|
32
|
-
@handler = @handler_class.new(self)
|
33
33
|
end
|
34
34
|
|
35
35
|
def splat
|
@@ -56,8 +56,10 @@ module Deas
|
|
56
56
|
|
57
57
|
def body(value = nil)
|
58
58
|
if !value.nil?
|
59
|
+
# http://www.rubydoc.info/github/rack/rack/master/file/SPEC#The_Body
|
60
|
+
# "The Body must respond to each and must only yield String values"
|
59
61
|
# String#each is a thing in 1.8.7, so account for it here
|
60
|
-
@body = !value.respond_to?(:each) || value.kind_of?(String) ? [*value] : value
|
62
|
+
@body = !value.respond_to?(:each) || value.kind_of?(String) ? [*value.to_s] : value
|
61
63
|
end
|
62
64
|
@body
|
63
65
|
end
|
@@ -66,6 +68,14 @@ module Deas
|
|
66
68
|
self.headers['Content-Type'] = get_content_type(extname, params)
|
67
69
|
end
|
68
70
|
|
71
|
+
def set_cookie(name, value, opts = nil)
|
72
|
+
Rack::Utils.set_cookie_header!(
|
73
|
+
self.headers,
|
74
|
+
name,
|
75
|
+
(opts || {}).merge(:value => value)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
69
79
|
def halt(*args)
|
70
80
|
self.status(args.shift) if args.first.instance_of?(::Fixnum)
|
71
81
|
self.headers(args.shift) if args.first.kind_of?(::Hash)
|
data/lib/deas/server.rb
CHANGED
@@ -6,6 +6,7 @@ require 'deas/router'
|
|
6
6
|
require 'deas/show_exceptions'
|
7
7
|
require 'deas/sinatra_app'
|
8
8
|
require 'deas/template_source'
|
9
|
+
require 'deas/trailing_slashes'
|
9
10
|
|
10
11
|
module Deas
|
11
12
|
|
@@ -194,11 +195,27 @@ module Deas
|
|
194
195
|
# it is run before any other middleware
|
195
196
|
self.middlewares.unshift([Rack::MethodOverride]) if self.method_override
|
196
197
|
|
197
|
-
# append the show exceptions and logging middlewares last.
|
198
|
-
#
|
199
|
-
#
|
198
|
+
# append the show exceptions and logging middlewares next-to-last. This
|
199
|
+
# ensures the logging and exception showing happens just before the
|
200
|
+
# optional trailing slashes handling. It should be just before the app
|
201
|
+
# gets the request and just after the app sends a response (except for
|
202
|
+
# trailing slashes - this should happen inside of the show exceptions
|
203
|
+
# and logging behavior).
|
200
204
|
self.middlewares << [Deas::ShowExceptions] if self.show_exceptions
|
201
|
-
self.middlewares <<
|
205
|
+
self.middlewares << [
|
206
|
+
Deas::Logging.middleware_type(self.verbose_logging),
|
207
|
+
self.logger
|
208
|
+
]
|
209
|
+
|
210
|
+
# optionally add the trailing slashes middleware last b/c it should
|
211
|
+
# happen inside of show exceptions and logging. we want the behavior
|
212
|
+
# to feel like app behavior to the rest of the middleware stack so it
|
213
|
+
# needs to be just before the app gest the request and just after the
|
214
|
+
# app sends a response.
|
215
|
+
if self.router.trailing_slashes_set?
|
216
|
+
self.middlewares << [Deas::TrailingSlashes, self.router]
|
217
|
+
end
|
218
|
+
|
202
219
|
self.middlewares.freeze
|
203
220
|
|
204
221
|
@valid = true # if it made it this far, its valid!
|
data/lib/deas/sinatra_app.rb
CHANGED
@@ -43,13 +43,6 @@ module Deas
|
|
43
43
|
set :environment, server_config.env
|
44
44
|
set :root, server_config.root
|
45
45
|
|
46
|
-
# TODO: sucks to have to do this but b/c of Rack there is no better way
|
47
|
-
# to make the server data available to middleware. We should remove this
|
48
|
-
# once we remove Sinatra. Whatever rack app implemenation will needs to
|
49
|
-
# provide the server data or maybe the server data *will be* the rack app.
|
50
|
-
# Not sure right now, just jotting down notes.
|
51
|
-
set :deas_server_data, server_data
|
52
|
-
|
53
46
|
# static settings - Deas doesn't care about these anymore so just
|
54
47
|
# use some intelligent defaults
|
55
48
|
set :views, server_config.root
|
@@ -84,8 +77,8 @@ module Deas
|
|
84
77
|
RequestData.new({
|
85
78
|
:request => request,
|
86
79
|
:response => response,
|
87
|
-
:
|
88
|
-
:
|
80
|
+
:route_path => route.path,
|
81
|
+
:params => params
|
89
82
|
})
|
90
83
|
)
|
91
84
|
rescue *STANDARD_ERROR_CLASSES => err
|
@@ -95,11 +88,11 @@ module Deas
|
|
95
88
|
:server_data => server_data,
|
96
89
|
:request => request,
|
97
90
|
:response => response,
|
91
|
+
:route_path => request.env['deas.route_path'],
|
98
92
|
:handler_class => request.env['deas.handler_class'],
|
99
93
|
:handler => request.env['deas.handler'],
|
100
94
|
:params => request.env['deas.params'],
|
101
|
-
:splat => request.env['deas.splat']
|
102
|
-
:route_path => request.env['deas.route_path']
|
95
|
+
:splat => request.env['deas.splat']
|
103
96
|
})
|
104
97
|
end
|
105
98
|
end
|
@@ -109,7 +102,7 @@ module Deas
|
|
109
102
|
# `self` is the sinatra call in this context
|
110
103
|
if env['sinatra.error']
|
111
104
|
env['deas.error'] = if env['sinatra.error'].instance_of?(::Sinatra::NotFound)
|
112
|
-
Deas::NotFound.new(env['PATH_INFO']).tap do |e|
|
105
|
+
Deas::NotFound.new("#{env['REQUEST_METHOD']} #{env['PATH_INFO']}").tap do |e|
|
113
106
|
e.set_backtrace(env['sinatra.error'].backtrace)
|
114
107
|
end
|
115
108
|
else
|
@@ -119,11 +112,11 @@ module Deas
|
|
119
112
|
:server_data => server_data,
|
120
113
|
:request => request,
|
121
114
|
:response => response,
|
115
|
+
:route_path => request.env['deas.route_path'],
|
122
116
|
:handler_class => request.env['deas.handler_class'],
|
123
117
|
:handler => request.env['deas.handler'],
|
124
118
|
:params => request.env['deas.params'],
|
125
|
-
:splat => request.env['deas.splat']
|
126
|
-
:route_path => request.env['deas.route_path']
|
119
|
+
:splat => request.env['deas.splat']
|
127
120
|
})
|
128
121
|
end
|
129
122
|
end
|
data/lib/deas/test_runner.rb
CHANGED
@@ -27,8 +27,8 @@ module Deas
|
|
27
27
|
:router => a.delete(:router),
|
28
28
|
:template_source => a.delete(:template_source),
|
29
29
|
:request => a.delete(:request),
|
30
|
-
:
|
31
|
-
:
|
30
|
+
:route_path => a.delete(:route_path),
|
31
|
+
:params => NormalizedParams.new(a.delete(:params) || {}).value
|
32
32
|
})
|
33
33
|
@splat = a.delete(:splat)
|
34
34
|
a.each{|key, value| self.handler.send("#{key}=", value) }
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
|
3
|
+
require 'deas/exceptions'
|
4
|
+
require 'deas/router'
|
5
|
+
|
6
|
+
module Deas
|
7
|
+
|
8
|
+
class TrailingSlashes
|
9
|
+
|
10
|
+
module RequireNoHandler; end
|
11
|
+
module AllowHandler; end
|
12
|
+
|
13
|
+
HANDLERS = {
|
14
|
+
Deas::Router::REMOVE_TRAILING_SLASHES => RequireNoHandler,
|
15
|
+
Deas::Router::ALLOW_TRAILING_SLASHES => AllowHandler
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(app, router)
|
19
|
+
@app = app
|
20
|
+
@router = router
|
21
|
+
|
22
|
+
if !@router.trailing_slashes_set?
|
23
|
+
val = @router.trailing_slashes
|
24
|
+
desc = val.nil? ? 'no' : "an invalid (`#{val.inspect}`)"
|
25
|
+
raise ArgumentError, "TrailingSlashes middleware is in use but there is "\
|
26
|
+
"#{desc} trailing slashes router directive set."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# The Rack call interface. The receiver acts as a prototype and runs
|
31
|
+
# each request in a clone object unless the +rack.run_once+ variable is
|
32
|
+
# set in the environment. Ripped from:
|
33
|
+
# http://github.com/rtomayko/rack-cache/blob/master/lib/rack/cache/context.rb
|
34
|
+
def call(env)
|
35
|
+
if env['rack.run_once']
|
36
|
+
call! env
|
37
|
+
else
|
38
|
+
clone.call! env
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# The real Rack call interface.
|
43
|
+
def call!(env)
|
44
|
+
HANDLERS[@router.trailing_slashes].run(env){ @app.call(env) }
|
45
|
+
end
|
46
|
+
|
47
|
+
module RequireNoHandler
|
48
|
+
|
49
|
+
def self.run(env)
|
50
|
+
if env['PATH_INFO'][-1..-1] == Deas::Router::SLASH
|
51
|
+
[302, { 'Location' => env['PATH_INFO'][0..-2] }, ['']]
|
52
|
+
else
|
53
|
+
yield
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
module AllowHandler
|
60
|
+
|
61
|
+
def self.run(env)
|
62
|
+
status, headers, body = yield
|
63
|
+
if env['deas.error'].kind_of?(Deas::NotFound)
|
64
|
+
# reset 'deas.error' state
|
65
|
+
env['deas.error'] = nil
|
66
|
+
|
67
|
+
# switching the trailing slash of the path info
|
68
|
+
env['PATH_INFO'] = if env['PATH_INFO'][-1..-1] == Deas::Router::SLASH
|
69
|
+
env['PATH_INFO'][0..-2]
|
70
|
+
else
|
71
|
+
env['PATH_INFO']+Deas::Router::SLASH
|
72
|
+
end
|
73
|
+
|
74
|
+
# retry
|
75
|
+
yield
|
76
|
+
else
|
77
|
+
[status, headers, body]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|