Exemple #1
0
        public List <object> DeserializeFromBody(ChannelMethodInfo methodDescription, string contentType)
        {
            string inputRequest = string.Empty;

            using (StreamReader reader = new StreamReader(_requestStream))
            {
                inputRequest = reader.ReadToEnd();
            }

            LogChannel.Write(LogSeverity.Info, $"Request body: ");
            LogChannel.Write(LogSeverity.Info, inputRequest);

            if (contentType == "application/xml" || contentType == "text/xml; charset=utf-8")
            {
                return(_services.Get <IXmlRequestService>().Deserialize(inputRequest, methodDescription));
            }
            else if (contentType == "application/json" || contentType == "application/json; charset=utf-8")
            {
                return(_services.Get <IJsonRequestService>().Deserialize(inputRequest, methodDescription));
            }
            else
            {
                throw new ChannelMethodContentTypeException("Content-type must be application/json or application/xml");
            }
        }
        private void SetupAndInvokeGetRequest(Type channel,
                                              MethodInfo method,
                                              ChannelMethodDeserializerFactory dsrFactory,
                                              HttpListenerRequest request,
                                              HttpListenerResponse response,
                                              ChannelMethodInfo methodDescription,
                                              ChannelConfigurationInfo channelConfig,
                                              List <object> channelRequestBody,
                                              bool authenticated,
                                              bool hasParams)
        {
            InitChannelMethodContext(channelConfig.Endpoint, request, response, authenticated, channelConfig.HttpMethod, channelRequestBody);
            if (hasParams)
            {
                dsrFactory         = new ChannelMethodDeserializerFactory(request.QueryString);
                channelRequestBody = dsrFactory.DeserializeFromQueryParameters(methodDescription);
                _requestActivator.GetActivateWithParameters(channel, method, channelRequestBody, response);
            }
            else
            {
                _requestActivator.GetActivateWithoutParameters(channel, method, response);
            }

            _contextProvider.DestroyChannelMethodContext(channelConfig.Endpoint);
        }
Exemple #3
0
        public List <object> Deserialize(string inputBody, ChannelMethodInfo methodDescription)
        {
            XmlDocument requestXml = new XmlDocument();

            requestXml.LoadXml(inputBody);

            Debug.Assert(requestXml.HasChildNodes);
            List <object> channelRequestBody;

            if (methodDescription.Parameters.Count != 0)
            {
                channelRequestBody = new List <object>();

                //Parameter initialization logic
                foreach (ChannelMethodParameter parameter in methodDescription.Parameters)
                {
                    Type   paramType     = parameter.Type;              // Parameter type
                    string paramTypeFull = paramType.FullName;          // Name of the class
                    string paramTypeASM  = paramType.Assembly.FullName; // Name of the assembly

                    if (paramType == typeof(string))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeString(requestXml, parameter.Name));
                    }
                    else if (paramType == typeof(int))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeInt(requestXml, parameter.Name));
                    }
                    else if (paramType == typeof(double))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeDouble(requestXml, parameter.Name));
                    }
                    else if (paramType == typeof(decimal))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeDecimal(requestXml, parameter.Name));
                    }
                    else if (paramType == typeof(float))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeFloat(requestXml, parameter.Name));
                    }
                    else if (paramType == typeof(bool))
                    {
                        channelRequestBody.Add(XmlTools.DeserializeBool(requestXml, parameter.Name));
                    }
                    else
                    {
                        channelRequestBody.Add(XmlTools.DeserializeComplex(inputBody, paramTypeASM, paramTypeFull));
                    }
                }
            }
            else
            {
                channelRequestBody = null;
            }

            return(channelRequestBody);
        }
