示例#1
0
		public override void Invoke(AMFContext context)
		{
			AMFMessage amfMessage = context.AMFMessage;
			AMFHeader amfHeader = amfMessage.GetHeader( AMFHeader.DebugHeader );
			if( amfHeader != null )
			{
				//The value of the header
				ASObject asObject = amfHeader.Content as ASObject;
				//["error"]: {true}
				//["trace"]: {true}
				//["httpheaders"]: {false}
				//["coldfusion"]: {true}
				//["amf"]: {false}
				//["m_debug"]: {true}
				//["amfheaders"]: {false}
				//["recordset"]: {true}

				AMFBody amfBody = amfMessage.GetBodyAt(amfMessage.BodyCount-1);//last body
				ResponseBody amfBodyOut = new ResponseBody();
				amfBodyOut.Target = amfBody.Response + AMFBody.OnDebugEvents;
				amfBodyOut.Response = null;
				amfBodyOut.IsDebug = true;

				ArrayList headerResults = new ArrayList();
				ArrayList result = new ArrayList();
				headerResults.Add( result );
				

				if( (bool)asObject["httpheaders"] == true ) 
				{ 
					//If the client wants http headers
					result.Add( new HttpHeader( ) );
				} 
				if( (bool)asObject["amfheaders"] == true ) 
				{
					result.Add( new AMFRequestHeaders( amfMessage ) );
				}

				ArrayList traceStack = NetDebug.GetTraceStack();
				if( (bool)asObject["trace"] == true  && traceStack != null && traceStack.Count > 0 )
				{
					ArrayList tmp = new ArrayList( traceStack );
					result.Add( new TraceHeader( tmp ) );
					NetDebug.Clear();
				}

				//http://osflash.org/amf/envelopes/remoting/debuginfo

				amfBodyOut.Content = headerResults;
				context.MessageOutput.AddBody(amfBodyOut);
			}
			NetDebug.Clear();
		}
