lib/rack/amf/response.rb in rack-amf-0.0.2 vs lib/rack/amf/response.rb in rack-amf-0.0.3

- old
+ new

@@ -1,54 +1,78 @@ module Rack::AMF + # Rack specific wrapper around AMF::Response class Response attr_reader :raw_response + V = ::AMF::Values + def initialize request @request = request @raw_response = ::AMF::Response.new + @raw_response.amf_version = @request.version == 3 ? 3 : 0 # Can't just copy version because FMS sends version as 1 end # Builds response, iterating over each method call and using the return value # as the method call's return value + #-- + # Iterate over all the sent messages. If they're somthing we can handle, like + # a command message, then simply add the response message ourselves. If it's + # a method call, then call the block with the method and args, catching errors + # for handling. Then create the appropriate response message using the return + # value of the block as the return value for the method call. def each_method_call &block - @request.messages.each do |m| - target_uri = m.response_uri + raise 'Response already constructed' if @constructed - rd = m.data - if rd.is_a?(::AMF::Values::CommandMessage) - if rd.operation == ::AMF::Values::CommandMessage::CLIENT_PING_OPERATION - data = ::AMF::Values::AcknowledgeMessage.new(rd) + @request.messages.each do |m| + # What's the request body? + case m.data + when V::CommandMessage + # Pings should be responded to with an AcknowledgeMessage built using the ping + # Everything else is unsupported + command_msg = m.data + if command_msg.operation == V::CommandMessage::CLIENT_PING_OPERATION + response_value = V::AcknowledgeMessage.new(command_msg) else - data == ::AMF::Values::ErrorMessage.new(Exception.new("CommandMessage #{rd.operation} not implemented"), rd) + response_value = V::ErrorMessage.new(Exception.new("CommandMessage #{command_msg.operation} not implemented"), command_msg) end - elsif rd.is_a?(::AMF::Values::RemotingMessage) - am = ::AMF::Values::AcknowledgeMessage.new(rd) - body = dispatch_call(rd.source+'.'+rd.operation, rd.body, rd, block) - if body.is_a?(::AMF::Values::ErrorMessage) - data = body + when V::RemotingMessage + # Using RemoteObject style message calls + remoting_msg = m.data + acknowledge_msg = V::AcknowledgeMessage.new(remoting_msg) + body = dispatch_call :method => remoting_msg.source+'.'+remoting_msg.operation, :args => remoting_msg.body, :source => remoting_msg, :block => block + + # Response should be the bare ErrorMessage if there was an error + if body.is_a?(V::ErrorMessage) + response_value = body else - am.body = body - data = am + acknowledge_msg.body = body + response_value = acknowledge_msg end else - data = dispatch_call(m.target_uri, rd, m, block) + # Standard response message + response_value = dispatch_call :method => m.target_uri, :args => m.data, :source => m, :block => block end - target_uri += data.is_a?(::AMF::Values::ErrorMessage) ? '/onStatus' : '/onResult' - @raw_response.messages << ::AMF::Message.new(target_uri, '', data) + target_uri = m.response_uri + target_uri += response_value.is_a?(V::ErrorMessage) ? '/onStatus' : '/onResult' + @raw_response.messages << ::AMF::Message.new(target_uri, '', response_value) end + + @constructed = true end + # Return the serialized response as a string def to_s raw_response.serialize end private - def dispatch_call method, args, source_message, handler + def dispatch_call p begin - handler.call(method, args) + p[:block].call(p[:method], p[:args]) rescue Exception => e - ::AMF::Values::ErrorMessage.new(source_message, e) + # Create ErrorMessage object using the source message as the base + V::ErrorMessage.new(p[:source], e) end end end end \ No newline at end of file