class Protobuf::Rpc::Http::Server

Constants

HTTP_STATUSES

TODO: more comprehensive mapping?

Public Class Methods

new(options = {}) click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 30
def initialize(options = {})
  @options = options
end

Public Instance Methods

call(env) click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 38
def call(env)
  path_components = env['PATH_INFO'].split("/")
                                    .map { |x| CGI.unescape(x) }
                                    .compact.reject(&:empty?)
  if path_components.length < 2
    return protobuf_http_response 400,
                                  :error => "Expected path format /CLASS/METHOD",
                                  :reason => Protobuf::Socketrpc::ErrorReason::INVALID_REQUEST_PROTO
  end

  service_name = path_components[0..-2].join("::")
  method_name = path_components[-1]

  rpc_request = ::Protobuf::Socketrpc::Request.new(
    :service_name => service_name,
    :method_name => method_name,
    :request_proto => env['rack.input'].read,
    :caller => env['HTTP_X_PROTOBUF_CALLER'] || ''
  )

  encoded_request = rpc_request.encode

  begin
    encoded_response = handle_request(encoded_request, env)
  rescue StandardError => e
    return protobuf_http_response 500,
                                  :error => "Handle request failed: #{e}",
                                  :reason => Protobuf::Socketrpc::ErrorReason::RPC_ERROR
  end

  rpc_response = Protobuf::Socketrpc::Response.decode(encoded_response)

  if rpc_response[:error].present?
    status = HTTP_STATUSES[rpc_response[:error_reason]] || 500
    return protobuf_http_response status,
                                  :error => rpc_response[:error],
                                  :reason => rpc_response[:error_reason]
  end

  protobuf_http_response 200, :body => rpc_response['response_proto']
end
log_signature() click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 34
def log_signature
  @_log_signature ||= "[http-server-#{self.class.name}]"
end
protobuf_http_response(status, options) click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 80
def protobuf_http_response(status, options)
  response = [status, { 'Content-Type' => 'application/x-protobuf' }, []]
  response[1]['X-Protobuf-Error'] = options[:error] unless options[:error].nil?
  response[1]['X-Protobuf-Error-Reason'] = options[:reason].to_s unless options[:reason].nil?
  response[2] = [options[:body]] unless options[:body].nil?
  response
end
run() click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 88
def run
  Rack::Server.start(
    :app => self,
    :Host => @options[:host],
    :Port => @options[:port]
  )
  @running = true
end
running?() click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 97
def running?
  !!@running # rubocop:disable Style/DoubleNegation
end
stop() click to toggle source
# File lib/protobuf/rpc/servers/http/server.rb, line 101
def stop
end