示例#2
0
		public override void Invoke(AMFContext context)
		{
			MessageOutput messageOutput = context.MessageOutput;
			for(int i = 0; i < context.AMFMessage.BodyCount; i++)
			{
				AMFBody amfBody = context.AMFMessage.GetBodyAt(i);
				ResponseBody responseBody = null;
				//Check for Flex2 messages and skip
				if( amfBody.IsEmptyTarget )
					continue;

				if( amfBody.IsDebug )
					continue;
				if( amfBody.IsDescribeService )
				{
					responseBody = new ResponseBody();
					responseBody.IgnoreResults = amfBody.IgnoreResults;
                    responseBody.Target = amfBody.Response + AMFBody.OnResult;
					responseBody.Response = null;
					DescribeService describeService = new DescribeService( amfBody );
					responseBody.Content = describeService.GetDescription();
					messageOutput.AddBody(responseBody);
					continue;
				}

				//Check if response exists.
				responseBody = messageOutput.GetResponse(amfBody);
				if( responseBody != null )
				{
					continue;
				}

				try
				{
				    MessageBroker messageBroker = _endpoint.GetMessageBroker();
                    RemotingService remotingService = messageBroker.GetService(RemotingService.RemotingServiceId) as RemotingService;
                    if (remotingService == null)
                    {
                        string serviceNotFound = __Res.GetString(__Res.Service_NotFound, RemotingService.RemotingServiceId);
                        responseBody = new ErrorResponseBody(amfBody, new FluorineException(serviceNotFound));
                        messageOutput.AddBody(responseBody);
                        if (log.IsErrorEnabled)
                            log.Error(serviceNotFound);
                        continue;
                    }
                    Destination destination = null;
                    if (destination == null)
                        destination = remotingService.GetDestinationWithSource(amfBody.TypeName);
                    if (destination == null)
                        destination = remotingService.DefaultDestination;
                    //At this moment we got a destination with the exact source or we have a default destination with the "*" source.
                    if (destination == null)
                    {
                        string destinationNotFound = __Res.GetString(__Res.Destination_NotFound, amfBody.TypeName);
                        responseBody = new ErrorResponseBody(amfBody, new FluorineException(destinationNotFound));
                        messageOutput.AddBody(responseBody);
                        if (log.IsErrorEnabled)
                            log.Error(destinationNotFound);
                        continue;
                    }

                    try
                    {
                        remotingService.CheckSecurity(destination);
                    }
                    catch (UnauthorizedAccessException exception)
                    {
                        responseBody = new ErrorResponseBody(amfBody, exception);
                        if (log.IsDebugEnabled)
                            log.Debug(exception.Message);
                        continue;
                    }

                    //Cache check
                    string source = amfBody.TypeName + "." + amfBody.Method;
                    IList parameterList = amfBody.GetParameterList();
                    string key = FluorineFx.Configuration.CacheMap.GenerateCacheKey(source, parameterList);
                    if (FluorineConfiguration.Instance.CacheMap.ContainsValue(key))
                    {
                        object result = FluorineFx.Configuration.FluorineConfiguration.Instance.CacheMap.Get(key);
                        if (result != null)
                        {
                            if (log != null && log.IsDebugEnabled)
                                log.Debug(__Res.GetString(__Res.Cache_HitKey, source, key));
                            responseBody = new ResponseBody(amfBody, result);
                            messageOutput.AddBody(responseBody);
                            continue;
                        }
                    }

				    FactoryInstance factoryInstance = destination.GetFactoryInstance();
				    factoryInstance.Source = amfBody.TypeName;
				    if( FluorineContext.Current.ActivationMode != null )//query string can override the activation mode
					    factoryInstance.Scope = FluorineContext.Current.ActivationMode;
				    object instance = factoryInstance.Lookup();

				    if( instance != null )
                    {
                        try
                        {
                            bool isAccessible = TypeHelper.GetTypeIsAccessible(instance.GetType());
                            if (!isAccessible)
                            {
                                string msg = __Res.GetString(__Res.Type_InitError, amfBody.TypeName);
                                if (log.IsErrorEnabled)
                                    log.Error(msg);
                                responseBody = new ErrorResponseBody(amfBody, new FluorineException(msg));
                                messageOutput.AddBody(responseBody);
                                continue;
                            }

                            MethodInfo mi = null;
                            if (!amfBody.IsRecordsetDelivery)
                            {
                                mi = MethodHandler.GetMethod(instance.GetType(), amfBody.Method, amfBody.GetParameterList());
                            }
                            else
                            {
                                //will receive recordsetid only (ignore)
                                mi = instance.GetType().GetMethod(amfBody.Method);
                            }
                            if (mi != null)
                            {
                                object[] roleAttributes = mi.GetCustomAttributes(typeof(RoleAttribute), true);
                                if (roleAttributes != null && roleAttributes.Length == 1)
                                {
                                    RoleAttribute roleAttribute = roleAttributes[0] as RoleAttribute;
                                    string[] roles = roleAttribute.Roles.Split(',');

                                    bool authorized = messageBroker.LoginManager.DoAuthorization(roles);
                                    if (!authorized)
                                        throw new UnauthorizedAccessException(__Res.GetString(__Res.Security_AccessNotAllowed));
                                }

                                #region Invocation handling
                                PageSizeAttribute pageSizeAttribute = null;
                                MethodInfo miCounter = null;
                                object[] pageSizeAttributes = mi.GetCustomAttributes(typeof(PageSizeAttribute), true);
                                if (pageSizeAttributes != null && pageSizeAttributes.Length == 1)
                                {
                                    pageSizeAttribute = pageSizeAttributes[0] as PageSizeAttribute;
                                    miCounter = instance.GetType().GetMethod(amfBody.Method + "Count");
                                    if (miCounter != null && miCounter.ReturnType != typeof(System.Int32))
                                        miCounter = null; //check signature
                                }
                                ParameterInfo[] parameterInfos = mi.GetParameters();
                                //Try to handle missing/optional parameters.
                                object[] args = new object[parameterInfos.Length];
                                if (!amfBody.IsRecordsetDelivery)
                                {
                                    if (args.Length != parameterList.Count)
                                    {
                                        string msg = __Res.GetString(__Res.Arg_Mismatch, parameterList.Count, mi.Name, args.Length);
                                        if (log != null && log.IsErrorEnabled)
                                            log.Error(msg);
                                        responseBody = new ErrorResponseBody(amfBody, new ArgumentException(msg));
                                        messageOutput.AddBody(responseBody);
                                        continue;
                                    }
                                    parameterList.CopyTo(args, 0);
                                    if (pageSizeAttribute != null)
                                    {
                                        PagingContext pagingContext = new PagingContext(pageSizeAttribute.Offset, pageSizeAttribute.Limit);
                                        PagingContext.SetPagingContext(pagingContext);
                                    }
                                }
                                else
                                {
                                    if (amfBody.Target.EndsWith(".release"))
                                    {
                                        responseBody = new ResponseBody(amfBody, null);
                                        messageOutput.AddBody(responseBody);
                                        continue;
                                    }
                                    string recordsetId = parameterList[0] as string;
                                    string recordetDeliveryParameters = amfBody.GetRecordsetArgs();
                                    byte[] buffer = System.Convert.FromBase64String(recordetDeliveryParameters);
                                    recordetDeliveryParameters = System.Text.Encoding.UTF8.GetString(buffer);
                                    if (recordetDeliveryParameters != null && recordetDeliveryParameters != string.Empty)
                                    {
                                        string[] stringParameters = recordetDeliveryParameters.Split(new char[] { ',' });
                                        for (int j = 0; j < stringParameters.Length; j++)
                                        {
                                            if (stringParameters[j] == string.Empty)
                                                args[j] = null;
                                            else
                                                args[j] = stringParameters[j];
                                        }
                                        //TypeHelper.NarrowValues(argsStore, parameterInfos);
                                    }
                                    PagingContext pagingContext = new PagingContext(System.Convert.ToInt32(parameterList[1]), System.Convert.ToInt32(parameterList[2]));
                                    PagingContext.SetPagingContext(pagingContext);
                                }

                                TypeHelper.NarrowValues(args, parameterInfos);

                                try
                                {
                                    InvocationHandler invocationHandler = new InvocationHandler(mi);
                                    object result = invocationHandler.Invoke(instance, args);

                                    if (FluorineConfiguration.Instance.CacheMap != null && FluorineConfiguration.Instance.CacheMap.ContainsCacheDescriptor(source))
                                    {
                                        //The result should be cached
                                        CacheableObject cacheableObject = new CacheableObject(source, key, result);
                                        FluorineConfiguration.Instance.CacheMap.Add(cacheableObject.Source, cacheableObject.CacheKey, cacheableObject);
                                        result = cacheableObject;
                                    }
                                    responseBody = new ResponseBody(amfBody, result);

                                    if (pageSizeAttribute != null)
                                    {
                                        int totalCount = 0;
                                        string recordsetId = null;

                                        IList list = amfBody.GetParameterList();
                                        string recordetDeliveryParameters = null;
                                        if (!amfBody.IsRecordsetDelivery)
                                        {
                                            //fist call paging
                                            object[] argsStore = new object[list.Count];
                                            list.CopyTo(argsStore, 0);
                                            recordsetId = System.Guid.NewGuid().ToString();
                                            if (miCounter != null)
                                            {
                                                //object[] counterArgs = new object[0];
                                                totalCount = (int)miCounter.Invoke(instance, args);
                                            }
                                            string[] stringParameters = new string[argsStore.Length];
                                            for (int j = 0; j < argsStore.Length; j++)
                                            {
                                                if (argsStore[j] != null)
                                                    stringParameters[j] = argsStore[j].ToString();
                                                else
                                                    stringParameters[j] = string.Empty;
                                            }
                                            recordetDeliveryParameters = string.Join(",", stringParameters);
                                            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(recordetDeliveryParameters);
                                            recordetDeliveryParameters = System.Convert.ToBase64String(buffer);
                                        }
                                        else
                                        {
                                            recordsetId = amfBody.GetParameterList()[0] as string;
                                        }
                                        if (result is DataTable)
                                        {
                                            DataTable dataTable = result as DataTable;
                                            dataTable.ExtendedProperties["TotalCount"] = totalCount;
                                            dataTable.ExtendedProperties["Service"] = recordetDeliveryParameters + "/" + amfBody.Target;
                                            dataTable.ExtendedProperties["RecordsetId"] = recordsetId;
                                            if (amfBody.IsRecordsetDelivery)
                                            {
                                                dataTable.ExtendedProperties["Cursor"] = Convert.ToInt32(list[list.Count - 2]);
                                                dataTable.ExtendedProperties["DynamicPage"] = true;
                                            }
                                        }
                                    }
                                }
                                catch (UnauthorizedAccessException exception)
                                {
                                    responseBody = new ErrorResponseBody(amfBody, exception);
                                    if (log.IsDebugEnabled)
                                        log.Debug(exception.Message);
                                }
                                catch (Exception exception)
                                {
                                    if (exception is TargetInvocationException && exception.InnerException != null)
                                        responseBody = new ErrorResponseBody(amfBody, exception.InnerException);
                                    else
                                        responseBody = new ErrorResponseBody(amfBody, exception);
                                    if (log.IsDebugEnabled)
                                        log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, exception.Message));
                                }
                                #endregion Invocation handling
                            }
                            else
                                responseBody = new ErrorResponseBody(amfBody, new MissingMethodException(amfBody.TypeName, amfBody.Method));
                        }
                        finally
                        {
                            factoryInstance.OnOperationComplete(instance);
                        }
                    }
                    else
                        responseBody = new ErrorResponseBody(amfBody, new TypeInitializationException(amfBody.TypeName, null));
                }
			    catch(Exception exception)
			    {
					if( log != null && log.IsErrorEnabled )
                        log.Error(exception.Message, exception);
				    responseBody = new ErrorResponseBody(amfBody, exception);
			    }
				messageOutput.AddBody(responseBody);
			}
		}
		public override void Invoke(AMFContext context)
		{
			MessageOutput messageOutput = context.MessageOutput;
			for(int i = 0; i < context.AMFMessage.BodyCount; i++)
			{
				AMFBody amfBody = context.AMFMessage.GetBodyAt(i);

				if( !amfBody.IsEmptyTarget )
					continue;

				object content = amfBody.Content;
				if( content is IList )
					content = (content as IList)[0];
				IMessage message = content as IMessage;

				//Check for Flex2 messages and handle
				if( message != null )
				{
                    //if (FluorineContext.Current.Client == null)
                    //    FluorineContext.Current.SetCurrentClient(_endpoint.GetMessageBroker().ClientRegistry.GetClient(message));

					if(message.clientId == null)
						message.clientId = Guid.NewGuid().ToString("D");

					//Check if response exists.
					ResponseBody responseBody = messageOutput.GetResponse(amfBody);
					if( responseBody != null )
					{
						continue;
					}

					try
					{
                        if (context.AMFMessage.BodyCount > 1)
                        {
                            CommandMessage commandMessage = message as CommandMessage;
                            //Suppress poll wait if there are more messages to process
                            if (commandMessage != null && commandMessage.operation == CommandMessage.PollOperation )
                                commandMessage.SetHeader(CommandMessage.FluorineSuppressPollWaitHeader, null);
                        }
						IMessage resultMessage = _endpoint.ServiceMessage(message);
						if (resultMessage is ErrorMessage)
						{
							ErrorMessage errorMessage = resultMessage as ErrorMessage;
							responseBody = new ErrorResponseBody(amfBody, message, resultMessage as ErrorMessage);
                            if (errorMessage.faultCode == ErrorMessage.ClientAuthenticationError)
							{
								messageOutput.AddBody(responseBody);
								for (int j = i + 1; j < context.AMFMessage.BodyCount; j++)
								{
									amfBody = context.AMFMessage.GetBodyAt(j);

									if (!amfBody.IsEmptyTarget)
										continue;

									content = amfBody.Content;
									if (content is IList)
										content = (content as IList)[0];
									message = content as IMessage;

									//Check for Flex2 messages and handle
									if (message != null)
									{
										responseBody = new ErrorResponseBody(amfBody, message, new SecurityException(errorMessage.faultString));
										messageOutput.AddBody(responseBody);
									}
								}
								//Leave further processing
								return;
							}
						}
						else
						{
							responseBody = new ResponseBody(amfBody, resultMessage);
						}
					}
					catch(Exception exception)
					{
						if( log != null && log.IsErrorEnabled )
							log.Error(exception.Message, exception);
						responseBody = new ErrorResponseBody(amfBody, message, exception);
					}
					messageOutput.AddBody(responseBody);
				}
			}
		}
        object ProcessMessage(AMFMessage amfMessage)
        {
            // Apply AMF-based operation selector
            /*
            Dictionary<string, string> operationNameDictionary = new Dictionary<string, string>();
            foreach (OperationDescription operation in _endpoint.Contract.Operations)
            {
                try
                {
                    operationNameDictionary.Add(operation.Name.ToLower(), operation.Name);
                }
                catch (ArgumentException)
                {
                    throw new Exception(String.Format("The specified contract cannot be used with case insensitive URI dispatch because there is more than one operation named {0}", operation.Name));
                }
            }
            */

            //SessionMode, CallbackContract, ProtectionLevel

            AMFMessage output = new AMFMessage(amfMessage.Version);
            for (int i = 0; i < amfMessage.BodyCount; i++)
            {
                AMFBody amfBody = amfMessage.GetBodyAt(i);
                object content = amfBody.Content;
                if (content is IList)
                    content = (content as IList)[0];
                IMessage message = content as IMessage;
                if (message != null)
                {
                    //WCF should not assign client id for Flex...
                    if (message.clientId == null)
                        message.clientId = Guid.NewGuid().ToString("D");

                    //IMessage resultMessage = _endpoint.ServiceMessage(message);
                    IMessage responseMessage = null;
                    CommandMessage commandMessage = message as CommandMessage;
                    if (commandMessage != null && commandMessage.operation == CommandMessage.ClientPingOperation)
                    {
                        responseMessage = new AcknowledgeMessage();
                        responseMessage.body = true;
                    }
                    else
                    {
                        RemotingMessage remotingMessage = message as RemotingMessage;
                        string operation = remotingMessage.operation;
                        //TODO: you could use an alias for a contract to expose a different name to the clients in the metadata using the Name property of the ServiceContract attribute
                        string source = remotingMessage.source;
                        Type serviceType = TypeHelper.Locate(source);
                        Type contractInterface = serviceType.GetInterface(_endpoint.Contract.ContractType.FullName);
                        //WCF also lets you apply the ServiceContract attribute directly on the service class. Avoid using it.
                        //ServiceContractAttribute serviceContractAttribute = ReflectionUtils.GetAttribute(typeof(ServiceContractAttribute), type, true) as ServiceContractAttribute;
                        if (contractInterface != null)
                        {
                            object instance = Activator.CreateInstance(serviceType);
                            IList parameterList = remotingMessage.body as IList;
                            MethodInfo mi = MethodHandler.GetMethod(contractInterface, operation, parameterList, false, false);
                            //MethodInfo mi = MethodHandler.GetMethod(serviceType, operation, parameterList, false, false);
                            if (mi != null)
                            {
                                //TODO OperationContract attribute to alias it to a different publicly exposed name
                                OperationContractAttribute operationContractAttribute = ReflectionUtils.GetAttribute(typeof(OperationContractAttribute), mi, true) as OperationContractAttribute;
                                if (operationContractAttribute != null)
                                {
                                    //mi = MethodHandler.GetMethod(serviceType, operation, parameterList, false, false);
                                    ParameterInfo[] parameterInfos = mi.GetParameters();
                                    object[] args = new object[parameterInfos.Length];
                                    parameterList.CopyTo(args, 0);
                                    TypeHelper.NarrowValues(args, parameterInfos);
                                    object result = mi.Invoke(instance, args);
                                    if (!(result is IMessage))
                                    {
                                        responseMessage = new AcknowledgeMessage();
                                        responseMessage.body = result;
                                    }
                                    else
                                        responseMessage = result as IMessage;
                                }
                                else
                                    responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException("Method in not part of an service contract"));
                            }
                            else
                                responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException("Method in not part of an service contract"));
                        }
                        else
                            responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException(String.Format("The specified contract {0} cannot be used with the source named {1} and operation named {2}", _endpoint.Contract.ContractType.Name, source, operation)));
                    }

                    if (responseMessage is AsyncMessage)
                    {
                        ((AsyncMessage)responseMessage).correlationId = message.messageId;
                    }
                    responseMessage.destination = message.destination;
                    responseMessage.clientId = message.clientId;

                    ResponseBody responseBody = new ResponseBody(amfBody, responseMessage);
                    output.AddBody(responseBody);
                }
            }
            return output;
        }
