private bool CheckServiceMatch(string[] parts, DeltaWebServiceDefinition s)
        {
            //Get template
            string[] template = s.GetTemplateUrl().Split('/');

            //Check length
            if (parts.Length != template.Length)
            {
                return(false);
            }

            //Check for matches
            for (int i = 0; i < template.Length; i++)
            {
                //If this is a wildcard, ignore
                if (template[i].StartsWith('{') && template[i].EndsWith('}'))
                {
                    continue;
                }

                //Check for match
                if (template[i] != parts[i])
                {
                    return(false);
                }
            }

            return(true);
        }
        public List <string> exposedHeaders = new List <string>(); //List of headers that are exposed to CORS

        public async Task OnHTTPRequest(HttpContext e)
        {
            //Do CORS stuff
            e.Response.Headers.Add("X-Delta-Server-Instance-ID", conn.instanceId);
            e.Response.Headers.Add("X-Delta-Server-Type", conn.server_type.ToString().ToUpper());
            e.Response.Headers.Add("Access-Control-Expose-Headers", GetExposedHeadersString());
            e.Response.Headers.Add("Access-Control-Allow-Headers", GetExposedHeadersString());
            e.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            e.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE, PUT, PATCH");
            if (e.Request.Method.ToUpper() == "OPTIONS")
            {
                await WriteStringToBody(e, "Dropping OPTIONS request. Hello CORS!", "text/plain", 200);

                return;
            }

            //Log
            conn.Log("DeltaWebServer-OnHTTPRequest", $"Got HTTP {e.Request.Method.ToUpper()} -> {e.Request.Path + e.Request.QueryString}", DeltaLogLevel.Debug);
            stat_requests_handled++;

            //Check if this is a status request
            if (e.Request.Path == "/status.json")
            {
                await WriteStringToBody(e, JsonConvert.SerializeObject(GetStatus()), "application/json");

                return;
            }

            //Find a matching service
            DeltaWebServiceDefinition service = FindService(e.Request.Path);

            //Check to see if we found a service
            if (service == null)
            {
                await WriteStringToBody(e, "Not Found", "text/plain", 404);

                return;
            }

            //Parse args
            Dictionary <string, string> args = MatchWildcardArgs(e.Request.Path.ToString().Split('/'), service.GetTemplateUrl().Split('/'));

            //Create a new session
            DeltaWebService session = service.OpenRequest(conn, e);

            try
            {
                //Preauthenticate this session
                if (!await session.OnPreRequest())
                {
                    return;
                }

                //Set args on this session
                if (!await session.SetArgs(args))
                {
                    return;
                }

                //Run the actual code
                await session.OnRequest();
            } catch (DeltaWebException wex)
            {
                await WriteStringToBody(e, wex.text, "text/plain", wex.httpCode);
            } catch (Exception ex)
            {
                await WriteStringToBody(e, $"Internal Server Error. Please try again later.\n\nDEBUG DATA:\nService={service.GetType().Name}\nAppVersion={conn.system_version_major}.{conn.system_version_minor}\nLibVersion={DeltaConnection.LIB_VERSION_MAJOR}.{DeltaConnection.LIB_VERSION_MINOR}\nDeltaServerInstanceID={conn.instanceId}\nRequestID={session._request_id}", "text/plain", 500);

                conn.Log("DeltaWebServer-OnHTTPRequest", $"Internal server error. Service={service.GetType().Name}, RequestID={session._request_id}, AppVersion={conn.system_version_major}.{conn.system_version_minor}, LibVersion={DeltaConnection.LIB_VERSION_MAJOR}.{DeltaConnection.LIB_VERSION_MINOR}, URL={e.Request.Path.Value}{e.Request.QueryString}, Exception={ex.Message}, StackTrace={ex.StackTrace}", DeltaLogLevel.High);
            }
        }