class Cramp::Action
Constants
- CHUNKED_TAIL
- CHUNKED_TERM
Public Class Methods
new(env)
click to toggle source
Calls superclass method
Cramp::PeriodicTimer::new
# File lib/cramp/action.rb, line 6 def initialize(env) super case when Faye::EventSource.eventsource?(env) # request has Accept: text/event-stream # faye server adapter intercepts headers - need to send them in send_initial_response or use faye's implementation @eventsource_detected = true unless transport == :sse err = "WARNING: Cramp got request with EventSource header on action with transport #{transport} (not sse)! Response may not contain valid http headers!" Cramp.logger ? Cramp.logger.error(err) : $stderr.puts(err) end when Faye::WebSocket.websocket?(env) @web_socket = Faye::WebSocket.new(env) @web_socket.onmessage = lambda do |event| message = event.data _invoke_data_callbacks(message) if message.is_a?(String) end end end
Private Instance Methods
build_headers()
click to toggle source
Calls superclass method
Cramp::Abstract#build_headers
# File lib/cramp/action.rb, line 57 def build_headers case transport when :sse status, headers = respond_to?(:respond_with, true) ? respond_with : [200, {'Content-Type' => 'text/html'}] [status, headers.merge(self.default_sse_headers)] when :chunked status, headers = respond_to?(:respond_with, true) ? respond_with : [200, {}] headers = headers.merge(self.default_chunked_headers) headers['Content-Type'] ||= 'text/html' headers['Cache-Control'] ||= 'no-cache' [status, headers] else super end end
encode(string, encoding = 'UTF-8')
click to toggle source
# File lib/cramp/action.rb, line 118 def encode(string, encoding = 'UTF-8') string.respond_to?(:force_encoding) ? string.force_encoding(encoding) : string end
finish()
click to toggle source
Calls superclass method
Cramp::Abstract#finish
# File lib/cramp/action.rb, line 122 def finish case transport when :chunked @body.call(CHUNKED_TAIL) if is_finishable? end super end
render(body, *args)
click to toggle source
# File lib/cramp/action.rb, line 29 def render(body, *args) send(:"render_#{transport}", body, *args) end
render_chunked(body, *)
click to toggle source
# File lib/cramp/action.rb, line 107 def render_chunked(body, *) data = [Rack::Utils.bytesize(body).to_s(16), CHUNKED_TERM, body, CHUNKED_TERM].join @body.call(data) end
render_long_polling(data, *)
click to toggle source
# File lib/cramp/action.rb, line 79 def render_long_polling(data, *) @_lp_headers['Content-Length'] = data.size.to_s send_response(@_lp_status, @_lp_headers, @body) @body.call(data) finish end
render_regular(body, *)
click to toggle source
# File lib/cramp/action.rb, line 75 def render_regular(body, *) @body.call(body) end
render_sse(data, options = {})
click to toggle source
# File lib/cramp/action.rb, line 88 def render_sse(data, options = {}) #TODO: Faye uses \r\n for newlines, some compatibility? result = "id: #{sse_event_id}\n" result << "event: #{options[:event]}\n" if options[:event] result << "retry: #{options[:retry]}\n" if options[:retry] data.split(/\n/).each {|d| result << "data: #{d}\n" } result << "\n" @body.call(result) end
render_websocket(body, *)
click to toggle source
# File lib/cramp/action.rb, line 100 def render_websocket(body, *) @web_socket.send(body) end
send_initial_response(status, headers, body)
click to toggle source
Calls superclass method
Cramp::Abstract#send_initial_response
# File lib/cramp/action.rb, line 33 def send_initial_response(status, headers, body) case transport when :long_polling # Dont send no initial response. Just cache it for later. @_lp_status = status @_lp_headers = headers when :sse super if @eventsource_detected # Reconstruct headers that were killed by faye server adapter: @body.call("HTTP/1.1 200 OK\r\n#{headers.map{|(k,v)| "#{k}: #{v.is_a?(Time) ? v.httpdate : v.to_s}"}.join("\r\n")}\r\n\r\n") end # send retry? @body.call("retry: #{ (@retry * 1000).floor }\r\n\r\n") else super end end
sse_event_id()
click to toggle source
Used by SSE
# File lib/cramp/action.rb, line 114 def sse_event_id @sse_event_id ||= Time.now.to_i end