Exemple #4
0
        public List <object> DeserializeFromQueryParameters(ChannelMethodInfo methodDescription)
        {
            List <object> channelRequestBody = new List <object>();
            Dictionary <string, string> deserializedNameValues = new Dictionary <string, string>();
            NameValueCollection         urlParameters          = _queryParameters;

            for (int i = 0; i < urlParameters.AllKeys.Length; i++)
            {
                deserializedNameValues.Add(urlParameters.Keys[i].ToLower(), urlParameters[i]);
            }
            foreach (ChannelMethodParameter description in methodDescription.Parameters)
            {
                Type paramType = description.Type;
                if (deserializedNameValues.Any(x => x.Key.Equals(description.Name.ToLower())))
                {
                    KeyValuePair <string, string> exists = deserializedNameValues.FirstOrDefault(x => x.Key.Equals(description.Name.ToLower()));

                    if (paramType == typeof(string))
                    {
                        channelRequestBody.Add(exists.Value);
                    }
                    else if (paramType == typeof(int))
                    {
                        channelRequestBody.Add(int.Parse(exists.Value));
                    }
                    else if (paramType == typeof(double))
                    {
                        channelRequestBody.Add(double.Parse(exists.Value));
                    }
                    else if (paramType == typeof(decimal))
                    {
                        channelRequestBody.Add(decimal.Parse(exists.Value));
                    }
                    else if (paramType == typeof(float))
                    {
                        channelRequestBody.Add(float.Parse(exists.Value));
                    }
                    else if (paramType == typeof(bool))
                    {
                        channelRequestBody.Add(bool.Parse(exists.Value));
                    }
                    else
                    {
                        channelRequestBody = null;
                    }
                }
            }

            return(channelRequestBody);
        }
