Class: Angelo::Responder
- Inherits:
-
Object
- Object
- Angelo::Responder
- Includes:
- Celluloid::Internals::Logger
- Defined in:
- lib/angelo/responder.rb,
lib/angelo/responder/websocket.rb,
lib/angelo/responder/eventsource.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Eventsource, Websocket
Class Attribute Summary collapse
Instance Attribute Summary collapse
-
#base ⇒ Object
writeonly
Sets the attribute base.
-
#connection ⇒ Object
Returns the value of attribute connection.
-
#mustermann ⇒ Object
Returns the value of attribute mustermann.
-
#request ⇒ Object
Returns the value of attribute request.
Class Method Summary collapse
-
.content_type(type) ⇒ Object
top-level setter.
Instance Method Summary collapse
-
#content_type(type) ⇒ Object
route handler helper.
- #error_message(_error) ⇒ Object
- #handle_error(_error, type = :internal_server_error, report = @base.report_errors?) ⇒ Object
- #handle_request ⇒ Object
- #headers(hs = nil) ⇒ Object
-
#initialize(method, &block) ⇒ Responder
constructor
A new instance of Responder.
- #on_close ⇒ Object
- #on_close=(on_close) ⇒ Object
- #redirect(url, permanent = false) ⇒ Object
- #redirect!(url) ⇒ Object
- #reset! ⇒ Object
- #respond ⇒ Object
- #respond_with?(type) ⇒ Boolean
- #transfer_encoding(*encodings) ⇒ Object
Constructor Details
#initialize(method, &block) ⇒ Responder
Returns a new instance of Responder.
33 34 35 |
# File 'lib/angelo/responder.rb', line 33 def initialize method, &block @method, @response_handler = method, block end |
Class Attribute Details
.default_headers ⇒ Object
23 24 25 26 |
# File 'lib/angelo/responder.rb', line 23 def default_headers @default_headers ||= DEFAULT_RESPONSE_HEADERS @default_headers end |
Instance Attribute Details
#base=(value) ⇒ Object (writeonly)
Sets the attribute base
31 32 33 |
# File 'lib/angelo/responder.rb', line 31 def base=(value) @base = value end |
#connection ⇒ Object
Returns the value of attribute connection.
30 31 32 |
# File 'lib/angelo/responder.rb', line 30 def connection @connection end |
#mustermann ⇒ Object
Returns the value of attribute mustermann.
30 31 32 |
# File 'lib/angelo/responder.rb', line 30 def mustermann @mustermann end |
#request ⇒ Object
Returns the value of attribute request.
30 31 32 |
# File 'lib/angelo/responder.rb', line 30 def request @request end |
Class Method Details
.content_type(type) ⇒ Object
top-level setter
11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/angelo/responder.rb', line 11 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 |
Instance Method Details
#content_type(type) ⇒ Object
route handler helper
100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/angelo/responder.rb', line 100 def content_type type case type when :json headers CONTENT_TYPE_HEADER_KEY => JSON_TYPE when :html headers CONTENT_TYPE_HEADER_KEY => HTML_TYPE when :js headers CONTENT_TYPE_HEADER_KEY => JS_TYPE when :xml headers CONTENT_TYPE_HEADER_KEY => XML_TYPE else raise ArgumentError.new "invalid content_type: #{type}" end end |
#error_message(_error) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/angelo/responder.rb', line 79 def _error case when respond_with?(:json) { error: _error. }.to_json else case _error. when Hash _error..to_s else _error. end end end |
#handle_error(_error, type = :internal_server_error, report = @base.report_errors?) ⇒ Object
71 72 73 74 75 76 77 |
# File 'lib/angelo/responder.rb', line 71 def handle_error _error, type = :internal_server_error, report = @base.report_errors? err_msg = _error Angelo.log @method, @connection, @request, nil, type, err_msg.size @connection.respond type, headers, err_msg @connection.close error _error if report end |
#handle_request ⇒ Object
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 |
# File 'lib/angelo/responder.rb', line 44 def handle_request if @response_handler @base.filter :before @body = catch(:halt) { @base.instance_exec(&@response_handler) || EMPTY_STRING } # TODO any real reason not to run afters with SSE? case @body when HALT_STRUCT @base.filter :after if @body.body != :sse else @base.filter :after end respond else raise NotImplementedError end rescue JSON::ParserError => jpe handle_error jpe, :bad_request rescue FormEncodingError => fee handle_error fee, :bad_request rescue RequestError => re handle_error re, re.type rescue => e handle_error e end |
#headers(hs = nil) ⇒ Object
93 94 95 96 97 |
# File 'lib/angelo/responder.rb', line 93 def headers hs = nil @headers ||= self.class.default_headers.dup @headers.merge! hs if hs @headers end |
#on_close ⇒ Object
212 213 214 |
# File 'lib/angelo/responder.rb', line 212 def on_close @on_close[] if @on_close end |
#on_close=(on_close) ⇒ Object
207 208 209 210 |
# File 'lib/angelo/responder.rb', line 207 def on_close= on_close raise ArgumentError.new unless Proc === on_close @on_close = on_close end |
#redirect(url, permanent = false) ⇒ Object
198 199 200 201 |
# File 'lib/angelo/responder.rb', line 198 def redirect url, permanent = false @redirect = [url, permanent ? :moved_permanently : :found] nil end |
#redirect!(url) ⇒ Object
203 204 205 |
# File 'lib/angelo/responder.rb', line 203 def redirect! url redirect url, true end |
#reset! ⇒ Object
37 38 39 40 41 42 |
# File 'lib/angelo/responder.rb', line 37 def reset! @params = nil @redirect = nil @body = nil @request = nil end |
#respond ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/angelo/responder.rb', line 137 def respond status = nil case @body when HALT_STRUCT status = @body.status @body = @body.body @body = nil if @body == :sse if Hash === @body @body = {error: @body} if status != :ok or status < 200 && status >= 300 @body = @body.to_json if respond_with? :json end when String JSON.parse @body if respond_with? :json # for the raises when Hash raise 'html response requires String' if respond_with? :html @body = @body.to_json if respond_with? :json when NilClass @body = EMPTY_STRING else if respond_with? :json and @body.respond_to? :to_json @body = @body.to_json raise "uhhh? #{@body}" unless String === @body else unless @chunked and @body.respond_to? :each raise RequestError.new "what is this? #{@body}" end end end status ||= @redirect.nil? ? :ok : @redirect[1] headers LOCATION_HEADER_KEY => @redirect[0] if @redirect if @chunked Angelo.log @method, @connection, @request, nil, status @request.respond status, headers err = nil begin @body.each do |r| r = r.to_json + NEWLINE if respond_with? :json @request << r end rescue => e err = e ensure @request.finish_response raise err if err end else size = @body.nil? ? 0 : @body.size Angelo.log @method, @connection, @request, nil, status, size @request.respond status, headers, @body end rescue => e handle_error e, :internal_server_error end |
#respond_with?(type) ⇒ Boolean
128 129 130 131 132 133 134 135 |
# File 'lib/angelo/responder.rb', line 128 def respond_with? type case headers[CONTENT_TYPE_HEADER_KEY] when JSON_TYPE type == :json else type == :html end end |
#transfer_encoding(*encodings) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/angelo/responder.rb', line 115 def transfer_encoding *encodings encodings.flatten.each do |encoding| case encoding when :chunked @chunked = true headers transfer_encoding: :chunked # when :compress, :deflate, :gzip, :identity else raise ArgumentError.new "invalid transfer_conding: #{encoding}" end end end |