示例#1
0
        private void HandleRequestInternal(HttpRequestArgs args)
        {
            // TODO: verify the performance of this pile of reflection

            // any of the endpoints will do here; it's done this way in order to avoid hardcoding the namespace
            string endpointsNamespace = typeof(StatusEndpoint).Namespace;

            // get all endpoint classes
            var allEndpoints = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Namespace == endpointsNamespace);

            // get all endpoints that contain the HttpEndpointAttribute
            var attributedEndpoints = allEndpoints.Select(x => new Tuple <Type, Attribute>(x, x.GetCustomAttribute(typeof(HttpEndpointAttribute)))).Where(x => x.Item2 != null);

            // get the endpoint that should serve the request
            var endpointTuple = attributedEndpoints.FirstOrDefault(x => ((HttpEndpointAttribute)x.Item2).ShouldServeRequest(args.Url));

            if (endpointTuple == null)
            {
                // TODO: send some response
                args.SetResponse(404, new HttpErrorResponse("Endpoint not found"));
                return;
            }

            var endpointAttribute = (HttpEndpointAttribute)endpointTuple.Item2;
            var endpoint          = endpointTuple.Item1;

            // locate the correct method for requested HTTP method
            var attributedMethods = endpoint.GetMethods(BindingFlags.Public | BindingFlags.Static).Select(x => new Tuple <MethodInfo, Attribute>(x, x.GetCustomAttribute(typeof(HttpMethodAttribute)))).Where(x => x.Item2 != null);
            var methodTuple       = attributedMethods.FirstOrDefault(x => ((HttpMethodAttribute)x.Item2).Method == args.Context.Request.HttpMethod);

            if (methodTuple == null)
            {
                // TODO: send some response
                args.SetResponse(405, new HttpErrorResponse("HTTP method not supported for this endpoint"));
                return;
            }

            // determine if the endpoint contains an asterisk
            if (endpointAttribute.UrlContainsArguments)
            {
                args.UrlArguments = endpointAttribute.GetUrlArguments(args.Url);
            }

            // call the handler
            methodTuple.Item1.Invoke(null, new object[] { args });
        }
示例#2
0
        private void HandleRequest(HttpListenerContext ctx)
        {
            HttpRequestArgs args = new HttpRequestArgs(ctx);

            ctx.Response.ContentType = "application/json";

            // if the HTTP server is closing, ignore all incoming requests
            if (isTerminating)
            {
                args.SetResponse(503, new HttpErrorResponse("The server is shutting down"));
            }
            else if (args.Url == null)
            {
                args.SetResponse(403, new HttpErrorResponse("Invalid API key"));
            }
            else
            {
                try
                {
                    HandleRequestInternal(args);
                }
                catch (Exception ex)
                {
                    args.SetResponse(500, new HttpErrorResponse($"An exception has occurred during request processing:\n{ex}"));
                }
            }

            if (args.Response == null)
            {
                Logger.Log("Http", $"Request {args.Url} did not produce any response", Logger.MessageLevel.Warning);
                args.Response = new HttpErrorResponse("Empty response");
            }

            byte[] resp = args.Response.ToJsonResponse();
            ctx.Response.ContentLength64 = resp.LongLength;
            ctx.Response.OutputStream.Write(resp);

            ctx.Response.Close();
        }