halorgium-actionpack 3.0.pre
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/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'strscan'
|
|
2
|
+
|
|
3
|
+
module HTML #:nodoc:
|
|
4
|
+
|
|
5
|
+
# A simple HTML tokenizer. It simply breaks a stream of text into tokens, where each
|
|
6
|
+
# token is a string. Each string represents either "text", or an HTML element.
|
|
7
|
+
#
|
|
8
|
+
# This currently assumes valid XHTML, which means no free < or > characters.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
#
|
|
12
|
+
# tokenizer = HTML::Tokenizer.new(text)
|
|
13
|
+
# while token = tokenizer.next
|
|
14
|
+
# p token
|
|
15
|
+
# end
|
|
16
|
+
class Tokenizer #:nodoc:
|
|
17
|
+
|
|
18
|
+
# The current (byte) position in the text
|
|
19
|
+
attr_reader :position
|
|
20
|
+
|
|
21
|
+
# The current line number
|
|
22
|
+
attr_reader :line
|
|
23
|
+
|
|
24
|
+
# Create a new Tokenizer for the given text.
|
|
25
|
+
def initialize(text)
|
|
26
|
+
@scanner = StringScanner.new(text)
|
|
27
|
+
@position = 0
|
|
28
|
+
@line = 0
|
|
29
|
+
@current_line = 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Return the next token in the sequence, or +nil+ if there are no more tokens in
|
|
33
|
+
# the stream.
|
|
34
|
+
def next
|
|
35
|
+
return nil if @scanner.eos?
|
|
36
|
+
@position = @scanner.pos
|
|
37
|
+
@line = @current_line
|
|
38
|
+
if @scanner.check(/<\S/)
|
|
39
|
+
update_current_line(scan_tag)
|
|
40
|
+
else
|
|
41
|
+
update_current_line(scan_text)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Treat the text at the current position as a tag, and scan it. Supports
|
|
48
|
+
# comments, doctype tags, and regular tags, and ignores less-than and
|
|
49
|
+
# greater-than characters within quoted strings.
|
|
50
|
+
def scan_tag
|
|
51
|
+
tag = @scanner.getch
|
|
52
|
+
if @scanner.scan(/!--/) # comment
|
|
53
|
+
tag << @scanner.matched
|
|
54
|
+
tag << (@scanner.scan_until(/--\s*>/) || @scanner.scan_until(/\Z/))
|
|
55
|
+
elsif @scanner.scan(/!\[CDATA\[/)
|
|
56
|
+
tag << @scanner.matched
|
|
57
|
+
tag << (@scanner.scan_until(/\]\]>/) || @scanner.scan_until(/\Z/))
|
|
58
|
+
elsif @scanner.scan(/!/) # doctype
|
|
59
|
+
tag << @scanner.matched
|
|
60
|
+
tag << consume_quoted_regions
|
|
61
|
+
else
|
|
62
|
+
tag << consume_quoted_regions
|
|
63
|
+
end
|
|
64
|
+
tag
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Scan all text up to the next < character and return it.
|
|
68
|
+
def scan_text
|
|
69
|
+
"#{@scanner.getch}#{@scanner.scan(/[^<]*/)}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Counts the number of newlines in the text and updates the current line
|
|
73
|
+
# accordingly.
|
|
74
|
+
def update_current_line(text)
|
|
75
|
+
text.scan(/\r?\n/) { @current_line += 1 }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Skips over quoted strings, so that less-than and greater-than characters
|
|
79
|
+
# within the strings are ignored.
|
|
80
|
+
def consume_quoted_regions
|
|
81
|
+
text = ""
|
|
82
|
+
loop do
|
|
83
|
+
match = @scanner.scan_until(/['"<>]/) or break
|
|
84
|
+
|
|
85
|
+
delim = @scanner.matched
|
|
86
|
+
if delim == "<"
|
|
87
|
+
match = match.chop
|
|
88
|
+
@scanner.pos -= 1
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
text << match
|
|
92
|
+
break if delim == "<" || delim == ">"
|
|
93
|
+
|
|
94
|
+
# consume the quoted region
|
|
95
|
+
while match = @scanner.scan_until(/[\\#{delim}]/)
|
|
96
|
+
text << match
|
|
97
|
+
break if @scanner.matched == delim
|
|
98
|
+
text << @scanner.getch # skip the escaped character
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
text
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2004-2009 David Heinemeier Hansson
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
require 'rack'
|
|
25
|
+
|
|
26
|
+
module Rack
|
|
27
|
+
autoload :Test, 'rack/test'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module ActionDispatch
|
|
31
|
+
autoload :Request, 'action_dispatch/http/request'
|
|
32
|
+
autoload :Response, 'action_dispatch/http/response'
|
|
33
|
+
autoload :StatusCodes, 'action_dispatch/http/status_codes'
|
|
34
|
+
autoload :Utils, 'action_dispatch/http/utils'
|
|
35
|
+
|
|
36
|
+
autoload :Callbacks, 'action_dispatch/middleware/callbacks'
|
|
37
|
+
autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
|
|
38
|
+
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
|
|
39
|
+
autoload :Rescue, 'action_dispatch/middleware/rescue'
|
|
40
|
+
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
|
|
41
|
+
autoload :Static, 'action_dispatch/middleware/static'
|
|
42
|
+
autoload :StringCoercion, 'action_dispatch/middleware/string_coercion'
|
|
43
|
+
|
|
44
|
+
autoload :Routing, 'action_dispatch/routing'
|
|
45
|
+
|
|
46
|
+
autoload :Assertions, 'action_dispatch/testing/assertions'
|
|
47
|
+
autoload :Integration, 'action_dispatch/testing/integration'
|
|
48
|
+
autoload :IntegrationTest, 'action_dispatch/testing/integration'
|
|
49
|
+
autoload :PerformanceTest, 'action_dispatch/testing/performance_test'
|
|
50
|
+
autoload :TestRequest, 'action_dispatch/testing/test_request'
|
|
51
|
+
autoload :TestResponse, 'action_dispatch/testing/test_response'
|
|
52
|
+
|
|
53
|
+
autoload :HTML, 'action_controller/vendor/html-scanner'
|
|
54
|
+
|
|
55
|
+
module Http
|
|
56
|
+
autoload :Headers, 'action_dispatch/http/headers'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
module Session
|
|
60
|
+
autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store'
|
|
61
|
+
autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store'
|
|
62
|
+
autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
autoload :Mime, 'action_dispatch/http/mime_type'
|
|
67
|
+
|
|
68
|
+
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
|
69
|
+
$:.unshift activesupport_path if File.directory?(activesupport_path)
|
|
70
|
+
require 'active_support'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'active_support/memoizable'
|
|
2
|
+
|
|
3
|
+
module ActionDispatch
|
|
4
|
+
module Http
|
|
5
|
+
class Headers < ::Hash
|
|
6
|
+
extend ActiveSupport::Memoizable
|
|
7
|
+
|
|
8
|
+
def initialize(*args)
|
|
9
|
+
if args.size == 1 && args[0].is_a?(Hash)
|
|
10
|
+
super()
|
|
11
|
+
update(args[0])
|
|
12
|
+
else
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def [](header_name)
|
|
18
|
+
if include?(header_name)
|
|
19
|
+
super
|
|
20
|
+
else
|
|
21
|
+
super(env_name(header_name))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
# Converts a HTTP header name to an environment variable name.
|
|
27
|
+
def env_name(header_name)
|
|
28
|
+
"HTTP_#{header_name.upcase.gsub(/-/, '_')}"
|
|
29
|
+
end
|
|
30
|
+
memoize :env_name
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
|
3
|
+
|
|
4
|
+
module Mime
|
|
5
|
+
class Mimes < Array
|
|
6
|
+
def symbols
|
|
7
|
+
@symbols ||= map {|m| m.to_sym }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
%w(<< concat shift unshift push pop []= clear compact! collect!
|
|
11
|
+
delete delete_at delete_if flatten! map! insert reject! reverse!
|
|
12
|
+
replace slice! sort! uniq!).each do |method|
|
|
13
|
+
module_eval <<-CODE
|
|
14
|
+
def #{method}(*args)
|
|
15
|
+
@symbols = nil
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
CODE
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
SET = Mimes.new
|
|
23
|
+
EXTENSION_LOOKUP = {}
|
|
24
|
+
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
|
|
25
|
+
|
|
26
|
+
def self.[](type)
|
|
27
|
+
return type if type.is_a?(Type)
|
|
28
|
+
Type.lookup_by_extension(type.to_s)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Encapsulates the notion of a mime type. Can be used at render time, for example, with:
|
|
32
|
+
#
|
|
33
|
+
# class PostsController < ActionController::Base
|
|
34
|
+
# def show
|
|
35
|
+
# @post = Post.find(params[:id])
|
|
36
|
+
#
|
|
37
|
+
# respond_to do |format|
|
|
38
|
+
# format.html
|
|
39
|
+
# format.ics { render :text => post.to_ics, :mime_type => Mime::Type["text/calendar"] }
|
|
40
|
+
# format.xml { render :xml => @people.to_xml }
|
|
41
|
+
# end
|
|
42
|
+
# end
|
|
43
|
+
# end
|
|
44
|
+
class Type
|
|
45
|
+
@@html_types = Set.new [:html, :all]
|
|
46
|
+
cattr_reader :html_types
|
|
47
|
+
|
|
48
|
+
# These are the content types which browsers can generate without using ajax, flash, etc
|
|
49
|
+
# i.e. following a link, getting an image or posting a form. CSRF protection
|
|
50
|
+
# only needs to protect against these types.
|
|
51
|
+
@@browser_generated_types = Set.new [:html, :url_encoded_form, :multipart_form, :text]
|
|
52
|
+
cattr_reader :browser_generated_types
|
|
53
|
+
attr_reader :symbol
|
|
54
|
+
|
|
55
|
+
@@unverifiable_types = Set.new [:text, :json, :csv, :xml, :rss, :atom, :yaml]
|
|
56
|
+
def self.unverifiable_types
|
|
57
|
+
ActiveSupport::Deprecation.warn("unverifiable_types is deprecated and has no effect", caller)
|
|
58
|
+
@@unverifiable_types
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# A simple helper class used in parsing the accept header
|
|
62
|
+
class AcceptItem #:nodoc:
|
|
63
|
+
attr_accessor :order, :name, :q
|
|
64
|
+
|
|
65
|
+
def initialize(order, name, q=nil)
|
|
66
|
+
@order = order
|
|
67
|
+
@name = name.strip
|
|
68
|
+
q ||= 0.0 if @name == Mime::ALL # default wilcard match to end of list
|
|
69
|
+
@q = ((q || 1.0).to_f * 100).to_i
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_s
|
|
73
|
+
@name
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def <=>(item)
|
|
77
|
+
result = item.q <=> q
|
|
78
|
+
result = order <=> item.order if result == 0
|
|
79
|
+
result
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def ==(item)
|
|
83
|
+
name == (item.respond_to?(:name) ? item.name : item)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class << self
|
|
88
|
+
def lookup(string)
|
|
89
|
+
LOOKUP[string]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def lookup_by_extension(extension)
|
|
93
|
+
EXTENSION_LOOKUP[extension.to_s]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Registers an alias that's not used on mime type lookup, but can be referenced directly. Especially useful for
|
|
97
|
+
# rendering different HTML versions depending on the user agent, like an iPhone.
|
|
98
|
+
def register_alias(string, symbol, extension_synonyms = [])
|
|
99
|
+
register(string, symbol, [], extension_synonyms, true)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
|
|
103
|
+
Mime.instance_eval { const_set symbol.to_s.upcase, Type.new(string, symbol, mime_type_synonyms) }
|
|
104
|
+
|
|
105
|
+
SET << Mime.const_get(symbol.to_s.upcase)
|
|
106
|
+
|
|
107
|
+
([string] + mime_type_synonyms).each { |string| LOOKUP[string] = SET.last } unless skip_lookup
|
|
108
|
+
([symbol.to_s] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext] = SET.last }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def parse(accept_header)
|
|
112
|
+
if accept_header !~ /,/
|
|
113
|
+
[Mime::Type.lookup(accept_header)]
|
|
114
|
+
else
|
|
115
|
+
# keep track of creation order to keep the subsequent sort stable
|
|
116
|
+
list = []
|
|
117
|
+
accept_header.split(/,/).each_with_index do |header, index|
|
|
118
|
+
params, q = header.split(/;\s*q=/)
|
|
119
|
+
if params
|
|
120
|
+
params.strip!
|
|
121
|
+
list << AcceptItem.new(index, params, q) unless params.empty?
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
list.sort!
|
|
125
|
+
|
|
126
|
+
# Take care of the broken text/xml entry by renaming or deleting it
|
|
127
|
+
text_xml = list.index("text/xml")
|
|
128
|
+
app_xml = list.index(Mime::XML.to_s)
|
|
129
|
+
|
|
130
|
+
if text_xml && app_xml
|
|
131
|
+
# set the q value to the max of the two
|
|
132
|
+
list[app_xml].q = [list[text_xml].q, list[app_xml].q].max
|
|
133
|
+
|
|
134
|
+
# make sure app_xml is ahead of text_xml in the list
|
|
135
|
+
if app_xml > text_xml
|
|
136
|
+
list[app_xml], list[text_xml] = list[text_xml], list[app_xml]
|
|
137
|
+
app_xml, text_xml = text_xml, app_xml
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# delete text_xml from the list
|
|
141
|
+
list.delete_at(text_xml)
|
|
142
|
+
|
|
143
|
+
elsif text_xml
|
|
144
|
+
list[text_xml].name = Mime::XML.to_s
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Look for more specific XML-based types and sort them ahead of app/xml
|
|
148
|
+
|
|
149
|
+
if app_xml
|
|
150
|
+
idx = app_xml
|
|
151
|
+
app_xml_type = list[app_xml]
|
|
152
|
+
|
|
153
|
+
while(idx < list.length)
|
|
154
|
+
type = list[idx]
|
|
155
|
+
break if type.q < app_xml_type.q
|
|
156
|
+
if type.name =~ /\+xml$/
|
|
157
|
+
list[app_xml], list[idx] = list[idx], list[app_xml]
|
|
158
|
+
app_xml = idx
|
|
159
|
+
end
|
|
160
|
+
idx += 1
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
list.map! { |i| Mime::Type.lookup(i.name) }.uniq!
|
|
165
|
+
list
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def initialize(string, symbol = nil, synonyms = [])
|
|
171
|
+
@symbol, @synonyms = symbol, synonyms
|
|
172
|
+
@string = string
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def to_s
|
|
176
|
+
@string
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def to_str
|
|
180
|
+
to_s
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def to_sym
|
|
184
|
+
@symbol || @string.to_sym
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def ===(list)
|
|
188
|
+
if list.is_a?(Array)
|
|
189
|
+
(@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
|
|
190
|
+
else
|
|
191
|
+
super
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def ==(mime_type)
|
|
196
|
+
return false if mime_type.blank?
|
|
197
|
+
(@synonyms + [ self ]).any? do |synonym|
|
|
198
|
+
synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def =~(mime_type)
|
|
203
|
+
return false if mime_type.blank?
|
|
204
|
+
regexp = Regexp.new(Regexp.quote(mime_type.to_s))
|
|
205
|
+
(@synonyms + [ self ]).any? do |synonym|
|
|
206
|
+
synonym.to_s =~ regexp
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
|
|
211
|
+
# ActionController::RequestForgeryProtection.
|
|
212
|
+
def verify_request?
|
|
213
|
+
@@browser_generated_types.include?(to_sym)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def html?
|
|
217
|
+
@@html_types.include?(to_sym) || @string =~ /html/
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
private
|
|
221
|
+
def method_missing(method, *args)
|
|
222
|
+
if method.to_s =~ /(\w+)\?$/
|
|
223
|
+
$1.downcase.to_sym == to_sym
|
|
224
|
+
else
|
|
225
|
+
super
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
require 'action_dispatch/http/mime_types'
|