actionpack 4.0.1 → 4.2.11.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +402 -1173
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/abstract_controller/base.rb +39 -7
- data/lib/abstract_controller/callbacks.rb +32 -53
- data/lib/abstract_controller/collector.rb +11 -1
- data/lib/abstract_controller/helpers.rb +26 -16
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
- data/lib/abstract_controller/rendering.rb +57 -127
- data/lib/abstract_controller/url_for.rb +1 -1
- data/lib/abstract_controller.rb +1 -2
- data/lib/action_controller/base.rb +19 -10
- data/lib/action_controller/caching/fragments.rb +7 -1
- data/lib/action_controller/caching.rb +2 -12
- data/lib/action_controller/log_subscriber.rb +29 -20
- data/lib/action_controller/metal/conditional_get.rb +37 -12
- data/lib/action_controller/metal/data_streaming.rb +1 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
- data/lib/action_controller/metal/exceptions.rb +1 -1
- data/lib/action_controller/metal/flash.rb +17 -0
- data/lib/action_controller/metal/force_ssl.rb +2 -2
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +45 -23
- data/lib/action_controller/metal/instrumentation.rb +9 -6
- data/lib/action_controller/metal/live.rb +173 -20
- data/lib/action_controller/metal/mime_responds.rb +127 -232
- data/lib/action_controller/metal/params_wrapper.rb +16 -9
- data/lib/action_controller/metal/rack_delegation.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +34 -26
- data/lib/action_controller/metal/renderers.rb +39 -12
- data/lib/action_controller/metal/rendering.rb +41 -14
- data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
- data/lib/action_controller/metal/streaming.rb +19 -21
- data/lib/action_controller/metal/strong_parameters.rb +166 -22
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -12
- data/lib/action_controller/metal.rb +14 -8
- data/lib/action_controller/model_naming.rb +1 -1
- data/lib/action_controller/railtie.rb +5 -1
- data/lib/action_controller/test_case.rb +160 -94
- data/lib/action_controller.rb +2 -18
- data/lib/action_dispatch/http/cache.rb +5 -4
- data/lib/action_dispatch/http/filter_parameters.rb +2 -2
- data/lib/action_dispatch/http/filter_redirect.rb +5 -4
- data/lib/action_dispatch/http/headers.rb +46 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
- data/lib/action_dispatch/http/mime_type.rb +25 -26
- data/lib/action_dispatch/http/mime_types.rb +1 -0
- data/lib/action_dispatch/http/parameter_filter.rb +1 -1
- data/lib/action_dispatch/http/parameters.rb +25 -41
- data/lib/action_dispatch/http/request.rb +49 -32
- data/lib/action_dispatch/http/response.rb +127 -25
- data/lib/action_dispatch/http/upload.rb +9 -21
- data/lib/action_dispatch/http/url.rb +97 -70
- data/lib/action_dispatch/journey/formatter.rb +35 -19
- data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
- data/lib/action_dispatch/journey/nodes/node.rb +4 -0
- data/lib/action_dispatch/journey/parser.rb +51 -59
- data/lib/action_dispatch/journey/parser.y +12 -10
- data/lib/action_dispatch/journey/path/pattern.rb +16 -19
- data/lib/action_dispatch/journey/route.rb +8 -19
- data/lib/action_dispatch/journey/router/strexp.rb +9 -6
- data/lib/action_dispatch/journey/router/utils.rb +54 -18
- data/lib/action_dispatch/journey/router.rb +53 -75
- data/lib/action_dispatch/journey/routes.rb +4 -0
- data/lib/action_dispatch/journey/scanner.rb +5 -5
- data/lib/action_dispatch/journey/visitors.rb +81 -60
- data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
- data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +7 -7
- data/lib/action_dispatch/middleware/cookies.rb +119 -43
- data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
- data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
- data/lib/action_dispatch/middleware/flash.rb +37 -24
- data/lib/action_dispatch/middleware/params_parser.rb +2 -2
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
- data/lib/action_dispatch/middleware/reloader.rb +11 -2
- data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
- data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
- data/lib/action_dispatch/middleware/ssl.rb +10 -7
- data/lib/action_dispatch/middleware/static.rb +79 -23
- data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
- data/lib/action_dispatch/railtie.rb +5 -2
- data/lib/action_dispatch/request/session.rb +12 -0
- data/lib/action_dispatch/request/utils.rb +35 -0
- data/lib/action_dispatch/routing/endpoint.rb +10 -0
- data/lib/action_dispatch/routing/inspector.rb +11 -17
- data/lib/action_dispatch/routing/mapper.rb +519 -312
- data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
- data/lib/action_dispatch/routing/redirection.rb +51 -26
- data/lib/action_dispatch/routing/route_set.rb +331 -206
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
- data/lib/action_dispatch/routing/url_for.rb +19 -5
- data/lib/action_dispatch/routing.rb +9 -6
- data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
- data/lib/action_dispatch/testing/assertions/response.rb +9 -15
- data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
- data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
- data/lib/action_dispatch/testing/assertions.rb +11 -7
- data/lib/action_dispatch/testing/integration.rb +31 -29
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +1 -5
- data/lib/action_dispatch.rb +5 -8
- data/lib/action_pack/gem_version.rb +15 -0
- data/lib/action_pack/version.rb +4 -7
- data/lib/action_pack.rb +1 -1
- metadata +77 -159
- data/lib/abstract_controller/layouts.rb +0 -423
- data/lib/abstract_controller/view_paths.rb +0 -96
- data/lib/action_controller/deprecated/integration_test.rb +0 -5
- data/lib/action_controller/deprecated.rb +0 -7
- data/lib/action_controller/metal/responder.rb +0 -287
- data/lib/action_controller/record_identifier.rb +0 -31
- data/lib/action_controller/vendor/html-scanner.rb +0 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
- data/lib/action_view/base.rb +0 -201
- data/lib/action_view/buffers.rb +0 -49
- data/lib/action_view/context.rb +0 -36
- data/lib/action_view/dependency_tracker.rb +0 -93
- data/lib/action_view/digestor.rb +0 -113
- data/lib/action_view/flows.rb +0 -76
- data/lib/action_view/helpers/active_model_helper.rb +0 -49
- data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
- data/lib/action_view/helpers/asset_url_helper.rb +0 -355
- data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
- data/lib/action_view/helpers/cache_helper.rb +0 -196
- data/lib/action_view/helpers/capture_helper.rb +0 -216
- data/lib/action_view/helpers/controller_helper.rb +0 -25
- data/lib/action_view/helpers/csrf_helper.rb +0 -30
- data/lib/action_view/helpers/date_helper.rb +0 -1083
- data/lib/action_view/helpers/debug_helper.rb +0 -39
- data/lib/action_view/helpers/form_helper.rb +0 -1880
- data/lib/action_view/helpers/form_options_helper.rb +0 -838
- data/lib/action_view/helpers/form_tag_helper.rb +0 -785
- data/lib/action_view/helpers/javascript_helper.rb +0 -117
- data/lib/action_view/helpers/number_helper.rb +0 -441
- data/lib/action_view/helpers/output_safety_helper.rb +0 -38
- data/lib/action_view/helpers/record_tag_helper.rb +0 -106
- data/lib/action_view/helpers/rendering_helper.rb +0 -90
- data/lib/action_view/helpers/sanitize_helper.rb +0 -256
- data/lib/action_view/helpers/tag_helper.rb +0 -173
- data/lib/action_view/helpers/tags/base.rb +0 -148
- data/lib/action_view/helpers/tags/check_box.rb +0 -64
- data/lib/action_view/helpers/tags/checkable.rb +0 -16
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
- data/lib/action_view/helpers/tags/collection_select.rb +0 -28
- data/lib/action_view/helpers/tags/color_field.rb +0 -25
- data/lib/action_view/helpers/tags/date_field.rb +0 -13
- data/lib/action_view/helpers/tags/date_select.rb +0 -72
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
- data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
- data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
- data/lib/action_view/helpers/tags/email_field.rb +0 -8
- data/lib/action_view/helpers/tags/file_field.rb +0 -8
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
- data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
- data/lib/action_view/helpers/tags/label.rb +0 -66
- data/lib/action_view/helpers/tags/month_field.rb +0 -13
- data/lib/action_view/helpers/tags/number_field.rb +0 -18
- data/lib/action_view/helpers/tags/password_field.rb +0 -12
- data/lib/action_view/helpers/tags/radio_button.rb +0 -31
- data/lib/action_view/helpers/tags/range_field.rb +0 -8
- data/lib/action_view/helpers/tags/search_field.rb +0 -24
- data/lib/action_view/helpers/tags/select.rb +0 -40
- data/lib/action_view/helpers/tags/tel_field.rb +0 -8
- data/lib/action_view/helpers/tags/text_area.rb +0 -18
- data/lib/action_view/helpers/tags/text_field.rb +0 -29
- data/lib/action_view/helpers/tags/time_field.rb +0 -13
- data/lib/action_view/helpers/tags/time_select.rb +0 -8
- data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
- data/lib/action_view/helpers/tags/url_field.rb +0 -8
- data/lib/action_view/helpers/tags/week_field.rb +0 -13
- data/lib/action_view/helpers/tags.rb +0 -39
- data/lib/action_view/helpers/text_helper.rb +0 -443
- data/lib/action_view/helpers/translation_helper.rb +0 -107
- data/lib/action_view/helpers/url_helper.rb +0 -635
- data/lib/action_view/helpers.rb +0 -58
- data/lib/action_view/locale/en.yml +0 -56
- data/lib/action_view/log_subscriber.rb +0 -30
- data/lib/action_view/lookup_context.rb +0 -241
- data/lib/action_view/model_naming.rb +0 -12
- data/lib/action_view/path_set.rb +0 -77
- data/lib/action_view/railtie.rb +0 -43
- data/lib/action_view/record_identifier.rb +0 -84
- data/lib/action_view/renderer/abstract_renderer.rb +0 -47
- data/lib/action_view/renderer/partial_renderer.rb +0 -492
- data/lib/action_view/renderer/renderer.rb +0 -50
- data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
- data/lib/action_view/renderer/template_renderer.rb +0 -96
- data/lib/action_view/routing_url_for.rb +0 -107
- data/lib/action_view/tasks/dependencies.rake +0 -17
- data/lib/action_view/template/error.rb +0 -138
- data/lib/action_view/template/handlers/builder.rb +0 -26
- data/lib/action_view/template/handlers/erb.rb +0 -146
- data/lib/action_view/template/handlers/raw.rb +0 -11
- data/lib/action_view/template/handlers.rb +0 -53
- data/lib/action_view/template/resolver.rb +0 -326
- data/lib/action_view/template/text.rb +0 -34
- data/lib/action_view/template/types.rb +0 -57
- data/lib/action_view/template.rb +0 -339
- data/lib/action_view/test_case.rb +0 -270
- data/lib/action_view/testing/resolvers.rb +0 -50
- data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
- data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
- data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
- data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
- data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
- data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
- data/lib/action_view/vendor/html-scanner.rb +0 -20
- data/lib/action_view.rb +0 -93
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
1
|
module ActionDispatch
|
4
2
|
module Journey # :nodoc:
|
5
3
|
class Router # :nodoc:
|
@@ -15,7 +13,7 @@ module ActionDispatch
|
|
15
13
|
# normalize_path("") # => "/"
|
16
14
|
# normalize_path("/%ab") # => "/%AB"
|
17
15
|
def self.normalize_path(path)
|
18
|
-
path = "/#{path}"
|
16
|
+
path = "/#{path}".force_encoding(Encoding::UTF_8)
|
19
17
|
path.squeeze!('/')
|
20
18
|
path.sub!(%r{/+\Z}, '')
|
21
19
|
path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
|
@@ -25,31 +23,69 @@ module ActionDispatch
|
|
25
23
|
|
26
24
|
# URI path and fragment escaping
|
27
25
|
# http://tools.ietf.org/html/rfc3986
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
class UriEncoder # :nodoc:
|
27
|
+
ENCODE = "%%%02X".freeze
|
28
|
+
US_ASCII = Encoding::US_ASCII
|
29
|
+
UTF_8 = Encoding::UTF_8
|
30
|
+
EMPTY = "".force_encoding(US_ASCII).freeze
|
31
|
+
DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(US_ASCII) }
|
32
|
+
|
33
|
+
ALPHA = "a-zA-Z".freeze
|
34
|
+
DIGIT = "0-9".freeze
|
35
|
+
UNRESERVED = "#{ALPHA}#{DIGIT}\\-\\._~".freeze
|
36
|
+
SUB_DELIMS = "!\\$&'\\(\\)\\*\\+,;=".freeze
|
37
|
+
|
38
|
+
ESCAPED = /%[a-zA-Z0-9]{2}/.freeze
|
39
|
+
|
40
|
+
FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/\?]/.freeze
|
41
|
+
SEGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@]/.freeze
|
42
|
+
PATH = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/]/.freeze
|
43
|
+
|
44
|
+
def escape_fragment(fragment)
|
45
|
+
escape(fragment, FRAGMENT)
|
46
|
+
end
|
47
|
+
|
48
|
+
def escape_path(path)
|
49
|
+
escape(path, PATH)
|
50
|
+
end
|
51
|
+
|
52
|
+
def escape_segment(segment)
|
53
|
+
escape(segment, SEGMENT)
|
54
|
+
end
|
55
|
+
|
56
|
+
def unescape_uri(uri)
|
57
|
+
encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding
|
58
|
+
uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def escape(component, pattern)
|
63
|
+
component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(US_ASCII)
|
64
|
+
end
|
65
|
+
|
66
|
+
def percent_encode(unsafe)
|
67
|
+
safe = EMPTY.dup
|
68
|
+
unsafe.each_byte { |b| safe << DEC2HEX[b] }
|
69
|
+
safe
|
70
|
+
end
|
39
71
|
end
|
40
72
|
|
41
|
-
|
73
|
+
ENCODER = UriEncoder.new
|
42
74
|
|
43
75
|
def self.escape_path(path)
|
44
|
-
|
76
|
+
ENCODER.escape_path(path.to_s)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.escape_segment(segment)
|
80
|
+
ENCODER.escape_segment(segment.to_s)
|
45
81
|
end
|
46
82
|
|
47
83
|
def self.escape_fragment(fragment)
|
48
|
-
|
84
|
+
ENCODER.escape_fragment(fragment.to_s)
|
49
85
|
end
|
50
86
|
|
51
87
|
def self.unescape_uri(uri)
|
52
|
-
|
88
|
+
ENCODER.unescape_uri(uri)
|
53
89
|
end
|
54
90
|
end
|
55
91
|
end
|
@@ -20,60 +20,32 @@ module ActionDispatch
|
|
20
20
|
# :nodoc:
|
21
21
|
VERSION = '2.0.0'
|
22
22
|
|
23
|
-
class NullReq # :nodoc:
|
24
|
-
attr_reader :env
|
25
|
-
def initialize(env)
|
26
|
-
@env = env
|
27
|
-
end
|
28
|
-
|
29
|
-
def request_method
|
30
|
-
env['REQUEST_METHOD']
|
31
|
-
end
|
32
|
-
|
33
|
-
def path_info
|
34
|
-
env['PATH_INFO']
|
35
|
-
end
|
36
|
-
|
37
|
-
def ip
|
38
|
-
env['REMOTE_ADDR']
|
39
|
-
end
|
40
|
-
|
41
|
-
def [](k)
|
42
|
-
env[k]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
attr_reader :request_class, :formatter
|
47
23
|
attr_accessor :routes
|
48
24
|
|
49
|
-
def initialize(routes
|
50
|
-
@
|
51
|
-
@params_key = options[:parameters_key]
|
52
|
-
@request_class = options[:request_class] || NullReq
|
53
|
-
@routes = routes
|
25
|
+
def initialize(routes)
|
26
|
+
@routes = routes
|
54
27
|
end
|
55
28
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
script_name
|
61
|
-
'PATH_INFO',
|
62
|
-
@params_key)
|
29
|
+
def serve(req)
|
30
|
+
find_routes(req).each do |match, parameters, route|
|
31
|
+
set_params = req.path_parameters
|
32
|
+
path_info = req.path_info
|
33
|
+
script_name = req.script_name
|
63
34
|
|
64
35
|
unless route.path.anchored
|
65
|
-
|
66
|
-
|
36
|
+
req.script_name = (script_name.to_s + match.to_s).chomp('/')
|
37
|
+
req.path_info = match.post_match
|
38
|
+
req.path_info = "/" + req.path_info unless req.path_info.start_with? "/"
|
67
39
|
end
|
68
40
|
|
69
|
-
|
41
|
+
req.path_parameters = set_params.merge parameters
|
70
42
|
|
71
|
-
status, headers, body = route.app.
|
43
|
+
status, headers, body = route.app.serve(req)
|
72
44
|
|
73
45
|
if 'pass' == headers['X-Cascade']
|
74
|
-
|
75
|
-
|
76
|
-
|
46
|
+
req.script_name = script_name
|
47
|
+
req.path_info = path_info
|
48
|
+
req.path_parameters = set_params
|
77
49
|
next
|
78
50
|
end
|
79
51
|
|
@@ -83,14 +55,14 @@ module ActionDispatch
|
|
83
55
|
return [404, {'X-Cascade' => 'pass'}, ['Not Found']]
|
84
56
|
end
|
85
57
|
|
86
|
-
def recognize(
|
87
|
-
find_routes(
|
58
|
+
def recognize(rails_req)
|
59
|
+
find_routes(rails_req).each do |match, parameters, route|
|
88
60
|
unless route.path.anchored
|
89
|
-
|
90
|
-
|
61
|
+
rails_req.script_name = match.to_s
|
62
|
+
rails_req.path_info = match.post_match.sub(/^([^\/])/, '/\1')
|
91
63
|
end
|
92
64
|
|
93
|
-
yield(route,
|
65
|
+
yield(route, parameters)
|
94
66
|
end
|
95
67
|
end
|
96
68
|
|
@@ -121,45 +93,51 @@ module ActionDispatch
|
|
121
93
|
|
122
94
|
def filter_routes(path)
|
123
95
|
return [] unless ast
|
124
|
-
|
125
|
-
data ? data.memos : []
|
96
|
+
simulator.memos(path) { [] }
|
126
97
|
end
|
127
98
|
|
128
|
-
def find_routes
|
129
|
-
req = request_class.new(env)
|
130
|
-
|
99
|
+
def find_routes req
|
131
100
|
routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|
|
132
101
|
r.path.match(req.path_info)
|
133
102
|
}
|
134
|
-
routes.concat get_routes_as_head(routes)
|
135
103
|
|
136
|
-
routes
|
104
|
+
routes =
|
105
|
+
if req.request_method == "HEAD"
|
106
|
+
match_head_routes(routes, req)
|
107
|
+
else
|
108
|
+
match_routes(routes, req)
|
109
|
+
end
|
110
|
+
|
111
|
+
routes.sort_by!(&:precedence)
|
137
112
|
|
138
113
|
routes.map! { |r|
|
139
114
|
match_data = r.path.match(req.path_info)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
[match_data,
|
115
|
+
path_parameters = r.defaults.dup
|
116
|
+
match_data.names.zip(match_data.captures) { |name,val|
|
117
|
+
path_parameters[name.to_sym] = Utils.unescape_uri(val) if val
|
118
|
+
}
|
119
|
+
[match_data, path_parameters, r]
|
145
120
|
}
|
146
121
|
end
|
147
122
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
123
|
+
def match_head_routes(routes, req)
|
124
|
+
verb_specific_routes = routes.reject { |route| route.verb == // }
|
125
|
+
head_routes = match_routes(verb_specific_routes, req)
|
126
|
+
|
127
|
+
if head_routes.empty?
|
128
|
+
begin
|
129
|
+
req.request_method = "GET"
|
130
|
+
match_routes(routes, req)
|
131
|
+
ensure
|
132
|
+
req.request_method = "HEAD"
|
133
|
+
end
|
134
|
+
else
|
135
|
+
head_routes
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def match_routes(routes, req)
|
140
|
+
routes.select { |r| r.matches?(req) }
|
163
141
|
end
|
164
142
|
end
|
165
143
|
end
|
@@ -39,18 +39,18 @@ module ActionDispatch
|
|
39
39
|
[:SLASH, text]
|
40
40
|
when text = @ss.scan(/\*\w+/)
|
41
41
|
[:STAR, text]
|
42
|
-
when text = @ss.scan(
|
42
|
+
when text = @ss.scan(/(?<!\\)\(/)
|
43
43
|
[:LPAREN, text]
|
44
|
-
when text = @ss.scan(
|
44
|
+
when text = @ss.scan(/(?<!\\)\)/)
|
45
45
|
[:RPAREN, text]
|
46
46
|
when text = @ss.scan(/\|/)
|
47
47
|
[:OR, text]
|
48
48
|
when text = @ss.scan(/\./)
|
49
49
|
[:DOT, text]
|
50
|
-
when text = @ss.scan(
|
50
|
+
when text = @ss.scan(/(?<!\\):\w+/)
|
51
51
|
[:SYMBOL, text]
|
52
|
-
when text = @ss.scan(/[\w
|
53
|
-
[:LITERAL, text]
|
52
|
+
when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\:|\\\(|\\\))+/)
|
53
|
+
[:LITERAL, text.tr('\\', '')]
|
54
54
|
# any char
|
55
55
|
when text = @ss.scan(/./)
|
56
56
|
[:LITERAL, text]
|
@@ -1,14 +1,57 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'thread_safe'
|
4
|
-
|
5
3
|
module ActionDispatch
|
6
4
|
module Journey # :nodoc:
|
5
|
+
class Format
|
6
|
+
ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) }
|
7
|
+
ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) }
|
8
|
+
|
9
|
+
class Parameter < Struct.new(:name, :escaper)
|
10
|
+
def escape(value); escaper.call value; end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.required_path(symbol)
|
14
|
+
Parameter.new symbol, ESCAPE_PATH
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.required_segment(symbol)
|
18
|
+
Parameter.new symbol, ESCAPE_SEGMENT
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(parts)
|
22
|
+
@parts = parts
|
23
|
+
@children = []
|
24
|
+
@parameters = []
|
25
|
+
|
26
|
+
parts.each_with_index do |object,i|
|
27
|
+
case object
|
28
|
+
when Journey::Format
|
29
|
+
@children << i
|
30
|
+
when Parameter
|
31
|
+
@parameters << i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def evaluate(hash)
|
37
|
+
parts = @parts.dup
|
38
|
+
|
39
|
+
@parameters.each do |index|
|
40
|
+
param = parts[index]
|
41
|
+
value = hash[param.name]
|
42
|
+
return ''.freeze unless value
|
43
|
+
parts[index] = param.escape value
|
44
|
+
end
|
45
|
+
|
46
|
+
@children.each { |index| parts[index] = parts[index].evaluate(hash) }
|
47
|
+
|
48
|
+
parts.join
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
7
52
|
module Visitors # :nodoc:
|
8
53
|
class Visitor # :nodoc:
|
9
|
-
DISPATCH_CACHE =
|
10
|
-
h[k] = :"visit_#{k}"
|
11
|
-
}
|
54
|
+
DISPATCH_CACHE = {}
|
12
55
|
|
13
56
|
def accept(node)
|
14
57
|
visit(node)
|
@@ -38,9 +81,39 @@ module ActionDispatch
|
|
38
81
|
def visit_STAR(n); unary(n); end
|
39
82
|
|
40
83
|
def terminal(node); end
|
41
|
-
|
42
|
-
|
84
|
+
def visit_LITERAL(n); terminal(n); end
|
85
|
+
def visit_SYMBOL(n); terminal(n); end
|
86
|
+
def visit_SLASH(n); terminal(n); end
|
87
|
+
def visit_DOT(n); terminal(n); end
|
88
|
+
|
89
|
+
private_instance_methods(false).each do |pim|
|
90
|
+
next unless pim =~ /^visit_(.*)$/
|
91
|
+
DISPATCH_CACHE[$1.to_sym] = pim
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class FormatBuilder < Visitor # :nodoc:
|
96
|
+
def accept(node); Journey::Format.new(super); end
|
97
|
+
def terminal(node); [node.left]; end
|
98
|
+
|
99
|
+
def binary(node)
|
100
|
+
visit(node.left) + visit(node.right)
|
101
|
+
end
|
102
|
+
|
103
|
+
def visit_GROUP(n); [Journey::Format.new(unary(n))]; end
|
104
|
+
|
105
|
+
def visit_STAR(n)
|
106
|
+
[Journey::Format.required_path(n.left.to_sym)]
|
107
|
+
end
|
108
|
+
|
109
|
+
def visit_SYMBOL(n)
|
110
|
+
symbol = n.to_sym
|
111
|
+
if symbol == :controller
|
112
|
+
[Journey::Format.required_path(symbol)]
|
113
|
+
else
|
114
|
+
[Journey::Format.required_segment(symbol)]
|
43
115
|
end
|
116
|
+
end
|
44
117
|
end
|
45
118
|
|
46
119
|
# Loop through the requirements AST
|
@@ -52,8 +125,8 @@ module ActionDispatch
|
|
52
125
|
end
|
53
126
|
|
54
127
|
def visit(node)
|
55
|
-
super
|
56
128
|
block.call(node)
|
129
|
+
super
|
57
130
|
end
|
58
131
|
end
|
59
132
|
|
@@ -77,58 +150,6 @@ module ActionDispatch
|
|
77
150
|
end
|
78
151
|
end
|
79
152
|
|
80
|
-
class OptimizedPath < String # :nodoc:
|
81
|
-
private
|
82
|
-
|
83
|
-
def visit_GROUP(node)
|
84
|
-
""
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Used for formatting urls (url_for)
|
89
|
-
class Formatter < Visitor # :nodoc:
|
90
|
-
attr_reader :options, :consumed
|
91
|
-
|
92
|
-
def initialize(options)
|
93
|
-
@options = options
|
94
|
-
@consumed = {}
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def visit_GROUP(node)
|
100
|
-
if consumed == options
|
101
|
-
nil
|
102
|
-
else
|
103
|
-
route = visit(node.left)
|
104
|
-
route.include?("\0") ? nil : route
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def terminal(node)
|
109
|
-
node.left
|
110
|
-
end
|
111
|
-
|
112
|
-
def binary(node)
|
113
|
-
[visit(node.left), visit(node.right)].join
|
114
|
-
end
|
115
|
-
|
116
|
-
def nary(node)
|
117
|
-
node.children.map { |c| visit(c) }.join
|
118
|
-
end
|
119
|
-
|
120
|
-
def visit_SYMBOL(node)
|
121
|
-
key = node.to_sym
|
122
|
-
|
123
|
-
if value = options[key]
|
124
|
-
consumed[key] = value
|
125
|
-
Router::Utils.escape_path(value)
|
126
|
-
else
|
127
|
-
"\0"
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
153
|
class Dot < Visitor # :nodoc:
|
133
154
|
def initialize
|
134
155
|
@nodes = []
|
@@ -2,13 +2,13 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<title><%= title %></title>
|
5
|
-
<link rel="stylesheet" href="https://
|
5
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" type="text/css">
|
6
6
|
<style>
|
7
7
|
<% stylesheets.each do |style| %>
|
8
8
|
<%= style %>
|
9
9
|
<% end %>
|
10
10
|
</style>
|
11
|
-
<script src="https://
|
11
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js" type="text/javascript"></script>
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<div id="wrapper">
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
module ActionDispatch
|
3
|
-
#
|
3
|
+
# Provides callbacks to be executed before and after dispatching the request.
|
4
4
|
class Callbacks
|
5
5
|
include ActiveSupport::Callbacks
|
6
6
|
|
@@ -8,14 +8,14 @@ module ActionDispatch
|
|
8
8
|
|
9
9
|
class << self
|
10
10
|
delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
|
11
|
-
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def before(*args, &block)
|
13
|
+
set_callback(:call, :before, *args, &block)
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
def after(*args, &block)
|
17
|
+
set_callback(:call, :after, *args, &block)
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
21
|
def initialize(app)
|