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