public
Rubygem
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-core.git
Search Repo:
wycats (author)
Sat Jan 12 13:30:36 -0800 2008
commit  248c2837aa42dc12b323dc6da15445ae3a774b6e
tree    ceb6ba85efdbaefc9d9864f692e215c979b27e4f
parent  e11196de18e713d643f28995688562a646168775
merb-core / lib / merb_core / controller / controller.rb
100644 119 lines (106 sloc) 4.496 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class Merb::Controller < AbstractController
  
  class_inheritable_accessor :_session_id_key, :_session_expiry, :_hidden_actions
  cattr_accessor :_subclasses, :_session_secret_key
  self._subclasses = Set.new
  self.session_secret_key = nil
  self._session_id_key = '_session_id'
  self._session_expiry = Time.now + Merb::Const::WEEK * 2
  
  include Merb::ResponderMixin
  include Merb::ControllerExceptions
  
  class << self
    
    # ==== Parameters
    # klass<Merb::Controller>:: The Merb::Controller inheriting from the
    # base class
    def inherited(klass)
      _subclasses << klass.to_s
      klass._hidden_actions = Merb::Controller.public_instance_methods
      super
    end
 
    # A list of actions that should not be available as callable actions
    def hidden_actions
      _hidden_actions
    end
    
    # Hide each of the given methods from being callable as actions.
    #
    # ==== Parameters
    # *names<~to-s>:: Actions that should be added to the list
    def hide_action(*names)
      _hidden_actions = _hidden_actions | names.collect { |n| n.to_s })
    end
    
    # Build a new controller.
    #
    # ==== Parameters
    # request<Merb::Request>:: The Merb::Request that came in from Mongrel
    # response<IO>::
    # The response IO object to write the response to. This could be any
    # IO object, but is probably an HTTPResponse
    # status<Integer>:: An integer code for the status
    # headers<Hash{header => value}>::
    # A hash of headers to start the controller with. These headers
    # can be overridden later by the #headers method
    def build(request, response = StringIO.new, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
      cont = new
      cont.set_dispatch_variables(request, response, status, headers)
      cont
    end
    
    # Sets the variables that came in through the dispatch as available to
    # the controller. This is called by .build, so see it for more
    # information.
    #
    # This method uses the :session_id_cookie_only and :query_string_whitelist
    # configuration options. See CONFIG for more details.
    #
    # ==== Parameters
    # request<Merb::Request>:: The Merb::Request that came in from Mongrel
    # response<IO>::
    # The response IO object to write the response to. This could be any
    # IO object, but is probably an HTTPResponse
    # status<Integer>:: An integer code for the status
    # headers<Hash{header => value}>::
    # A hash of headers to start the controller with. These headers
    # can be overridden later by the #headers method
    def set_dispatch_variables(request, response, status, headers)
      if request.params.key?(_session_id_key)
        if Merb::Config[:session_id_cookie_only]
          # This condition allows for certain controller/action paths to allow
          # a session ID to be passed in a query string. This is needed for
          # Flash Uploads to work since flash will not pass a Session Cookie
          # Recommend running session.regenerate after any controller taking
          # advantage of this in case someone is attempting a session fixation
          # attack
          if Merb::Config[:query_string_whitelist].include?("#{request.controller_name}/#{request.action}")
          # FIXME to use routes not controller and action names -----^
            request.cookies[_session_id_key] = request.params[_session_id_key]
          end
        else
          request.cookies[_session_id_key] = request.params[_session_id_key]
        end
      end
      @_request = request
      @_response = response
      @_status = status
      @_headers = headers
    end
    
    # Dispatch the action
    #
    # ==== Parameters
    def dispatch(action=:index)
      start = Time.now
      if self.class.callable_actions[action.to_s]
        params[:action] ||= action
        setup_session
        super(action)
        finalize_session
      else
        raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
      end
      @_benchmarks[:action_time] = Time.now - start
      Merb.logger.info("Time spent in #{self.class}##{action} action: #{@_benchmarks[:action_time]} seconds")
    end
    
    _attr_reader :body, :status, :request, :params, :headers, :response
    def params() request.params end
    def cookies() request.cookies end
    def session() request.session end
    def route() request.route end
    
    
    
  end
end