From d8e2c03b25a49bdc6b582df6f9118fb0c84903c4 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Mon, 26 Sep 2022 12:58:42 -0600 Subject: [PATCH 1/4] Adds support for serving static files out of a directory --- plugins/experimental/statichit/statichit.cc | 90 +++++++++++++++++---- 1 file changed, 75 insertions(+), 15 deletions(-) diff --git a/plugins/experimental/statichit/statichit.cc b/plugins/experimental/statichit/statichit.cc index 09bc6860916..aad6f7758b3 100644 --- a/plugins/experimental/statichit/statichit.cc +++ b/plugins/experimental/statichit/statichit.cc @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -62,21 +63,79 @@ static int StaticHitInterceptHook(TSCont contp, TSEvent event, void *edata); static int StaticHitTxnHook(TSCont contp, TSEvent event, void *edata); struct StaticHitConfig { - explicit StaticHitConfig(const std::string &filePath, const std::string &mimeType, bool disableExact) - : filePath(filePath), mimeType(mimeType), disableExact(disableExact) + explicit StaticHitConfig(const std::string &fileOrDir, const std::string &mimeType, bool exact) : mimeType(mimeType) { + std::filesystem::path base_path; + + if (fileOrDir.find('/') != 0) { + base_path = std::filesystem::weakly_canonical(std::string(TSConfigDirGet()) + "/" + fileOrDir); + } else { + base_path = std::filesystem::weakly_canonical(fileOrDir); + } + + if (std::filesystem::is_directory(base_path)) { + dirPath = base_path; + filePath = ""; + disableExact = true; + } else if (std::filesystem::is_regular_file(base_path)) { + dirPath = ""; + filePath = base_path; + disableExact = exact; + } else { + VERROR("Invalid file path: %s", filePath.c_str()); + filePath = ""; + dirPath = ""; + } } ~StaticHitConfig() { TSContDestroy(cont); } + std::string + makePath(TSHttpTxn txnp) const + { + if (!dirPath.empty()) { + TSMBuffer reqp; + TSMLoc hdr_loc = nullptr, url_loc = nullptr; + + if (TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) { + if (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc)) { + int path_len = 0; + auto path = TSUrlPathGet(reqp, url_loc, &path_len); + + std::filesystem::path requested_file_path( + std::filesystem::weakly_canonical(dirPath / std::string_view{path, static_cast(path_len)})); + + TSHandleMLocRelease(reqp, hdr_loc, url_loc); + TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); + + if (std::equal(dirPath.begin(), dirPath.end(), requested_file_path.begin()) && + std::filesystem::is_regular_file(requested_file_path)) { + return requested_file_path; + } else { + return ""; + } + } else { + TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); + return ""; + } + } else { + return ""; + } + } else { + return filePath; + } + } + + std::filesystem::path dirPath; std::string filePath; - std::string mimeType; - int successCode = 200; - int failureCode = 404; - int maxAge = 0; + std::string mimeType = ""; + int successCode = 200; + int failureCode = 404; + int maxAge = 0; bool disableExact = false; + bool isDirectory = false; TSCont cont; }; @@ -166,12 +225,16 @@ struct StaticHitRequest { std::string mimeType; static StaticHitRequest * - createStaticHitRequest(StaticHitConfig *tc) + createStaticHitRequest(StaticHitConfig *tc, TSHttpTxn txn) { StaticHitRequest *shr = new StaticHitRequest; std::ifstream ifstr; - ifstr.open(tc->filePath); + auto filePath = tc->makePath(txn); + + VDEBUG("Requested file path: %s", filePath.c_str()); + + ifstr.open(filePath); if (!ifstr) { shr->statusCode = tc->failureCode; return shr; @@ -485,9 +548,9 @@ StaticHitInterceptHook(TSCont contp, TSEvent event, void *edata) static void StaticHitSetupIntercept(StaticHitConfig *cfg, TSHttpTxn txn) { - StaticHitRequest *req = StaticHitRequest::createStaticHitRequest(cfg); + StaticHitRequest *req = StaticHitRequest::createStaticHitRequest(cfg, txn); + if (req == nullptr) { - VERROR("could not create request for %s", cfg->filePath.c_str()); return; } @@ -651,15 +714,12 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSE } if (filePath.size() == 0) { - printf("Need to specify --file-path\n"); + VERROR("Need to specify --file-path\n"); return TS_ERROR; } - if (filePath.find('/') != 0) { - filePath = std::string(TSConfigDirGet()) + '/' + filePath; - } - StaticHitConfig *tc = new StaticHitConfig(filePath, mimeType, disableExact); + if (maxAge > 0) { tc->maxAge = maxAge; } From 22230d4bb09b8c40650e5487b5bb4035431459e3 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Mon, 26 Sep 2022 19:10:17 -0600 Subject: [PATCH 2/4] Change makePath to take a output container, and return string_view instead --- plugins/experimental/statichit/statichit.cc | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/experimental/statichit/statichit.cc b/plugins/experimental/statichit/statichit.cc index aad6f7758b3..8867e29290c 100644 --- a/plugins/experimental/statichit/statichit.cc +++ b/plugins/experimental/statichit/statichit.cc @@ -90,8 +90,8 @@ struct StaticHitConfig { ~StaticHitConfig() { TSContDestroy(cont); } - std::string - makePath(TSHttpTxn txnp) const + std::string_view + makePath(TSHttpTxn txnp, std::string &output) const { if (!dirPath.empty()) { TSMBuffer reqp; @@ -110,19 +110,20 @@ struct StaticHitConfig { if (std::equal(dirPath.begin(), dirPath.end(), requested_file_path.begin()) && std::filesystem::is_regular_file(requested_file_path)) { - return requested_file_path; + output = requested_file_path.string(); + return {output.c_str(), output.size()}; } else { - return ""; + return {}; } } else { TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); - return ""; + return {}; } } else { - return ""; + return {}; } } else { - return filePath; + return {filePath}; } } @@ -229,12 +230,12 @@ struct StaticHitRequest { { StaticHitRequest *shr = new StaticHitRequest; std::ifstream ifstr; + std::string output; + std::string_view filePath = tc->makePath(txn, output); - auto filePath = tc->makePath(txn); + VDEBUG("Requested file path: %s", filePath.data()); - VDEBUG("Requested file path: %s", filePath.c_str()); - - ifstr.open(filePath); + ifstr.open(filePath.data()); if (!ifstr) { shr->statusCode = tc->failureCode; return shr; From 0fa6c47d15bedd73c1eeff5ad2c4dfc6bb804307 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Thu, 13 Oct 2022 16:13:01 -0600 Subject: [PATCH 3/4] Fixes per AMC's review --- plugins/experimental/statichit/statichit.cc | 28 ++++++++------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/plugins/experimental/statichit/statichit.cc b/plugins/experimental/statichit/statichit.cc index 8867e29290c..192675119ca 100644 --- a/plugins/experimental/statichit/statichit.cc +++ b/plugins/experimental/statichit/statichit.cc @@ -65,26 +65,21 @@ static int StaticHitTxnHook(TSCont contp, TSEvent event, void *edata); struct StaticHitConfig { explicit StaticHitConfig(const std::string &fileOrDir, const std::string &mimeType, bool exact) : mimeType(mimeType) { - std::filesystem::path base_path; + std::filesystem::path base_path{fileOrDir}; - if (fileOrDir.find('/') != 0) { - base_path = std::filesystem::weakly_canonical(std::string(TSConfigDirGet()) + "/" + fileOrDir); - } else { - base_path = std::filesystem::weakly_canonical(fileOrDir); + if (!base_path.is_absolute()) { + base_path = std::filesystem::path(TSConfigDirGet()) / base_path; } + base_path = std::filesystem::weakly_canonical(base_path); if (std::filesystem::is_directory(base_path)) { dirPath = base_path; filePath = ""; disableExact = true; - } else if (std::filesystem::is_regular_file(base_path)) { + } else { dirPath = ""; filePath = base_path; disableExact = exact; - } else { - VERROR("Invalid file path: %s", filePath.c_str()); - filePath = ""; - dirPath = ""; } } @@ -93,6 +88,8 @@ struct StaticHitConfig { std::string_view makePath(TSHttpTxn txnp, std::string &output) const { + std::string_view ret = {}; + if (!dirPath.empty()) { TSMBuffer reqp; TSMLoc hdr_loc = nullptr, url_loc = nullptr; @@ -111,20 +108,17 @@ struct StaticHitConfig { if (std::equal(dirPath.begin(), dirPath.end(), requested_file_path.begin()) && std::filesystem::is_regular_file(requested_file_path)) { output = requested_file_path.string(); - return {output.c_str(), output.size()}; - } else { - return {}; + ret = {output.c_str(), output.size()}; } } else { TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); - return {}; } - } else { - return {}; } } else { - return {filePath}; + ret = {filePath}; } + + return ret; } std::filesystem::path dirPath; From 566b9c2c7dc90587c8e88d4783e54cc75cffe29b Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Tue, 8 Nov 2022 08:44:04 +0000 Subject: [PATCH 4/4] Make all clang compilers happy, maybe --- plugins/experimental/statichit/statichit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/experimental/statichit/statichit.cc b/plugins/experimental/statichit/statichit.cc index 192675119ca..7b2824f5547 100644 --- a/plugins/experimental/statichit/statichit.cc +++ b/plugins/experimental/statichit/statichit.cc @@ -115,7 +115,7 @@ struct StaticHitConfig { } } } else { - ret = {filePath}; + ret = filePath; } return ret;