示例#5
0
        /// <summary>
        /// This method supports the Fluorine infrastructure and is not intended to be used directly from your code.
        /// </summary>
        /// <param name="amfMessage"></param>

        public void WriteMessage(AMFMessage amfMessage)
        {
            try
            {
                base.WriteShort(amfMessage.Version);
                int headerCount = amfMessage.HeaderCount;
                base.WriteShort(headerCount);
                for (int i = 0; i < headerCount; i++)
                {
                    this.WriteHeader(amfMessage.GetHeaderAt(i), ObjectEncoding.AMF0);
                }
                int bodyCount = amfMessage.BodyCount;
                base.WriteShort(bodyCount);
                for (int i = 0; i < bodyCount; i++)
                {
                    ResponseBody responseBody = amfMessage.GetBodyAt(i) as ResponseBody;
                    if (responseBody != null && !responseBody.IgnoreResults)
                    {
                        //Try to catch serialization errors
                        if (this.BaseStream.CanSeek)
                        {
                            long position = this.BaseStream.Position;

                            try
                            {
                                responseBody.WriteBody(amfMessage.ObjectEncoding, this);
                            }
                            catch (Exception exception)
                            {
                                this.BaseStream.Seek(position, SeekOrigin.Begin);
                                //this.BaseStream.Position = position;

#if !SILVERLIGHT
                                if (log.IsFatalEnabled)
                                {
                                    log.Fatal(__Res.GetString(__Res.Amf_SerializationFail), exception);
                                }
#endif

                                ErrorResponseBody errorResponseBody;
                                if (responseBody.RequestBody.IsEmptyTarget)
                                {
                                    object content = responseBody.RequestBody.Content;
                                    if (content is IList)
                                    {
                                        content = (content as IList)[0];
                                    }
                                    IMessage         message          = content as IMessage;
                                    MessageException messageException = new MessageException(exception);
                                    messageException.FaultCode = __Res.GetString(__Res.Amf_SerializationFail);
                                    errorResponseBody          = new ErrorResponseBody(responseBody.RequestBody, message, messageException);
                                }
                                else
                                {
                                    errorResponseBody = new ErrorResponseBody(responseBody.RequestBody, exception);
                                }

                                try
                                {
                                    errorResponseBody.WriteBody(amfMessage.ObjectEncoding, this);
                                }
#if !SILVERLIGHT
                                catch (Exception exception2)
                                {
                                    if (log.IsFatalEnabled)
                                    {
                                        log.Fatal(__Res.GetString(__Res.Amf_ResponseFail), exception2);
                                    }
                                    throw;
                                }
#else
                                catch (Exception)
                                {
                                    throw;
                                }
#endif
                            }
                        }
                        else
                        {
                            responseBody.WriteBody(amfMessage.ObjectEncoding, this);
                        }
                    }
                    else
                    {
                        AMFBody amfBody = amfMessage.GetBodyAt(i);
                        FluorineFx.Util.ValidationUtils.ObjectNotNull(amfBody, "amfBody");
                        amfBody.WriteBody(amfMessage.ObjectEncoding, this);
                    }
                }
            }
#if !SILVERLIGHT
            catch (Exception exception)
            {
                if (log.IsFatalEnabled)
                {
                    log.Fatal(__Res.GetString(__Res.Amf_SerializationFail), exception);
                }
                throw;
            }
#else
            catch (Exception)
            {
                throw;
            }
#endif
        }