/// <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; } }
public override void Invoke(AMFContext context) { AMFMessage aMFMessage = context.AMFMessage; if (aMFMessage.GetHeader("DescribeService") != null) { aMFMessage.GetBodyAt(0).IsDescribeService = true; } }
public override void Invoke(AMFContext context) { AMFMessage amfMessage = context.AMFMessage; AMFHeader amfHeader = amfMessage.GetHeader(AMFHeader.ServiceBrowserHeader); if (amfHeader != null) { AMFBody amfBody = amfMessage.GetBodyAt(0); amfBody.IsDescribeService = true; } }
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(); }
public override void Invoke(AMFContext context) { AMFMessage aMFMessage = context.AMFMessage; AMFHeader header = aMFMessage.GetHeader("amf_server_debug"); if (header != null) { ASObject content = header.Content as ASObject; AMFBody bodyAt = aMFMessage.GetBodyAt(aMFMessage.BodyCount - 1); ResponseBody body = new ResponseBody { Target = bodyAt.Response + "/onDebugEvents", Response = null, IsDebug = true }; ArrayList list = new ArrayList(); ArrayList list2 = new ArrayList(); list.Add(list2); if ((bool)content["httpheaders"]) { list2.Add(new HttpHeader()); } if ((bool)content["amfheaders"]) { list2.Add(new AMFRequestHeaders(aMFMessage)); } ArrayList traceStack = NetDebug.GetTraceStack(); if ((((bool)content["trace"]) && (traceStack != null)) && (traceStack.Count > 0)) { ArrayList list4 = new ArrayList(traceStack); list2.Add(new TraceHeader(list4)); NetDebug.Clear(); } body.Content = list; context.MessageOutput.AddBody(body); } NetDebug.Clear(); }
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; }
private void BeginResponseFlexCall(IAsyncResult ar) { try { AmfRequestData amfRequestData = ar.AsyncState as AmfRequestData; if (amfRequestData != null) { HttpWebResponse response = (HttpWebResponse)amfRequestData.Request.EndGetResponse(ar); if (response != null) { //Get response and deserialize Stream responseStream = response.GetResponseStream(); if (responseStream != null) { AMFDeserializer amfDeserializer = new AMFDeserializer(responseStream); AMFMessage responseMessage = amfDeserializer.ReadAMFMessage(); AMFBody responseBody = responseMessage.GetBodyAt(0); for (int i = 0; i < responseMessage.HeaderCount; i++) { AMFHeader header = responseMessage.GetHeaderAt(i); if (header.Name == AMFHeader.RequestPersistentHeader) _netConnection.AddHeader(header.Name, header.MustUnderstand, header.Content); } object message = responseBody.Content; if (message is ErrorMessage) { /* ASObject status = new ASObject(); status["level"] = "error"; status["code"] = "NetConnection.Call.Failed"; status["description"] = (result as ErrorMessage).faultString; status["details"] = result; _netConnection.RaiseNetStatus(status); */ if (amfRequestData.Call != null) { PendingCall call = amfRequestData.Call; call.Result = message; call.Status = Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION; amfRequestData.Callback.ResultReceived(call); } if (amfRequestData.Responder != null) { StatusFunction statusFunction = amfRequestData.Responder.GetType().GetProperty("Status").GetValue(amfRequestData.Responder, null) as StatusFunction; if (statusFunction != null) statusFunction(new Fault(message as ErrorMessage)); } } else if (message is AcknowledgeMessage) { AcknowledgeMessage ack = message as AcknowledgeMessage; if (_netConnection.ClientId == null && ack.HeaderExists(MessageBase.FlexClientIdHeader)) _netConnection.SetClientId(ack.GetHeader(MessageBase.FlexClientIdHeader) as string); if (amfRequestData.Call != null) { PendingCall call = amfRequestData.Call; call.Result = ack.body; call.Status = Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT; amfRequestData.Callback.ResultReceived(call); } if (amfRequestData.Responder != null) { Delegate resultFunction = amfRequestData.Responder.GetType().GetProperty("Result").GetValue(amfRequestData.Responder, null) as Delegate; if (resultFunction != null) { ParameterInfo[] arguments = resultFunction.Method.GetParameters(); object result = TypeHelper.ChangeType(ack.body, arguments[0].ParameterType); resultFunction.DynamicInvoke(result); } } } } else _netConnection.RaiseNetStatus("Could not aquire ResponseStream"); } else _netConnection.RaiseNetStatus("Could not aquire HttpWebResponse"); } } catch (Exception ex) { _netConnection.RaiseNetStatus(ex); } }
private void BeginResponseFlashCall(IAsyncResult ar) { try { AmfRequestData amfRequestData = ar.AsyncState as AmfRequestData; if (amfRequestData != null) { HttpWebResponse response = (HttpWebResponse)amfRequestData.Request.EndGetResponse(ar); if (response != null) { //Get response and deserialize Stream responseStream = response.GetResponseStream(); if (responseStream != null) { AMFDeserializer amfDeserializer = new AMFDeserializer(responseStream); AMFMessage responseMessage = amfDeserializer.ReadAMFMessage(); AMFBody responseBody = responseMessage.GetBodyAt(0); for (int i = 0; i < responseMessage.HeaderCount; i++) { AMFHeader header = responseMessage.GetHeaderAt(i); if (header.Name == AMFHeader.RequestPersistentHeader) _netConnection.AddHeader(header.Name, header.MustUnderstand, header.Content); } if (amfRequestData.Call != null) { PendingCall call = amfRequestData.Call; call.Result = responseBody.Content; call.Status = responseBody.Target.EndsWith(AMFBody.OnStatus) ? Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION : Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT; amfRequestData.Callback.ResultReceived(call); } if (amfRequestData.Responder != null) { if (responseBody.Target.EndsWith(AMFBody.OnStatus)) { StatusFunction statusFunction = amfRequestData.Responder.GetType().GetProperty("Status").GetValue(amfRequestData.Responder, null) as StatusFunction; if (statusFunction != null) statusFunction(new Fault(responseBody.Content)); } else { Delegate resultFunction = amfRequestData.Responder.GetType().GetProperty("Result").GetValue(amfRequestData.Responder, null) as Delegate; if (resultFunction != null) { ParameterInfo[] arguments = resultFunction.Method.GetParameters(); object result = TypeHelper.ChangeType(responseBody.Content, arguments[0].ParameterType); resultFunction.DynamicInvoke(result); } } } } else _netConnection.RaiseNetStatus("Could not aquire ResponseStream"); } else _netConnection.RaiseNetStatus("Could not aquire HttpWebResponse"); } } catch (Exception ex) { _netConnection.RaiseNetStatus(ex); } }
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); }
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 }
/// <summary> /// Десериализует буфер данных в объект AMF. /// </summary> /// <typeparam name="T">Тип десериализуемого объекта.</typeparam> /// <param name="sourceBuffer">Исходный буфер данных объекта.</param> /// <returns></returns> public static T DeserializeFromAmf <T>(this byte[] sourceBuffer) where T : class { using (MemoryStream memoryStream = new MemoryStream(sourceBuffer)) // Открываем поток для чтения данных из буфера. using (AMFDeserializer amfDeserializer = new AMFDeserializer(memoryStream)) // Инициализируем десериализатор для AMF. { AMFMessage amfMessage = amfDeserializer.ReadAMFMessage(); // Получем сообщение AMF. AMFBody amfBody = amfMessage.GetBodyAt(0); // Получаем body из сообщения AMF. object amfObject = amfBody.Content; // Получаем объект из body AMF. Type amfObjectType = amfObject.GetType(); // Получаем метаданные типа объекта AMF. // Формируем запрос на получение всей коллекции нужных нам типов с заданными атрибутами. IEnumerable <Type> types = from type in Assembly.GetExecutingAssembly().GetTypes() where Attribute.IsDefined(type, typeof(AmfObjectAttribute)) select type; Type currentType = null; // Определяем текущий тип объекта из нашей сборки. // Проходим по всем найденным типам с нашим атрибутом. foreach (Type type in types) { AmfObjectAttribute attribute = type.GetAttribute <AmfObjectAttribute>(); // Получаем наш атрибут. if (attribute == null || attribute.Name != amfObjectType.FullName) { continue; // Если в атрибуте задано другое имя - пропускаем итерацию. } currentType = type; // Иначе сохраняем текущий тип объекта. break; } if (currentType == null) { return(default(T)); // Если тип не найден - возвращаем null. } object targetObject = Activator.CreateInstance(currentType); // Создаём инстанс нашего типа. // Анализируем все свойства нашего класса. foreach (PropertyInfo propertyInfo in currentType.GetProperties()) { AmfMemberAttribute attribute = propertyInfo.GetAttribute <AmfMemberAttribute>(); // Получаем наш кастомный атрибут. if (attribute == null) { continue; // Если атрибут не задан - пропускаем. } propertyInfo.SetValue(targetObject, amfObjectType.GetProperty(attribute.Name).GetValue(amfObject, null), null); // Получаем значение свойства у десериализуемого объекта и сохраняем его в свойстве нашего объекта. } // Анализируем все поля нашего класса. foreach (FieldInfo fieldInfo in currentType.GetFields()) { AmfMemberAttribute attribute = fieldInfo.GetAttribute <AmfMemberAttribute>(); // Получаем наш кастомный атрибут. if (attribute == null) { continue; // Если атрибут не задан - пропускаем. } fieldInfo.SetValue(targetObject, amfObjectType.GetField(attribute.Name).GetValue(amfObject)); // Получаем значение поля у десериализуемого объекта и сохраняем его в поле нашего объекта. } return(targetObject as T); // Приводит к типу T и возвращает текущий объект. } }