From 80ecb903cc37e3a1d820e3e43d30f801ca35dfab Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sun, 24 Feb 2019 15:12:31 -0800 Subject: [PATCH] modules/webroot: Return 404 before any 405 for non-existent resources. --- modules/webroot.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/modules/webroot.cc b/modules/webroot.cc index cf2e44a0e..c366d27b6 100644 --- a/modules/webroot.cc +++ b/modules/webroot.cc @@ -18,6 +18,9 @@ content_type(const mutable_buffer &out, const string_view &filename, const strin resource::response get_root(client &client, const resource::request &request); +resource::response +non_get_root(client &client, const resource::request &request); + static void init_files(); @@ -44,6 +47,30 @@ root_get root_resource, "GET", get_root }; +resource::method +root_put +{ + root_resource, "PUT", non_get_root +}; + +resource::method +root_post +{ + root_resource, "POST", non_get_root +}; + +resource::method +root_options +{ + root_resource, "OPTIONS", non_get_root +}; + +resource::method +root_delete +{ + root_resource, "DELETE", non_get_root +}; + conf::item webroot_path { @@ -79,6 +106,38 @@ init_files() } } +/// This handler exists because the root resource on path "/" catches +/// everything rejected by all the other registered resources; after that +/// happens if the method was not GET the client always gets a 405 even if +/// the path they specified truly does not exist. This handler allows us to +/// give them a 404 first instead by checking the path's existence; then a 405 +/// if it does exist and they did not use GET. +resource::response +non_get_root(client &client, + const resource::request &request) +{ + const auto &path + { + !request.head.path? + "index.html": + request.head.path == "/"? + "index.html": + request.head.path + }; + + const http::code code + { + files.count(lstrip(path, '/'))? + http::METHOD_NOT_ALLOWED: + http::NOT_FOUND + }; + + return resource::response + { + client, code + }; +} + resource::response get_root(client &client, const resource::request &request)