Class | RubyAMF::Rails::RequestProcessor |
In: |
lib/rubyamf/rails/request_processor.rb
|
Parent: | Object |
Rack middleware that handles dispatching AMF calls to the appropriate controller and action.
Processes the AMF request and forwards the method calls to the corresponding rails controllers. No middleware beyond the request processor will receive anything if the request is a handleable AMF request.
# File lib/rubyamf/rails/request_processor.rb, line 12 12: def call env 13: return @app.call(env) unless env['rubyamf.response'] 14: 15: # Handle each method call 16: req = env['rubyamf.request'] 17: res = env['rubyamf.response'] 18: res.each_method_call req do |method, args| 19: handle_method method, args, env 20: end 21: end
Validate the controller and method name and return the controller class
# File lib/rubyamf/rails/request_processor.rb, line 63 63: def get_service controller_name, method_name 64: # Check controller and validate against hacking attempts 65: begin 66: controller_name += "Controller" unless controller_name =~ /^.+Controller$/ 67: controller = controller_name.constantize 68: raise "not controller" unless controller.respond_to?(:controller_name) && controller.respond_to?(:action_methods) 69: rescue Exception => e 70: raise "Service #{controller_name} does not exist" 71: end 72: 73: # Check action 74: unless controller.action_methods.include?(method_name) 75: raise "Service #{controller_name} does not respond to #{method_name}" 76: end 77: 78: return controller 79: end
Actually dispatch a fake request to the appropriate controller and extract the response for serialization
# File lib/rubyamf/rails/request_processor.rb, line 25 25: def handle_method method, args, env 26: # Parse method and load service 27: path = method.split('.') 28: method_name = path.pop 29: controller_name = path.pop 30: controller = get_service controller_name, method_name 31: 32: # Setup request and controller 33: new_env = env.dup 34: new_env['HTTP_ACCEPT'] = RubyAMF::MIME_TYPE # Force amf response only 35: req = ActionController::Request.new(new_env) 36: con = controller.new 37: 38: # Populate with AMF data 39: amf_req = env['rubyamf.request'] 40: params_hash = amf_req.params_hash(controller.name, method_name, args) 41: req.params.merge!(params_hash) if RubyAMF.configuration.populate_params_hash 42: con.instance_variable_set("@is_amf", true) 43: con.instance_variable_set("@rubyamf_params", params_hash) 44: con.instance_variable_set("@credentials", amf_req.credentials) 45: 46: # Dispatch the request to the controller 47: rails_version = ::Rails::VERSION::MAJOR 48: if rails_version == 3 49: res = con.dispatch(method_name, req) 50: else # Rails 2 51: req.params['controller'] = controller.controller_name 52: req.params['action'] = method_name 53: con.process(req, ActionController::Response.new) 54: end 55: 56: # Copy mapping scope over to response so it can be used when serialized 57: env['rubyamf.response'].mapping_scope = con.send(:mapping_scope) 58: 59: return con.send(:amf_response) 60: end