Class: Protobuf::Rpc::Http::Server
Constant Summary
collapse
- HTTP_STATUSES =
TODO: more comprehensive mapping?
{
Protobuf::Socketrpc::ErrorReason::BAD_REQUEST_DATA => 400,
Protobuf::Socketrpc::ErrorReason::BAD_REQUEST_PROTO => 400,
Protobuf::Socketrpc::ErrorReason::SERVICE_NOT_FOUND => 404,
Protobuf::Socketrpc::ErrorReason::METHOD_NOT_FOUND => 404,
Protobuf::Socketrpc::ErrorReason::RPC_ERROR => 500,
Protobuf::Socketrpc::ErrorReason::RPC_FAILED => 500,
Protobuf::Socketrpc::ErrorReason::INVALID_REQUEST_PROTO => 500,
Protobuf::Socketrpc::ErrorReason::BAD_RESPONSE_PROTO => 500,
Protobuf::Socketrpc::ErrorReason::UNKNOWN_HOST => 500,
Protobuf::Socketrpc::ErrorReason::IO_ERROR => 500
}
Instance Method Summary
collapse
included, #log_exception, #sign_message
Methods included from Server
#gc_pause, #handle_request
Constructor Details
#initialize(options = {}) ⇒ Server
Returns a new instance of Server.
27
28
29
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 27
def initialize(options = {})
@options = options
end
|
Instance Method Details
#call(env) ⇒ Object
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 35
def call(env)
path_components = env['PATH_INFO'].split("/").map{ |x| CGI::unescape(x) }.compact.reject{ |x| x.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)
rescue Exception => e
return protobuf_http_response 500,
:error => "Handle request failed: #{e.to_s}",
:reason => Protobuf::Socketrpc::ErrorReason::RPC_ERROR
end
rpc_response = Protobuf::Socketrpc::Response.decode(encoded_response)
if rpc_response[:error].length > 0
status = HTTP_STATUSES[rpc_response[:error_reason]] or 500
return protobuf_http_response status,
:error => rpc_response[:error],
:reason => rpc_response[:error_reason]
end
return protobuf_http_response 200, :body => rpc_response['response_proto']
end
|
#log_signature ⇒ Object
31
32
33
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 31
def log_signature
@_log_signature ||= "[http-server-#{self.class.name}]"
end
|
#protobuf_http_response(status, options) ⇒ Object
75
76
77
78
79
80
81
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 75
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 ⇒ Object
83
84
85
86
87
88
89
90
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 83
def run
Rack::Server.start(
:app => self,
:Host => @options[:host],
:Port => @options[:port]
)
@running = true
end
|
#running? ⇒ Boolean
92
93
94
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 92
def running?
!!@running
end
|
#stop ⇒ Object
96
97
|
# File 'lib/protobuf/rpc/servers/http/server.rb', line 96
def stop
end
|