public ChannelMethodInvoker() { _services = ServiceLocatorBuilder.CreateServiceLocator(); _channelMessageService = _services.Get <IChannelMessageService>(); _channelMessageWriter = _services.Get <IChannelMessageOutputWriter>(); _eventService = _services.Get <IChannelRedirectionEvents>(); _channelGenerator = _services.Get <IChannelGenerator>(); _heurCtx = _services.Get <IChannelHeuristicContext>(); Debug.Assert(_services != null); Debug.Assert(_channelMessageService != null); Debug.Assert(_channelMessageWriter != null); Debug.Assert(_eventService != null); Debug.Assert(_channelGenerator != null); Debug.Assert(_heurCtx != null); _channelMessageWriter.OnPostMessageServiceInvoked += _channelMessageWriter_OnPostMessageServiceInvoked; _eventService.OnRedirectionInvoked += _eventService_OnRedirectionInvoked; }
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 CacheExecutionResult ExecuteIfCached(Type channel, MethodInfo method, HttpListenerRequest request, HttpListenerResponse response, IChannelHeuristicContext heurContext) { CacheExecutionResult result = new CacheExecutionResult(); result.Executed = false; bool isCacheEnabled = false; try { isCacheEnabled = IsCached(method); } catch (InvalidChannelMethodTargetException ex) { StreamWriter writer = new StreamWriter(response.OutputStream); _msgService.ExceptionHandler(writer, ex, response); writer.Close(); result.Executed = true; } if (isCacheEnabled) { HeuristicsInfo hInfo = new HeuristicsInfo(); bool isCached = _heuristics.IsMethodCached(channel, method, out hInfo); if (isCached) { ChannelMethodHeuristicOptions hOptions = new ChannelMethodHeuristicOptions { Channel = channel, ChannelMethod = method, Request = request, Response = response }; return(_heuristics.Execute(hOptions, hInfo)); } else { heurContext.ExpectsAdding = true; heurContext.Channel = channel; heurContext.MethodInfo = method; result.Executed = false; result.DataProcessed = false; } } return(result); }
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(); } }