Class: Angelo::Responder

Inherits:
Object
  • Object
show all
Includes:
Celluloid::Logger
Defined in:
lib/angelo/responder.rb

Direct Known Subclasses

WebsocketResponder

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Responder

Returns a new instance of Responder.



38
39
40
# File 'lib/angelo/responder.rb', line 38

def initialize &block
  @response_handler = Base.compile! :request_handler, &block
end

Class Attribute Details

.default_headersObject



24
25
26
27
# File 'lib/angelo/responder.rb', line 24

def default_headers
  @default_headers ||= DEFAULT_RESPONSE_HEADERS
  @default_headers
end

Instance Attribute Details

#connection=(value) ⇒ Object (writeonly)

Sets the attribute connection

Parameters:

  • value

    the value to set the attribute connection to.



35
36
37
# File 'lib/angelo/responder.rb', line 35

def connection=(value)
  @connection = value
end

#requestObject

Returns the value of attribute request.



36
37
38
# File 'lib/angelo/responder.rb', line 36

def request
  @request
end

Class Method Details

.content_type(type) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/angelo/responder.rb', line 12

def content_type type
  dhs = self.default_headers
  case type
  when :json
    self.default_headers = dhs.merge CONTENT_TYPE_HEADER_KEY => JSON_TYPE
  when :html
    self.default_headers = dhs.merge CONTENT_TYPE_HEADER_KEY => HTML_TYPE
  else
    raise ArgumentError.new "invalid content_type: #{type}"
  end
end

.symhashObject



29
30
31
# File 'lib/angelo/responder.rb', line 29

def symhash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end

Instance Method Details

#base=(base) ⇒ Object



42
43
44
45
# File 'lib/angelo/responder.rb', line 42

def base= base
  @base = base
  @base.responder = self
end

#content_type(type) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/angelo/responder.rb', line 104

def content_type type
  case type
  when :json
    headers CONTENT_TYPE_HEADER_KEY => JSON_TYPE
  when :html
    headers CONTENT_TYPE_HEADER_KEY => HTML_TYPE
  else
    raise ArgumentError.new "invalid content_type: #{type}"
  end
end

#error_message(_error) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/angelo/responder.rb', line 84

def error_message _error
  case
  when respond_with?(:json)
    { error: _error.message }.to_json
  else
    case _error.message
    when Hash
      _error.message.to_s
    else
      _error.message
    end
  end
end

#handle_error(_error, type = :internal_server_error, report = true) ⇒ Object



73
74
75
76
77
78
79
80
81
82
# File 'lib/angelo/responder.rb', line 73

def handle_error _error, type = :internal_server_error, report = true
  err_msg = error_message _error
  Angelo.log @connection, @request, nil, type, err_msg.size
  @connection.respond type, headers, err_msg
  @connection.close
  if report
    error "#{_error.class} - #{_error.message}"
    ::STDERR.puts _error.backtrace
  end
end

#handle_requestObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/angelo/responder.rb', line 54

def handle_request
  if @response_handler
    @base.before if @base.respond_to? :before
    @body = @response_handler.bind(@base).call || ''
    @base.after if @base.respond_to? :after
    respond
  else
    raise NotImplementedError
  end
rescue JSON::ParserError => jpe
  handle_error jpe, :bad_request, false
rescue FormEncodingError => fee
  handle_error fee, :bad_request, false
rescue RequestError => re
  handle_error re, re.type, false
rescue => e
  handle_error e
end

#headers(hs = nil) ⇒ Object



98
99
100
101
102
# File 'lib/angelo/responder.rb', line 98

def headers hs = nil
  @headers ||= self.class.default_headers.dup
  @headers.merge! hs if hs
  @headers
end

#redirect(url) ⇒ Object



145
146
147
# File 'lib/angelo/responder.rb', line 145

def redirect url
  @redirect = url
end

#respondObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/angelo/responder.rb', line 124

def respond
  @body = case @body
          when String
            JSON.parse @body if respond_with? :json # for the raises
            @body
          when Hash
            raise 'html response requires String' if respond_with? :html
            @body.to_json if respond_with? :json
          when NilClass
            EMPTY_STRING
          end

  status = @redirect.nil? ? :ok : :moved_permanently
  headers LOCATION_HEADER_KEY => @redirect if @redirect

  Angelo.log @connection, @request, nil, status, @body.size
  @connection.respond status, headers, @body
rescue => e
  handle_error e, :internal_server_error, false
end

#respond_with?(type) ⇒ Boolean

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
# File 'lib/angelo/responder.rb', line 115

def respond_with? type
  case headers[CONTENT_TYPE_HEADER_KEY]
  when JSON_TYPE
    type == :json
  else
    type == :html
  end
end