class Restfulness::Response

Attributes

headers[R]

Outgoing data

payload[R]

Outgoing data

request[R]

Incoming data

resource[R]

The generated resource object

status[R]

Outgoing data

Public Class Methods

new(request) click to toggle source
# File lib/restfulness/response.rb, line 16
def initialize(request)
  @request = request
  @headers = {}
end

Public Instance Methods

content_length() click to toggle source
# File lib/restfulness/response.rb, line 51
def content_length
  payload.to_s.bytesize.to_s
end
run() click to toggle source
# File lib/restfulness/response.rb, line 21
def run
  @log_begin_at = Time.now
  route = request.route
  if route
    self.resource = route.build_resource(request, self)

    # run callbacks, if any fail, they'll raise an error
    resource.check_callbacks

    # Perform the actual work
    result = resource.call

    update_status_and_payload(result.nil? ? 204 : 200, result)
  else
    update_status_and_payload(404)
  end

rescue HTTPException => e # Deal with HTTP exceptions
  headers.update(e.headers)
  update_status_and_payload(e.status, e.payload)

rescue StandardError, LoadError, SyntaxError => e
  # Useful coding error handling, with backtrace
  log_exception(e)
  update_status_and_payload(500, e.message + "\n")

ensure
  log! if status
end
status=(code) click to toggle source

Override the status of this response.

# File lib/restfulness/response.rb, line 56
def status=(code)
  @status = code.to_i
end

Protected Instance Methods

content_type_from_accept_header() click to toggle source
# File lib/restfulness/response.rb, line 90
def content_type_from_accept_header
  accept = self.request.accept
  if accept
    if accept.json?
      :json
    elsif accept.xml?
      :xml
    elsif accept.text?
      :text
    end
  else
    nil
  end
end
log!() click to toggle source
# File lib/restfulness/response.rb, line 119
def log!
  dur = @log_begin_at ? Time.now - @log_begin_at : 0.0
  uri = request.uri

  resource_name = resource ? resource.class.to_s : 'Error'
  # We're only interested in parsed parameters.
  params = request.sanitized_params

  msg = %{%s "%s %s%s" %s %d %s %s %0.4fs %s} % [
    request.remote_ip,
    request.action.to_s.upcase,
    uri.path,
    uri.query ? "?#{request.sanitized_query_string}" : '',
    resource_name,
    status.to_s[0..3],
    STATUSES[status],
    content_length,
    dur,
    params ? params.inspect : ''
  ]
  Restfulness.logger.info(msg)
end
log_exception(e) click to toggle source
# File lib/restfulness/response.rb, line 142
def log_exception(e)
  string = "#{e.class}: #{e.message}\n"
  string << e.backtrace.map { |l| "\t#{l}" }.join("\n")
  Restfulness.logger.error(string)
end
payload=(body) click to toggle source
# File lib/restfulness/response.rb, line 71
def payload=(body)
  type = content_type_from_accept_header
  if body.nil?
    @payload = ""
  elsif body.is_a?(String)
    # Implies that the body was already prepared, and we should rely on accept headers or assume text
    @payload = body
    update_content_headers(type || :text) unless @payload.empty?
  elsif type && type == :xml
    # Try to use a #to_xml if available, or just use to_s.
    @payload = (body.respond_to?(:to_xml) ? body.to_xml : body).to_s
    update_content_headers(:xml) unless @payload.empty?
  else
    # DEFAULT: Assume we want JSON
    @payload = MultiJson.encode(body)
    update_content_headers(:json) unless @payload.empty?
  end
end
resource=(obj) click to toggle source
# File lib/restfulness/response.rb, line 62
def resource=(obj)
  @resource = obj
end
update_content_headers(type = :json) click to toggle source
# File lib/restfulness/response.rb, line 105
def update_content_headers(type = :json)
  if headers['Content-Type'].to_s.empty?
    case type
    when :json
      headers['Content-Type'] = 'application/json; charset=utf-8'
    when :xml
      headers['Content-Type'] = 'application/xml; charset=utf-8'
    else # Assume text
      headers['Content-Type'] = 'text/plain; charset=utf-8'
    end
  end
  headers['Content-Length'] = content_length
end
update_status_and_payload(status, payload = "") click to toggle source
# File lib/restfulness/response.rb, line 66
def update_status_and_payload(status, payload = "")
  self.status  = status unless self.status.present?
  self.payload = payload
end