Пример #1
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 {
         WriteShort(amfMessage.Version);
         var headerCount = amfMessage.HeaderCount;
         WriteShort(headerCount);
         for (var i = 0; i < headerCount; i++) {
             WriteHeader(amfMessage.GetHeaderAt(i), ObjectEncoding.AMF0);
         }
         var bodyCount = amfMessage.BodyCount;
         WriteShort(bodyCount);
         for (var i = 0; i < bodyCount; i++) {
             var responseBody = amfMessage.GetBodyAt(i) as ResponseBody;
             if (responseBody != null && !responseBody.IgnoreResults) {
                 responseBody.WriteBody(amfMessage.ObjectEncoding, this);
             } else {
                 var amfBody = amfMessage.GetBodyAt(i);
                 ValidationUtils.ObjectNotNull(amfBody, "amfBody");
                 amfBody.WriteBody(amfMessage.ObjectEncoding, this);
             }
         }
     } catch (Exception exception) {
         if (Log.IsFatalEnabled)
             Log.Fatal(String.Format(Resources.Amf_SerializationFail), exception);
         throw;
     }
 }
Пример #2
0
		public AMFRequestHeaders(AMFMessage amfMessage)
		{
			this["EventType"] = "AmfHeaders";
			Hashtable hashtable = new Hashtable();
			for(int i = 0; i < amfMessage.HeaderCount; i++)
			{
				AMFHeader amfHeader = amfMessage.GetHeaderAt(i);
				if( amfHeader != null && amfHeader.Name != null )
					hashtable[amfHeader.Name] = amfHeader.Content;
			}
			this["AmfHeaders"] = hashtable;
		}
Пример #3
0
        public byte[] LoadAmfMessageIntoBinMessage(AMFMessage message)
        {
            byte[] buffer = null;
            MemoryStream stream = new MemoryStream();

            AMFSerializer amfSerializers = new AMFSerializer(stream);
            amfSerializers.WriteMessage(message);
            amfSerializers.Flush();
            buffer = new byte[amfSerializers.BaseStream.Length];
            stream.Position = 0;
            stream.Read(buffer, 0, buffer.Length);

            return buffer;
        }
Пример #4
0
 /// <summary>
 /// This method supports the Fluorine infrastructure and is not intended to be used directly from your code.
 /// </summary>
 /// <returns></returns>
 public AMFMessage ReadAMFMessage()
 {
     // Version stored in the first two bytes.
     var version = ReadUInt16();
     var message = new AMFMessage(version);
     // Read header count.
     int headerCount = ReadUInt16();
     for (var i = 0; i < headerCount; i++) {
         message.AddHeader(ReadHeader());
     }
     // Read header count.
     int bodyCount = ReadUInt16();
     for (var i = 0; i < bodyCount; i++) {
         var amfBody = ReadBody();
         if (amfBody != null) //not failed
             message.AddBody(amfBody);
     }
     return message;
 }
Пример #5
0
        private AMFMessage ReadMessage(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            if (reader.TokenType != JsonToken.StartObject)
                throw new JsonReaderException("AMFMessage must be a JSON Object");

            AMFMessage message = new AMFMessage();

            for (reader.Read(); reader.TokenType != JsonToken.EndObject; reader.Read())
            {
                if (reader.TokenType != JsonToken.PropertyName)
                    throw new JsonReaderException("JSON format error, JSON Object must have property");

                string propertyName = (string)reader.Value;
                switch (propertyName)
                {
                    case "Version":
                        reader.Read();
                        if (reader.TokenType != JsonToken.Integer)
                            throw new JsonReaderException("AMFMessage 'Version' must be JSON Number");
                        message = new AMFMessage(Convert.ToUInt16(reader.Value));
                        break;
                    case "Bodies":
                        reader.Read();
                        if (reader.TokenType != JsonToken.StartArray)
                            throw new JsonReaderException("AMFMessage 'Bodies' must be JSON Array");
                        for (reader.Read(); reader.TokenType != JsonToken.EndArray; reader.Read())
                        {
                            AMFBody body = serializer.Deserialize<AMFBody>(reader);
                            message.AddBody(body);
                        }
                        break;
                    default:
                        throw new NotSupportedException("AMFMessage dont support property " + propertyName + ", please report this");
                        break;
                }
            }
            return message;
        }
        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;
        }
Пример #7
0
        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
        }
Пример #8
0
        private AMFMessage LoadBinMessageIntoAmfMessage(byte[] encodedMessage)
        {
            AMFMessage message = null;
            byte[] buffer = encodedMessage;
            MemoryStream stream = new MemoryStream(buffer);
            try
            {
                message = new AMFDeserializer(stream).ReadAMFMessage();
            }
            catch (DecoderFallbackException)
            {
                stream.Position = 0;
                object content = new AMFReader(stream) { FaultTolerancy = true }.ReadAMF3Data();
                message = new AMFMessage(3);
                message.AddBody(new AMFBody(string.Empty, string.Empty, content));
            }

            return message;
        }