Class: Angelo::Responder
- Inherits:
-
Object
- Object
- Angelo::Responder
- Includes:
- Celluloid::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.
-
#request ⇒ Object
Returns the value of attribute request.
Class Method Summary collapse
Instance Method Summary collapse
- #content_type(type) ⇒ Object
- #error_message(_error) ⇒ Object
- #handle_error(_error, type = :internal_server_error, report = @base.report_errors?) ⇒ Object
- #handle_request ⇒ Object
- #headers(hs = nil) ⇒ Object
-
#initialize(&block) ⇒ Responder
constructor
A new instance of Responder.
- #redirect(url) ⇒ Object
- #respond ⇒ Object
- #respond_with?(type) ⇒ Boolean
- #transfer_encoding(*encodings) ⇒ Object
Constructor Details
Class Attribute Details
.default_headers ⇒ Object
22 23 24 25 |
# File 'lib/angelo/responder.rb', line 22 def default_headers @default_headers ||= DEFAULT_RESPONSE_HEADERS @default_headers end |
Instance Attribute Details
#base=(value) ⇒ Object (writeonly)
Sets the attribute base
35 36 37 |
# File 'lib/angelo/responder.rb', line 35 def base=(value) @base = value end |
#connection ⇒ Object
Returns the value of attribute connection.
33 34 35 |
# File 'lib/angelo/responder.rb', line 33 def connection @connection end |
#request ⇒ Object
Returns the value of attribute request.
34 35 36 |
# File 'lib/angelo/responder.rb', line 34 def request @request end |
Class Method Details
.content_type(type) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/angelo/responder.rb', line 10 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 |
.symhash ⇒ Object
27 28 29 |
# File 'lib/angelo/responder.rb', line 27 def symhash Hash.new {|hash,key| hash[key.to_s] if Symbol === key } end |
Instance Method Details
#content_type(type) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/angelo/responder.rb', line 107 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 else raise ArgumentError.new "invalid content_type: #{type}" end end |
#error_message(_error) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/angelo/responder.rb', line 87 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
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/angelo/responder.rb', line 76 def handle_error _error, type = :internal_server_error, report = @base.report_errors? err_msg = _error Angelo.log @connection, @request, nil, type, err_msg.size @connection.respond type, headers, err_msg @connection.close if report error "#{_error.class} - #{_error.}" ::STDERR.puts _error.backtrace end end |
#handle_request ⇒ Object
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 |
# File 'lib/angelo/responder.rb', line 49 def handle_request if @response_handler @base.filter :before @body = catch(:halt) { @response_handler.bind(@base).call || 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
101 102 103 104 105 |
# File 'lib/angelo/responder.rb', line 101 def headers hs = nil @headers ||= self.class.default_headers.dup @headers.merge! hs if hs @headers end |
#redirect(url) ⇒ Object
198 199 200 |
# File 'lib/angelo/responder.rb', line 198 def redirect url @redirect = url end |
#respond ⇒ Object
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 142 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 unless @chunked and @body.respond_to? :each raise RequestError.new "what is this? #{@body}" end end status ||= @redirect.nil? ? :ok : :moved_permanently headers LOCATION_HEADER_KEY => @redirect if @redirect if @chunked Angelo.log @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 @connection, @request, nil, status, size @request.respond status, headers, @body end rescue => e handle_error e, :internal_server_error end |
#respond_with?(type) ⇒ Boolean
133 134 135 136 137 138 139 140 |
# File 'lib/angelo/responder.rb', line 133 def respond_with? type case headers[CONTENT_TYPE_HEADER_KEY] when JSON_TYPE type == :json else type == :html end end |
#transfer_encoding(*encodings) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/angelo/responder.rb', line 120 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 |