Exemple #5
0
        public List <ChannelDocument> GetDocumentation(AppDomain domain)
        {
            Debug.Assert(_services.Get <IChannelLocator>() != null);

            List <Type> channels = _services.Get <IChannelLocator>().RegisteredChannels(domain);

            foreach (var channel in channels)
            {
                ChannelDocument  channelDoc         = new ChannelDocument();
                ChannelAttribute channelAttr        = channel.GetCustomAttribute <ChannelAttribute>();
                string           channelDescription = channelAttr.Description == null ? string.Empty : channelAttr.Description.ToString();
                string           channelName        = String.IsNullOrEmpty(channelAttr.Name) ? channel.Name : channelAttr.Name;
                string           channelRoute       = $"~/channels/{channelName}";
                MethodInfo[]     methods            = channel.GetMethods().Where(x => x.GetCustomAttribute <ChannelMethodAttribute>() != null).ToArray();
                ChannelMethodDocs = new List <ChannelMethodDocument>();
                foreach (var method in methods)
                {
                    ChannelMethodDocument  methodDocument         = new ChannelMethodDocument();
                    ChannelMethodInfo      description            = _services.Get <IChannelMethodDescriptor>().GetMethodDescription(method);
                    ChannelMethodAttribute ChannelMethodAttribute = method.GetCustomAttribute <ChannelMethodAttribute>();
                    ChannelHttpMethod      HttpMethod             = ChannelMethodAttribute.HttpMethod;
                    string[] names = description.Parameters.Select(x => x.Name).ToArray();
                    Type[]   types = description.Parameters.Select(x => x.Type).ToArray();
                    methodDocument.HttpMethod          = HttpMethod;
                    methodDocument.InputParameters     = names;
                    methodDocument.InputParameterTypes = types;
                    methodDocument.ReturnTypeName      = method.ReturnType.Name;
                    methodDocument.ReturnType          = method.ReturnType;
                    methodDocument.URL         = $"{channelRoute}/{method.Name}/";
                    methodDocument.AuthSchema  = ChannelMethodAttribute.Schema;
                    methodDocument.Description = ChannelMethodAttribute.Description; //null possibility

                    ChannelMethodDocs.Add(methodDocument);
                }
                channelDoc.Name               = channel.Name;
                channelDoc.Description        = channelDescription; //null possibility
                channelDoc.URL                = channelRoute;
                channelDoc.AvailableEndpoints = ChannelMethodDocs;

                ChannelDocs.Add(channelDoc);
            }


            return(ChannelDocs);
        }
        private bool TryInvokeGetRequest(Type channel,
                                         MethodInfo method,
                                         HttpListenerRequest request,
                                         HttpListenerResponse response,
                                         ChannelMethodDeserializerFactory dsrFactory,
                                         ChannelMethodInfo methodDescription,
                                         ChannelConfigurationInfo channelConfig,
                                         List <object> channelRequestBody,
                                         bool authenticated)
        {
            try
            {
                if (request.QueryString.AllKeys.Length > 0)
                {
                    SetupAndInvokeGetRequest(channel, method, dsrFactory, request, response, methodDescription, channelConfig, channelRequestBody, authenticated, true);
                }
                else if (request.QueryString.AllKeys.Length == 0)
                {
                    if (methodDescription.Parameters.Count > 0)
                    {
                        StreamWriter writer = new StreamWriter(response.OutputStream);
                        _msgService.ExceptionHandler(writer, new TargetParameterCountException(), response);
                        writer.Close();
                        return(false);
                    }

                    SetupAndInvokeGetRequest(channel, method, dsrFactory, request, response, methodDescription, channelConfig, channelRequestBody, authenticated, false);
                }
                return(true);
            }
            catch (Exception ex)
            {
                using (StreamWriter writer = new StreamWriter(response.OutputStream))
                {
                    _msgService.ExceptionHandler(writer, ex, response);
                    LogChannel.Write(LogSeverity.Fatal, ex.Message);
                }

                return(true);
            }
        }
        public List <object> Deserialize(string inputBody, ChannelMethodInfo methodDescription)
        {
            List <object> parameters = new List <object>();
            JObject       propObject = JObject.Parse(inputBody);

            Debug.Assert(propObject != null);

            foreach (ChannelMethodParameter parameter in methodDescription.Parameters)
            {
                JProperty jProperty = propObject.Property(parameter.Name, StringComparison.OrdinalIgnoreCase);
                if (jProperty != null)
                {
                    if (jProperty.Value != null)
                    {
                        parameters.Add(jProperty.Value.ToObject(parameter.Type));
                    }
                }
                else
                {
                    continue;
                }
            }
            return(parameters);
        }
        internal void SetupAndInvokeGetRequest(Type channel,
                                               MethodInfo method,
                                               HttpListenerRequest request,
                                               HttpListenerResponse response,
                                               ChannelMethodInfo methodDescription,
                                               ChannelConfigurationInfo channelConfig,
                                               List <object> channelRequestBody,
                                               bool authenticated,
                                               bool hasParams,
                                               CacheExecutionResult cacheExecutionResult)
        {
            //Context should be initialized before invoking the method because ChannelBase relies on Context
            InitChannelMethodContext(channelConfig.Endpoint, request, response, authenticated, channelConfig.HttpMethod, channelRequestBody);
            if (hasParams)
            {
                //Since request body will be processed in Heuristics if cache is enabled
                //Data is already stored in Data.Parameters property of CacheExecutionResult
                if (!cacheExecutionResult.DataProcessed)
                {
                    _dsrFactory        = new ChannelMethodDeserializerFactory(request.QueryString);
                    channelRequestBody = _dsrFactory.DeserializeFromQueryParameters(methodDescription);
                }
                else
                {
                    channelRequestBody = cacheExecutionResult.Data.Parameters;
                }

                _requestActivator.GetActivateWithParameters(channel, method, channelRequestBody, response);
            }
            else
            {
                _requestActivator.GetActivateWithoutParameters(channel, method, response);
            }

            _contextProvider.DestroyChannelMethodContext(channelConfig.Endpoint);
        }
        public void StartListening(MethodInfo method, Type channel, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            HttpListener httpChannel = new HttpListener();

            ChannelConfigurationInfo channelConfig = _configuration.Configure(httpChannel, channel, method, _baseURL);

            //Keep the ChannelMethod open for new requests
            while (true)
            {
                try
                {
                    httpChannel.Start();
                }
                catch (HttpListenerException hle)
                {
                    Console.WriteLine($"System.Net.HttpListenerException encountered on {channelConfig.MethodUrl} with reason :{hle.Message}");
                    return;
                }

                Console.WriteLine($"Listening on {channelConfig.MethodUrl}");
                HttpListenerContext      context       = httpChannel.GetContext();
                HttpListenerRequest      request       = context.Request;
                HttpListenerResponse     response      = context.Response;
                IChannelHeuristicContext heuristicsCtx = _services.Get <IChannelHeuristicContext>();

                bool executedIfCached = ExecuteIfCached(channel, method, request, response, heuristicsCtx);
                if (executedIfCached)
                {
                    heuristicsCtx.Clear();
                    goto EndRequest;
                }

                LogChannel.Write(LogSeverity.Info, $"Request coming to {channelConfig.Endpoint.Name}");
                LogChannel.Write(LogSeverity.Info, $"HttpMethod:{request.HttpMethod}");

                bool authFailed = AuthenticationFailedIfRequired(context, request, response, channelConfig, out bool authenticated);
                if (authFailed)
                {
                    goto EndRequest;
                }

                //Check if the Http Method is correct
                if (channelConfig.HttpMethod.ToString() != request.HttpMethod && channelConfig.HttpMethod != ChannelHttpMethod.Unknown)
                {
                    _msgService.WrongHttpMethod(response, channelConfig.HttpMethod);
                    LogChannel.Write(LogSeverity.Error, "Wrong HttpMethod... Closing request");
                    goto EndRequest;
                }


                ChannelMethodInfo methodDescription         = _channelMethodDescriptor.GetMethodDescription(method);
                List <object>     channelRequestBody        = null;
                ChannelMethodDeserializerFactory dsrFactory = null;

                if (request.HttpMethod == "GET")
                {
                    bool invoked = TryInvokeGetRequest(channel, method, request, response, dsrFactory, methodDescription, channelConfig, channelRequestBody, authenticated);
                    goto EndRequest;
                }

                //Enter only if Request Body is supplied with POST Method
                if (request.HasEntityBody == true && request.HttpMethod == "POST")
                {
                    StreamWriter writer = new StreamWriter(response.OutputStream);
                    try
                    {
                        dsrFactory         = new ChannelMethodDeserializerFactory(request.InputStream);
                        channelRequestBody = dsrFactory.DeserializeFromBody(methodDescription, request.ContentType);
                        InitChannelMethodContext(channelConfig.Endpoint, request, response, authenticated, channelConfig.HttpMethod, channelRequestBody);
                        _requestActivator.PostActivate(channel, method, channelRequestBody, response);
                    }
                    catch (ChannelMethodContentTypeException cEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, cEx, response);
                        LogChannel.Write(LogSeverity.Error, cEx.Message);
                    }
                    catch (ChannelMethodParameterException pEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, pEx, response);
                        LogChannel.Write(LogSeverity.Error, pEx.Message);
                    }
                    catch (TargetParameterCountException tEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, tEx, response);
                        LogChannel.Write(LogSeverity.Error, tEx.Message);
                    }
                    catch (Exception ex)
                    {
                        response.StatusCode = 500;
                        _msgService.ExceptionHandler(writer, ex, response);
                        LogChannel.Write(LogSeverity.Fatal, ex.Message);
                    }
                    finally
                    {
                        _contextProvider.DestroyChannelMethodContext(channelConfig.Endpoint);
                        writer.Flush();
                        writer.Close();
                    }
                }

