public IHttpResponse HandleRequest(IHttpRequest request, TokenState tokenState) { _logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "GetRequestHandler started")); Stopwatch timer = Stopwatch.StartNew(); IActivityHandler handler = GetRequestHandler(request); var handlerName = handler != null?handler.GetType().Name : "null"; _logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "GetRequestHandler completed"), new LogItem("DurationMilliseconds", timer.Elapsed.TotalMilliseconds), new LogItem("FoundHandler", handlerName)); if (handler == null) { return(null); } IHttpResponse response = _container.GetInstance <IHttpResponse>(true); _logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "Handler Handle called")); timer.Restart(); handler.Handle(request, response); _logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "Handler Handle completed"), new LogItem("DurationMilliseconds", timer.Elapsed.TotalMilliseconds)); return(response); }
public void Handle(IHttpRequest request, IHttpResponse response) { Dictionary <Type, ActivityHandlerAttribute[]> handlers = _container.GetAttributedTypes <ActivityHandlerAttribute>(typeof(IActivityHandler)); List <object> handlerInfoList = new List <object>(); foreach (KeyValuePair <Type, ActivityHandlerAttribute[]> keyValuePair in handlers) { foreach (ActivityHandlerAttribute attribute in keyValuePair.Value) { var instance = (IActivityHandler)_container.GetInstance(keyValuePair.Key); handlerInfoList.Add(new { path = attribute.Path, verb = attribute.Verb.ToString(), description = attribute.Description, expectedParameters = attribute.ExpectedParameters, exampleCall = $"{attribute.Path}{(attribute.ExpectedParameters.Any() ? "?" : "")}{string.Join("&", attribute.ExpectedParameters.Select(a => a + "=<value>"))}", exampleRequestDocument = instance.ExampleRequestDocument, exampleResponseDocument = instance.ExampleResponseDocument, }); } } response.SetObjectContent(handlerInfoList); }
public IHttpResponse HandleRequest(IHttpRequest request, TokenState tokenState) { IHttpResponse response = _container.GetInstance <IHttpResponse>(true); if (tokenState == TokenState.Invalid || tokenState == TokenState.Expired || tokenState == TokenState.NotYetValid) { return(UnauthorisedResponse); } logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "GetRequestHandler started")); Stopwatch timer = Stopwatch.StartNew(); IActivityHandler handler = GetRequestHandler(request, out ActivityHandlerAttribute attribute); var handlerName = handler != null?handler.GetType().Name : "null"; logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "GetRequestHandler completed"), new LogItem("DurationMilliseconds", timer.Elapsed.TotalMilliseconds), new LogItem("FoundHandler", handlerName)); if (handler == null) { switch (request.Verb) { case HttpVerb.Options: handler = _container.GetInstance <OptionsActivityHandler>(); attribute = new ActivityHandlerAttribute("", request.Verb, "") { SkipAuthorisation = true }; break; default: return(null); } } JwtSecurityToken token = request.SecurityToken; if (!activityAuthorisationManager.CheckAuthorisation(token, attribute)) { var unauthorised = _container.GetInstance <IHttpResponse>(true); unauthorised.HttpStatusCode = HttpStatusCode.Unauthorized; return(unauthorised); } logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "Handler Handle called")); timer.Restart(); try { handler.Handle(request, response); } catch (Exception exception) { logger.Exception($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", "Exception caught handling request", exception); response.SetStringContent(string.Empty); response.HttpStatusCode = HttpStatusCode.InternalServerError; } var elapsedMilliseconds = timer.Elapsed.TotalMilliseconds; logger.Trace($"{nameof(RequestBroker)}.{nameof(HandleRequest)}", new LogItem("Event", "Handler Handle completed"), new LogItem("DurationMilliseconds", elapsedMilliseconds)); apiMetrics.RecordHandlerDuration(elapsedMilliseconds, handlerName, response.HttpStatusCode); return(response); }
private void Processor(Socket s) { try { byte[] buffer = new byte[4096]; byte[] content = null; int contentOffset = 0; HttpRequest request = null; Stopwatch connectionTimer = Stopwatch.StartNew(); using (NetworkStream ns = new NetworkStream(s)) { while (true) { int bytesReceived; do { bytesReceived = ns.Read(buffer, 0, buffer.Length); if (bytesReceived != 0) { break; } Thread.Sleep(1); } while (connectionTimer.ElapsedMilliseconds < requestTimeout); if (bytesReceived == 0) { s.Shutdown(SocketShutdown.Both); s.Dispose(); ns.Dispose(); logger.Trace($"{nameof(NanoHttp)}.{nameof(Processor)}", new LogItem("Event", "Closed socket"), new LogItem("Reason", $"No request received in {requestTimeout}ms")); return; } byte[] received = new byte[bytesReceived]; Array.Copy(buffer, 0, received, 0, bytesReceived); if (request == null) { int i = received.FindPattern((byte)13, (byte)10, (byte)13, (byte)10); // If we have a double CRLF then we have a complete header, otherwise keep looping if (i == -1) { continue; } request = ParseHeader(i, ref received, ref content, ref contentOffset, ref bytesReceived); if (request == null) { s.Shutdown(SocketShutdown.Both); s.Dispose(); ns.Dispose(); return; } } Array.Copy(received, 0, content, contentOffset, bytesReceived); contentOffset += bytesReceived; if (contentOffset < content.Length - 1) { continue; } // Completed loading body, which could have urlencoded content :( TokenState tokenState = request.FinaliseLoad(request.Verb != HttpVerb.Options && validJwtRequired, TokenValidationParameters); request.Body = content; logger.Trace($"{nameof(NanoHttp)}.{nameof(Processor)}", new LogItem("Event", "HandleRequest started")); Stopwatch responseTimer = Stopwatch.StartNew(); IHttpResponse response = null; foreach (IRequestBroker requestBroker in requestBrokers.OrderBy(x => x.Precedence)) { response = requestBroker.HandleRequest(request, tokenState); if (response != null) { break; } } if (response == null) { response = container.GetInstance <IHttpResponse>(true); response.HttpStatusCode = HttpStatusCode.NotFound; response.HttpContent = new NotFoundHttpContent(); } logger.Trace($"{nameof(NanoHttp)}.{nameof(Processor)}", new LogItem("Event", "HandleRequest completed"), new LogItem("DurationMilliseconds", responseTimer.Elapsed.TotalMilliseconds)); response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS"); response.Headers.Add("Access-Control-Allow-Headers", "authorization"); response.Headers.Add("Connection", "close"); if (response.CachingDisabled) { if (!response.Headers.ContainsKey("Expires")) { response.Headers.Add("Expires", "-1"); } if (!response.Headers.ContainsKey("Pragma")) { response.Headers.Add("Pragma", "no-cache"); } if (!response.Headers.ContainsKey("Cache-Control")) { response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate"); } } response.WriteToStream(ns); ns.Flush(); if (response.HttpStatusCode == HttpStatusCode.SwitchingProtocols) { // ####################################### // # WebSocket Stuff Goes Here # // # https://tools.ietf.org/html/rfc6455 # // ####################################### // There's a blocking call here into a message loop // while true ... // wait for a websocket message // ... etc // end } s.Shutdown(SocketShutdown.Both); s.Dispose(); ns.Dispose(); logger.Trace($"{nameof(NanoHttp)}.{nameof(Processor)}", new LogItem("Event", "Closed socket"), new LogItem("Reason", "Response complete"), new LogItem("DurationMilliseconds", connectionTimer.Elapsed.TotalMilliseconds)); return; } } } catch (Exception ex) { logger.Error($"{nameof(NanoHttp)}.{nameof(Processor)}", new LogItem("Event", "An error occurred processing request"), new LogItem("Exception", ex.ToString)); throw; } }