예제 #1
0
		public override void Invoke(AMFContext context) {
			MessageBroker messageBroker = _endpoint.GetMessageBroker();
			try {
				AMFHeader amfHeader = context.AMFMessage.GetHeader(AMFHeader.CredentialsHeader);
				if (amfHeader != null && amfHeader.Content != null) {
					string userId = ((ASObject)amfHeader.Content)["userid"] as string;
					string password = ((ASObject)amfHeader.Content)["password"] as string;
					//Clear credentials header, further requests will not send the credentials
					ASObject asoObject = new ASObject();
					asoObject["name"] = AMFHeader.CredentialsHeader;
					asoObject["mustUnderstand"] = false;
					asoObject["data"] = null;//clear
					AMFHeader header = new AMFHeader(AMFHeader.RequestPersistentHeader, true, asoObject);
					context.MessageOutput.AddHeader(header);
					IPrincipal principal = _endpoint.GetMessageBroker().LoginManager.Login(userId, amfHeader.Content as IDictionary);
					string key = EncryptCredentials(_endpoint, principal, userId, password);
					ASObject asoObjectCredentialsId = new ASObject();
					asoObjectCredentialsId["name"] = AMFHeader.CredentialsIdHeader;
					asoObjectCredentialsId["mustUnderstand"] = false;
					asoObjectCredentialsId["data"] = key;//set
					AMFHeader headerCredentialsId = new AMFHeader(AMFHeader.RequestPersistentHeader, true, asoObjectCredentialsId);
					context.MessageOutput.AddHeader(headerCredentialsId);
				} else {
					amfHeader = context.AMFMessage.GetHeader(AMFHeader.CredentialsIdHeader);
					if (amfHeader != null) {
						string key = amfHeader.Content as string;
						if (key != null)
							_endpoint.GetMessageBroker().LoginManager.RestorePrincipal(key);
					} else {
						_endpoint.GetMessageBroker().LoginManager.RestorePrincipal();
					}
				}
			} catch (UnauthorizedAccessException exception) {
				for (int i = 0; i < context.AMFMessage.BodyCount; i++) {
					AMFBody amfBody = context.AMFMessage.GetBodyAt(i);
					ErrorResponseBody errorResponseBody = new ErrorResponseBody(amfBody, exception);
					context.MessageOutput.AddBody(errorResponseBody);
				}
			} catch (Exception exception) {
				if (log != null && log.IsErrorEnabled)
					log.Error(exception.Message, exception);
				for (int i = 0; i < context.AMFMessage.BodyCount; i++) {
					AMFBody amfBody = context.AMFMessage.GetBodyAt(i);
					ErrorResponseBody errorResponseBody = new ErrorResponseBody(amfBody, exception);
					context.MessageOutput.AddBody(errorResponseBody);
				}
			}
		}
예제 #2
0
        private AMFBody ReadBody()
        {
            this.Reset();
            string target = base.ReadString();

            // Response that the client understands.
            string response = base.ReadString();
            int    length   = base.ReadInt32();

            try {
                object    content   = base.ReadData();
                AMFBody   amfBody   = new AMFBody(target, response, content);
                Exception exception = this.LastError;
                if (exception != null)
                {
                    ErrorResponseBody errorResponseBody = GetErrorBody(amfBody, exception);
                    _failedAMFBodies.Add(errorResponseBody);
#if !SILVERLIGHT
                    if (log.IsFatalEnabled)
                    {
                        log.Fatal(__Res.GetString(__Res.Amf_ReadBodyFail), exception);
                    }
#endif
                    return(null);
                }
                return(amfBody);
            } catch (Exception exception) {
                //Try to build a valid response from partialy deserialized amf body
                AMFBody           amfBody           = new AMFBody(target, response, null);
                ErrorResponseBody errorResponseBody = GetErrorBody(amfBody, exception);
                _failedAMFBodies.Add(errorResponseBody);
#if !SILVERLIGHT
                if (log.IsFatalEnabled)
                {
                    log.Fatal(__Res.GetString(__Res.Amf_ReadBodyFail), exception);
                }
#endif
                throw;
            }
        }
예제 #3
0
        private ErrorResponseBody GetErrorBody(AMFBody amfBody, Exception exception)
        {
            ErrorResponseBody errorResponseBody = null;

            try {
                object content = amfBody.Content;
                if (content is IList)
                {
                    content = (content as IList)[0];
                }
                if (content is GodLesZ.Library.Amf.Messaging.Messages.IMessage)
                {
                    errorResponseBody = new ErrorResponseBody(amfBody, content as GodLesZ.Library.Amf.Messaging.Messages.IMessage, exception);
                }
                else
                {
                    errorResponseBody = new ErrorResponseBody(amfBody, exception);
                }
            } catch {
                errorResponseBody = new ErrorResponseBody(amfBody, exception);
            }
            return(errorResponseBody);
        }
예제 #4
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 = GodLesZ.Library.Amf.Configuration.CacheMap.GenerateCacheKey(source, parameterList);
					if (FluorineConfiguration.Instance.CacheMap.ContainsValue(key)) {
						object result = GodLesZ.Library.Amf.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);
			}
		}
예제 #5
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);

				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);
				}
			}
		}
예제 #6
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);
                        GodLesZ.Library.Amf.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
        }