EndRequest:
                LogChannel.Write(LogSeverity.Debug, "Request finished...");
                LogChannel.Write(LogSeverity.Debug, "Closing the response");
                response.Close();
            }
        }
        internal void TryInvokePostRequest(Type channel,
                                           MethodInfo method,
                                           HttpListenerRequest request,
                                           HttpListenerResponse response,
                                           List <object> channelRequestBody,
                                           ChannelMethodInfo methodDescription,
                                           ChannelConfigurationInfo channelConfig,
                                           bool authenticated,
                                           CacheExecutionResult cacheExecutionResult)
        {
            StreamWriter writer = new StreamWriter(response.OutputStream);

            try
            {
                //Since request body will be processed in Heuristics if cache is enabled
                //InputStream is flushed and data is already stored in Data.Parameters
                //property of CacheExecutionResult
                if (!cacheExecutionResult.DataProcessed)
                {
                    _dsrFactory        = new ChannelMethodDeserializerFactory(request.InputStream);
                    channelRequestBody = _dsrFactory.DeserializeFromBody(methodDescription, request.ContentType);
                }
                else
                {
                    channelRequestBody = cacheExecutionResult.Data.Parameters;
                }

                InitChannelMethodContext(channelConfig.Endpoint, request, response, authenticated, channelConfig.HttpMethod, channelRequestBody);
                _requestActivator.PostActivate(channel, method, channelRequestBody, response);
            }
            catch (ChannelMethodContentTypeException cEx)
            {
                response.StatusCode = 400;
                _msgService.ExceptionHandler(writer, cEx, response);
                LogChannel.Write(LogSeverity.Error, cEx.Message);
            }
            catch (ChannelMethodParameterException pEx)
            {
                response.StatusCode = 400;
                _msgService.ExceptionHandler(writer, pEx, response);
                LogChannel.Write(LogSeverity.Error, pEx.Message);
            }
            catch (TargetParameterCountException tEx)
            {
                response.StatusCode = 400;
                _msgService.ExceptionHandler(writer, tEx, response);
                LogChannel.Write(LogSeverity.Error, tEx.Message);
            }
            catch (Exception ex)
            {
                response.StatusCode = 500;
                _msgService.ExceptionHandler(writer, ex, response);
                LogChannel.Write(LogSeverity.Fatal, ex.Message);
            }
            finally
            {
                _contextProvider.DestroyChannelMethodContext(channelConfig.Endpoint);
                writer.Flush();
                writer.Close();
            }
        }
        public void Start()
        {
            State     = EntityState.Starting;
            StateName = Enum.GetName(typeof(EntityState), EntityState.Starting);

            _httpListener = new HttpListener();
            ChannelConfigurationInfo channelConfig = _configuration.Configure(_httpListener, _channel, _method, _baseURL);

            Url = channelConfig.MethodUrl;
            //Keep the ChannelMethod open for new requests
            while (true)
            {
                try
                {
                    _httpListener.Start();
                    State     = EntityState.Running;
                    StateName = Enum.GetName(typeof(EntityState), EntityState.Running);
                }
                catch (HttpListenerException hle)
                {
                    Console.WriteLine($"System.Net.HttpListenerException encountered on {channelConfig.MethodUrl} with reason :{hle.Message}");
                    return;
                }

                if (!_isManaged)
                {
                    Console.WriteLine($"Listening on {Url}");
                }

                HttpListenerContext      context       = _httpListener.GetContext();
                HttpListenerRequest      request       = context.Request;
                HttpListenerResponse     response      = context.Response;
                IChannelHeuristicContext heuristicsCtx = _services.Get <IChannelHeuristicContext>();

                LogChannel.Write(LogSeverity.Info, $"Request coming to {channelConfig.Endpoint.Name}");
                LogChannel.Write(LogSeverity.Info, $"HttpMethod:{request.HttpMethod}");

                ChannelAuthenticationInspector authInspector = new ChannelAuthenticationInspector(_authenticationService, _msgService, _settings, _session, _basicAuthenticationMethod, _tokenAuthenticationMethod);

                //Even if method is cached check authenticaion first
                bool authFailed = authInspector.AuthenticationFailedIfRequired(context, request, response, channelConfig, out bool authenticated);
                if (authFailed)
                {
                    goto EndRequest;
                }

                List <object> channelRequestBody = null;

                ChannelMethodCacheInspector cacheInspector       = new ChannelMethodCacheInspector(_msgService, _heuristics);
                CacheExecutionResult        cacheExecutionResult = cacheInspector.ExecuteIfCached(_channel, _method, request, response, heuristicsCtx);

                if (cacheExecutionResult.Executed)
                {
                    heuristicsCtx.Clear();
                    goto EndRequest;
                }

                if (channelConfig.HttpMethod.ToString() != request.HttpMethod && channelConfig.HttpMethod != ChannelHttpMethod.Unknown)
                {
                    _msgService.WrongHttpMethod(response, channelConfig.HttpMethod);
                    LogChannel.Write(LogSeverity.Error, "Wrong HttpMethod... Closing request");
                    goto EndRequest;
                }

                ChannelMethodInfo   methodDescription   = _channelMethodDescriptor.GetMethodDescription(_method);
                ChannelMethodCaller channelMethodCaller = new ChannelMethodCaller(_msgService, _contextProvider, _requestActivator);

                if (request.HttpMethod == "GET")
                {
                    channelMethodCaller.TryInvokeGetRequest(_channel, _method, request, response, methodDescription, channelConfig, channelRequestBody, authenticated, cacheExecutionResult);
                    goto EndRequest;
                }

                //Enter only if Request Body is supplied with POST Method
                if (request.HasEntityBody == true && request.HttpMethod == "POST")
                {
                    channelMethodCaller.TryInvokePostRequest(_channel, _method, request, response, channelRequestBody, methodDescription, channelConfig, authenticated, cacheExecutionResult);
                }

EndRequest:
                LogChannel.Write(LogSeverity.Debug, "Request finished...");
                LogChannel.Write(LogSeverity.Debug, "Closing the response");
                response.Close();
            }
        }