Class: Fredo::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/fredo/handler.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#envObject

Returns the value of attribute env.



4
5
6
# File 'lib/fredo/handler.rb', line 4

def env
  @env
end

#paramsObject

Returns the value of attribute params.



4
5
6
# File 'lib/fredo/handler.rb', line 4

def params
  @params
end

#requestObject

Returns the value of attribute request.



4
5
6
# File 'lib/fredo/handler.rb', line 4

def request
  @request
end

#responseObject

Returns the value of attribute response.



4
5
6
# File 'lib/fredo/handler.rb', line 4

def response
  @response
end

Instance Method Details

#call(env) ⇒ Object



6
7
8
9
10
11
12
13
14
15
# File 'lib/fredo/handler.rb', line 6

def call(env)
  @env      = env
  @request  = Rack::Request.new(env)
  @params   = @request.params
  @response = Response.new([],200,{})
  
  dispatch!
  
  respond!
end

#dispatch!Object

Dispatch a request with error handling.



18
19
20
# File 'lib/fredo/handler.rb', line 18

def dispatch!
  route!
end

#handle_exception!(boom) ⇒ Object



75
76
77
78
79
80
# File 'lib/fredo/handler.rb', line 75

def handle_exception!(boom)
  @env['fredo.error'] = boom
  @response.body   = ["<h1>You broke my heart Fredo!</h1><h5>Fredo raised an exception.</h5><tt>#{boom.inspect}</tt>"]
  @response.status = 500
  # raise Mixup.new("original error: #{boom.inspect}") if Fredo.allow_exceptions?
end

#handle_not_found!(boom) ⇒ Object



69
70
71
72
73
# File 'lib/fredo/handler.rb', line 69

def handle_not_found!(boom)
  @env['fredo.error'] = boom
  @response.status    = 404
  @response.body      = ['<h1>Not Found</h1>']
end

#perform!(&block) ⇒ Object



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
# File 'lib/fredo/handler.rb', line 82

def perform!(&block)
  if block_given?
    @response['Content-Type']= 'text/html'
    
    res = instance_eval(&block)
    case
    when res.respond_to?(:to_str)
      @response.body = [res]
    when res.respond_to?(:to_ary)
      res = res.to_ary
      if Fixnum === res.first
        if res.length == 3
          @response.status, headers, body = res
          @response.body = body if body
          headers.each { |k, v| @response.headers[k] = v } if headers
        elsif res.length == 2
          @response.status = res.first
          @response.body   = res.last
        else
          raise TypeError, "#{res.inspect} not supported"
        end
      else
        @response.body = res
      end
    when res.respond_to?(:each)
      @response.body = res
    when (100...599) === res
      @response.status = res
    end
    
  end
rescue ::Exception => boom
  handle_exception!(boom)
end

#respond!Object



117
118
119
120
# File 'lib/fredo/handler.rb', line 117

def respond!
  status, header, body = @response.finish
  [status, header, body]
end

#route!Object

Raises:



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
# File 'lib/fredo/handler.rb', line 28

def route!
  
  if routes = routes_for_host?
    path = URI.unescape(@request.path_info)
    routes.each do |pattern, keys, conditions, block|
      if match = pattern.match(path)
        values = match.captures.to_a
        params =
          if keys.any?
            keys.zip(values).inject({}) do |hash,(k,v)|
              if k == :splat
                (hash[k] ||= []) << v
              else
                hash[k.to_sym] = v
              end
              hash
            end
          elsif values.any?
            {'captures' => values}
          else
            {}
          end
        @params.merge!(params)
        
        Fredo.books << {:path => path,
                        :params => @params,
                        :method => @request.request_method,
                        :host => @request.host,
                        :body => @request.body.read}
        @request.body.rewind
        
        perform!(&block)
        return
      end
    end
    
  end
  
  raise NotFound
end

#routes_for_host?Boolean



22
23
24
25
26
# File 'lib/fredo/handler.rb', line 22

def routes_for_host?
  Registry.routes[@request.request_method][@request.host]
rescue
  false
end