halorgium-actionpack 3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|