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); }
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); }
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); }
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(); } }