class Berkshelf::API::RESTGateway

Constants

CGI_1_1
CONNECTION
CONTENT_LENGTH
CONTENT_LENGTH_ORIG
CONTENT_TYPE
CONTENT_TYPE_ORIG
DEFAULT_OPTIONS
GATEWAY_INTERFACE
HOST
HTTP_
HTTP_1_0
HTTP_1_1
HTTP_VERSION
INITIAL_BODY
LOCALHOST
PATH_INFO
PROTO_RACK_ENV
QUERY_STRING
RACK_ERRORS
RACK_INPUT
RACK_LOGGER
RACK_MULTIPROCESS
RACK_MULTITHREAD
RACK_RUN_ONCE
RACK_URL_SCHEME
RACK_VERSION
RACK_WEBSOCKET
REMOTE_ADDR
REQUEST_METHOD
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE

Attributes

app[R]

@return [Berkshelf::API::RackApp]

host[R]

@return [String]

port[R]

@return [Integer]

workers[R]

@return [Integer]

Public Class Methods

new(options = {}) click to toggle source

@option options [String] :host ('0.0.0.0') @option options [Integer] :port (26200) @option options [Boolean] :quiet (false) @option options [Integer] :workers (10)

Calls superclass method
# File lib/berkshelf/api/rest_gateway.rb, line 83
def initialize(options = {})
  options = DEFAULT_OPTIONS.merge(options)
  @host   = options[:host]
  @port   = options[:port]

  log.info "REST Gateway listening on #{@host}:#{@port}"
  super(@host, @port, &method(:on_connect))
  @app = Berkshelf::API::RackApp.new
end

Public Instance Methods

on_connect(connection) click to toggle source
# File lib/berkshelf/api/rest_gateway.rb, line 93
def on_connect(connection)
  while request = connection.request
    case request
    when request.websocket?
      request.respond(:bad_request, "WebSockets not supported")
    else
      route_request(connection, request)
    end
  end
end
request_env(request, connection) click to toggle source
# File lib/berkshelf/api/rest_gateway.rb, line 113
def request_env(request, connection)
  env = env(request)
  env[REMOTE_ADDR] = connection.remote_ip
  env
end
route_request(connection, request) click to toggle source
# File lib/berkshelf/api/rest_gateway.rb, line 104
def route_request(connection, request)
  status, headers, body_parts = app.call(request_env(request, connection))
  body, is_stream             = response_body(body_parts)

  response_klass = is_stream ? Reel::StreamResponse : Reel::Response
  response       = response_klass.new(status, headers, body)
  connection.respond(response)
end

Private Instance Methods

env(request) click to toggle source
# File lib/berkshelf/api/rest_gateway.rb, line 121
def env(request)
  env = Hash[PROTO_RACK_ENV]

  env[RACK_INPUT] = StringIO.new(request.body.to_s || INITIAL_BODY)
  env[RACK_INPUT].set_encoding(Encoding::BINARY) if env[RACK_INPUT].respond_to?(:set_encoding)
  env[SERVER_NAME], env[SERVER_PORT] = (request[HOST]||'').split(':', 2)
  env[SERVER_PORT] ||= port.to_s
  env[HTTP_VERSION]   = request.version || env[SERVER_PROTOCOL]
  env[REQUEST_METHOD] = request.method
  env[PATH_INFO]      = request.path
  env[QUERY_STRING]   = request.query_string || ''

  (_ = request.headers.delete CONTENT_TYPE_ORIG) && (env[CONTENT_TYPE] = _)
  (_ = request.headers.delete CONTENT_LENGTH_ORIG) && (env[CONTENT_LENGTH] = _)

  request.headers.each_pair do |key, val|
    env[HTTP_ + key.gsub('-', '_').upcase] = val
  end
  env
end
response_body(body_parts) click to toggle source
# File lib/berkshelf/api/rest_gateway.rb, line 142
def response_body(body_parts)
  if body_parts.respond_to?(:to_path)
    ::File.new(body_parts.to_path)
  else
    body = ''
    body_parts.each do |c|
      return [c, true] if c.is_a?(Reel::Stream)
      body << c
    end
    body_parts.close if body_parts.respond_to?(:close)
    body
  end
end