using Newtonsoft.Json; using System.Collections; using System.Net; using System.Reflection; namespace SimpleHttpServer.Internal; internal class HttpEndpointHandler { private static readonly DefaultAuthorizer defaultAuth = new(); private readonly IAuthorizer _auth; private readonly MethodInfo _handler; private readonly Dictionary _params; private readonly Func _errorPageBuilder; public HttpEndpointHandler() { _auth = defaultAuth; } public HttpEndpointHandler(IAuthorizer auth) { } public virtual void Handle(HttpListenerContext ctx) { try { var (isAuth, authData) = _auth.IsAuthenticated(ctx); if (!isAuth) { throw new HttpHandlingException(401, "Authorization required!"); } // collect parameters var invokeParams = new object?[_params.Count + 1]; var set = new BitArray(_params.Count); invokeParams[0] = ctx; // read pparams // read qparams var qst = ctx.Request.QueryString; foreach (var qelem in ctx.Request.QueryString.AllKeys) { if (_params.ContainsKey(qelem!)) { var (pindex, type, isPParam) = _params[qelem!]; if (type == typeof(string)) { invokeParams[pindex] = ctx.Request.QueryString[qelem!]; set.Set(pindex - 1, true); } else { var elem = JsonConvert.DeserializeObject(ctx.Request.QueryString[qelem!]!, type); if (elem != null) { invokeParams[pindex] = elem; set.Set(pindex - 1, true); } } } } // fill with defaults foreach (var p in _params) { if (!set.Get(p.Value.pindex)) { invokeParams[p.Value.pindex] = p.Value.type.IsValueType ? Activator.CreateInstance(p.Value.type) : null; } } var builder = _handler.Invoke(null, invokeParams) as HttpResponseBuilder; builder!.SendResponse(ctx.Response); } catch (Exception e) { if (e is TargetInvocationException tex) { e = tex.InnerException!; } _errorPageBuilder(e).SendResponse(ctx.Response); } } }