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



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

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



61
62
63
64
65
# File 'lib/fredo/handler.rb', line 61

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

#perform!(&block) ⇒ Object



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

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



109
110
111
112
# File 'lib/fredo/handler.rb', line 109

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
# 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)
        perform!(&block)
        return
      end
    end
    
  end
  
  raise NotFound
end

#routes_for_host?Boolean

Returns:

  • (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