module Qeweney::ResponseMethods

Constants

WEBSOCKET_GUID

Public Instance Methods

file_full_path(path, opts) click to toggle source
# File lib/qeweney/response.rb, line 121
def file_full_path(path, opts)
  if (base_path = opts[:base_path])
    File.join(opts[:base_path], path)
  else
    path
  end
end
redirect(url, status = Status::FOUND) click to toggle source
# File lib/qeweney/response.rb, line 49
def redirect(url, status = Status::FOUND)
  respond(nil, ':status' => status, 'Location' => url)
end
redirect_to_host(new_host, status = Status::FOUND) click to toggle source
# File lib/qeweney/response.rb, line 58
def redirect_to_host(new_host, status = Status::FOUND)
  secure_uri = "//#{new_host}#{uri}"
  redirect(secure_uri, status)
end
redirect_to_https(status = Status::MOVED_PERMANENTLY) click to toggle source
# File lib/qeweney/response.rb, line 53
def redirect_to_https(status = Status::MOVED_PERMANENTLY)
  secure_uri = "https://#{host}#{uri}"
  redirect(secure_uri, status)
end
respond_with_static_file(path, etag, last_modified, opts) click to toggle source
# File lib/qeweney/response.rb, line 85
def respond_with_static_file(path, etag, last_modified, opts)
  cache_headers = {
    'etag' => etag,
    'last-modified' => last_modified,
  }
  File.open(path, 'r') do |f|
    if opts[:headers]
      opts[:headers].merge!(cache_headers)
    else
      opts[:headers] = cache_headers
    end

    # accept_encoding should return encodings in client's order of preference
    accept_encoding.each do |encoding|
      case encoding
      when 'deflate'
        return serve_io_deflate(f, opts)
      when 'gzip'
        return serve_io_gzip(f, opts)
      end
    end
    serve_io(f, opts)
  end
end
serve_file(path, opts = {}) click to toggle source
# File lib/qeweney/response.rb, line 63
def serve_file(path, opts = {})
  full_path = file_full_path(path, opts)
  stat = File.stat(full_path)
  etag = StaticFileCaching.file_stat_to_etag(stat)
  last_modified = StaticFileCaching.file_stat_to_last_modified(stat)

  if validate_static_file_cache(etag, last_modified)
    return respond(nil, {
      ':status' => Status::NOT_MODIFIED,
      'etag' => etag
    })
  end

  mime_type = Qeweney::MimeTypes[File.extname(path)]
  opts[:stat] = stat
  (opts[:headers] ||= {})['Content-Type'] ||= mime_type if mime_type

  respond_with_static_file(full_path, etag, last_modified, opts)
rescue Errno::ENOENT => e
  respond(nil, ':status' => Status::NOT_FOUND)
end
serve_io(io, opts) click to toggle source
# File lib/qeweney/response.rb, line 129
def serve_io(io, opts)
  respond(io.read, opts[:headers] || {})
end
serve_io_deflate(io, opts) click to toggle source
# File lib/qeweney/response.rb, line 133
def serve_io_deflate(io, opts)
  deflate = Zlib::Deflate.new
  headers = opts[:headers].merge(
    'content-encoding' => 'deflate',
    'vary' => 'Accept-Encoding'
  )

  respond(deflate.deflate(io.read, Zlib::FINISH), headers)
end
serve_io_gzip(io, opts) click to toggle source
# File lib/qeweney/response.rb, line 143
def serve_io_gzip(io, opts)
  buf = StringIO.new
  z = Zlib::GzipWriter.new(buf)
  z << io.read
  z.flush
  z.close
  headers = opts[:headers].merge(
    'content-encoding' => 'gzip',
    'vary' => 'Accept-Encoding'
  )
  respond(buf.string, headers)
end
serve_rack(app) click to toggle source
# File lib/qeweney/response.rb, line 156
def serve_rack(app)
  response = app.(Qeweney.rack_env_from_request(self))
  headers = (response[1] || {}).merge(':status' => response[0])
  respond(response[2].join, headers)

  # TODO: send separate chunks for multi-part body
  # TODO: add support for streaming body
  # TODO: add support for websocket
end
upgrade(protocol, custom_headers = nil) click to toggle source
# File lib/qeweney/response.rb, line 25
def upgrade(protocol, custom_headers = nil)
  upgrade_headers = {
    ':status' => Status::SWITCHING_PROTOCOLS,
    'Upgrade' => protocol,
    'Connection' => 'upgrade'
  }
  upgrade_headers.merge!(custom_headers) if custom_headers

  respond(nil, upgrade_headers)
end
upgrade_to_websocket(custom_headers = nil) click to toggle source
# File lib/qeweney/response.rb, line 38
def upgrade_to_websocket(custom_headers = nil)
  key = "#{headers['sec-websocket-key']}#{WEBSOCKET_GUID}"
  upgrade_headers = {
    'Sec-WebSocket-Accept' => Digest::SHA1.base64digest(key)
  }
  upgrade_headers.merge!(custom_headers) if custom_headers
  upgrade('websocket', upgrade_headers)

  adapter.websocket_connection(self)
end
validate_static_file_cache(etag, last_modified) click to toggle source
# File lib/qeweney/response.rb, line 110
def validate_static_file_cache(etag, last_modified)
  if (none_match = headers['if-none-match'])
    return true if none_match == etag
  end
  if (modified_since = headers['if-modified-since'])
    return true if modified_since == last_modified
  end

  false
end