2010-10-07 07:46:23 -07:00
|
|
|
module RocketAMF
|
|
|
|
class RemoteGateway
|
|
|
|
class Request
|
|
|
|
ERROR_CODE = 'AMFPHP_RUNTIME_ERROR'
|
|
|
|
|
|
|
|
def initialize(service, method, *params)
|
|
|
|
@service = service
|
|
|
|
@method = method
|
|
|
|
@params = params
|
|
|
|
end
|
|
|
|
|
|
|
|
def fetch
|
|
|
|
uri = @service.gateway.uri
|
|
|
|
data = envelope.serialize
|
2011-02-09 15:39:16 -08:00
|
|
|
# TODO: re-enable if we go back to using threads
|
|
|
|
if false && defined?(EventMachine) && EventMachine.respond_to?(:reactor_running?) && EventMachine.reactor_running?
|
2010-10-10 16:41:01 -07:00
|
|
|
req = EM::HttpRequest.new(uri).post :body => data
|
|
|
|
response_body = req.response
|
2010-10-07 07:46:23 -07:00
|
|
|
else
|
2010-10-10 16:41:01 -07:00
|
|
|
req = Net::HTTP::Post.new(uri.path)
|
|
|
|
req.body = data
|
|
|
|
res = Net::HTTP.new(uri.host, uri.port).start { |http| http.request(req) }
|
|
|
|
case res
|
|
|
|
when Net::HTTPSuccess
|
|
|
|
response_body = res.body
|
|
|
|
else
|
|
|
|
error = nil
|
|
|
|
begin
|
|
|
|
res.error!
|
|
|
|
rescue Exception => scoped_error
|
|
|
|
error = scoped_error
|
|
|
|
end
|
|
|
|
raise ConnectionError, "Error connecting to gateway: #{error}"
|
2010-10-07 07:46:23 -07:00
|
|
|
end
|
|
|
|
end
|
2010-10-10 16:41:01 -07:00
|
|
|
begin
|
|
|
|
result = RocketAMF::Envelope.new.populate_from_stream(response_body)
|
|
|
|
rescue Exception => e
|
|
|
|
raise ConnectionError, "Error parsing gateway response: #{e.message}"
|
|
|
|
end
|
|
|
|
first_message_data = result.messages[0].data
|
|
|
|
if first_message_data.respond_to?(:[]) && first_message_data[:code] == ERROR_CODE
|
|
|
|
raise AMFError.new(first_message_data)
|
|
|
|
end
|
|
|
|
result
|
2010-10-07 07:46:23 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def envelope
|
|
|
|
output = Envelope.new
|
|
|
|
output.messages << wrapper_message
|
|
|
|
output
|
|
|
|
end
|
|
|
|
|
|
|
|
def wrapper_message
|
|
|
|
message = Message.new 'null', '/1', [remoting_message]
|
|
|
|
end
|
|
|
|
|
|
|
|
def remoting_message
|
|
|
|
message = Values::RemotingMessage.new
|
|
|
|
message.source = @service.name
|
|
|
|
message.operation = @method
|
|
|
|
message.body = @params
|
|
|
|
message
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class ConnectionError < RuntimeError;end
|
|
|
|
class AMFError < RuntimeError
|
|
|
|
DATA_KEYS = [:details, :line, :code]
|
|
|
|
attr_reader *DATA_KEYS
|
|
|
|
attr_reader :message
|
|
|
|
|
|
|
|
def initialize(data)
|
|
|
|
DATA_KEYS.each do |key|
|
|
|
|
instance_variable_set "@#{key}", data[key]
|
|
|
|
end
|
|
|
|
|
|
|
|
@message = data[:description]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|