using System; using System.Collections.Generic; using ln.logging; using ln.http.exceptions; using System.IO; using System.Text; using System.Threading; namespace ln.http { /* public class HttpServer { public static bool DefaultRouteAuthentication { get; set; } = false; private HashSet _routerDelegates = new HashSet(); public IEnumerable Routers => _routerDelegates; public TextWriter AccessLogWriter { get; set; } private ILogWriter _logWriter; private HashSet _authenticationSources = new HashSet(); public IEnumerable AuthenticationSources => _authenticationSources; public HttpServer() : this(Console.Out, new LogWriter(new ConsoleLogSink())) { } public HttpServer(TextWriter accessLogWriter, ILogWriter logWriter) { AccessLogWriter = accessLogWriter; _logWriter = logWriter; } public HttpServer(HttpRouterDelegate router) : this() { AddRouter(router); } public void RegisterAuthenticationSource(IHttpAuthenticationSource authenticationSource) => _authenticationSources.Add(authenticationSource); public void UnregisterAuthenticationSource(IHttpAuthenticationSource authenticationSource) => _authenticationSources.Remove(authenticationSource); public void AddRouter(HttpRouter httpRouter) => AddRouter(httpRouter.RouteRequest); public void AddRouter(HttpRouterDelegate routerDelegate) => _routerDelegates.Add(routerDelegate); public void RemoveRouter(HttpRouter httpRouter) => RemoveRouter(httpRouter.RouteRequest); public void RemoveRouter(HttpRouterDelegate routerDelegate) => _routerDelegates.Remove(routerDelegate); public void Connection(HttpConnection httpConnection) => ThreadPool.QueueUserWorkItem((state => ConnectionWorker(httpConnection))); public void ConnectionWorker(HttpConnection httpConnection) { try { bool keepalive = false; do { DateTime start = DateTime.Now; using (HttpRequest httpRequest = ReadRequest(httpConnection)) { if (httpRequest == null) break; HttpContext httpContext = new HttpContext(this, httpRequest); try { if (!RouteRequest(httpContext)) throw new HttpException(HttpStatusCode.NotFound); } catch (Exception exception) { _logWriter?.Log(exception); if (exception is HttpException httpException) { try { HttpContext errorContext = new HttpContext(httpContext, httpException); if (!RouteRequest(errorContext)) { errorContext.ResetRoutingStack(String.Format("/_err.html", (int)httpException.HttpStatusCode)); RouteRequest(errorContext); } httpContext.Response = errorContext.Response; } finally { if (httpContext.Response is null) httpContext.Response = HttpResponse .InternalServerError() .Content( String.Format("An internal error occured ({0})", exception.ToString())); } } else { httpContext.Response = HttpResponse.InternalServerError() .Content(String.Format("An internal error occured ({0})", exception.ToString())); } } try { httpContext.Response.WriteTo(httpConnection.ClientStream); httpContext.Response?.ContentStream?.Dispose(); } catch (IOException ioexception) { break; } DateTime end = DateTime.Now; TimeSpan duration = end - start; AccessLogWriter?.WriteLine("{0} {1} {2} {3} {4} {5} {6} {7}", start, end, duration, httpConnection.RemoteEndPoint?.ToString(), httpContext.Response?.StatusCode.ToString() ?? "-", httpContext.AuthenticatedPrincipal?.ToString() ?? "-", httpContext.Request.Method, httpContext.Request.RequestUri ); AccessLogWriter?.Flush(); keepalive = httpContext.Response.GetHeader("connection", "keep-alive").Equals("keep-alive") && httpRequest .GetRequestHeader("connection", httpRequest.Protocol.Equals("HTTP/1.1") ? "keep-alive" : "close").Contains( "keep-alive", StringComparison.InvariantCultureIgnoreCase); } } while (keepalive); } finally { httpConnection.ClientStream.Close(); httpConnection.ClientStream.Dispose(); } } private bool RouteRequest(HttpContext httpContext) { foreach (var routerDelegate in _routerDelegates) { if (routerDelegate(httpContext)) return true; } return false; } private HttpRequest ReadRequest(HttpConnection httpConnection) { try { if (HttpLikeProtocolReader.ReadRequest(httpConnection.ClientStream, Encoding.UTF8, out Request request)) return new HttpRequest(this, request); return null; } catch (IOException) { return null; } catch (ConnectionClosedException) { return null; } catch (Exception e) { _logWriter?.Log(e); return null; } } } */ }