From 021f3d24f32dbad98c72cd5c36ff0b511be07a64 Mon Sep 17 00:00:00 2001 From: Mircea Pricop Date: Fri, 6 Jul 2012 17:19:20 +0200 Subject: Prevent conflict between mime types and Object methods Assuming the type ":touch", Collector.new was calling send(:touch), which instead of triggering method_missing and generating a new collector method, actually invoked the private method `touch` inherited from Object. By generating the method for each mime type as it is registered, the private methods on Object can never be reached by `send`, because the `Collector` will have them before `send` is called on it. To do this, a callback mechanism was added to Mime::Type This allows someone to add a callback for whenever a new mime type is registered. The callback then gets called with the new mime as a parameter. This is then used in AbstractController::Collector to generate new collector methods after each mime is registered. --- actionpack/lib/action_dispatch/http/mime_type.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch/http/mime_type.rb') diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index 83cd3d1ca8..fe39c220a5 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -58,6 +58,8 @@ module Mime cattr_reader :browser_generated_types attr_reader :symbol + @register_callbacks = [] + # A simple helper class used in parsing the accept header class AcceptItem #:nodoc: attr_accessor :order, :name, :q @@ -89,6 +91,10 @@ module Mime TRAILING_STAR_REGEXP = /(text|application)\/\*/ PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/ + def register_callback(&block) + @register_callbacks << block + end + def lookup(string) LOOKUP[string] end @@ -106,10 +112,15 @@ module Mime def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false) Mime.const_set(symbol.upcase, Type.new(string, symbol, mime_type_synonyms)) - SET << Mime.const_get(symbol.upcase) + new_mime = Mime.const_get(symbol.upcase) + SET << new_mime ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last } + + @register_callbacks.each do |callback| + callback.call(new_mime) + end end def parse(accept_header) -- cgit v1.2.3