From 97f2c5bf0cd00862b275a32241e27d2568a78a98 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 16 Dec 2019 20:07:06 +0800 Subject: [PATCH] Refactor http static file server path resolving. --- trunk/src/protocol/srs_http_stack.cpp | 25 +++++++++++++++++-------- trunk/src/protocol/srs_http_stack.hpp | 2 +- trunk/src/utest/srs_utest_http.cpp | 12 ++++++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index 1285ecf93..cd258380a 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -304,23 +304,32 @@ srs_error_t SrsHttpNotFoundHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHt return srs_go_http_error(w, SRS_CONSTS_HTTP_NotFound); } -string srs_http_fs_fullpath(string dir, string upath, string pattern) +string srs_http_fs_fullpath(string dir, string pattern, string upath) { // add default pages. if (srs_string_ends_with(upath, "/")) { upath += SRS_HTTP_DEFAULT_PAGE; } - string fullpath = dir + "/"; - - // remove the virtual directory. + // Remove the virtual directory. + // For example: + // pattern=/api, the virtual directory is api, upath=/api/index.html, fullpath={dir}/index.html + // pattern=/api, the virtual directory is api, upath=/api/views/index.html, fullpath={dir}/views/index.html + // The vhost prefix is ignored, for example: + // pattern=ossrs.net/api, the vhost is ossrs.net, the pattern equals to /api under this vhost, + // so the virtual directory is also api size_t pos = pattern.find("/"); + string filename = upath; if (upath.length() > pattern.length() && pos != string::npos) { - fullpath += upath.substr(pattern.length() - pos); - } else { - fullpath += upath; + filename = upath.substr(pattern.length() - pos); } + string fullpath = srs_string_trim_end(dir, "/"); + if (!srs_string_starts_with(filename, "/")) { + fullpath += "/"; + } + fullpath += filename; + return fullpath; } @@ -354,7 +363,7 @@ srs_error_t SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMes srs_assert(entry); string upath = r->path(); - string fullpath = srs_http_fs_fullpath(dir, upath, entry->pattern); + string fullpath = srs_http_fs_fullpath(dir, entry->pattern, upath); // stat current dir, if exists, return error. if (!_srs_path_exists(fullpath)) { diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index a0f0dd88a..f09ee9668 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -281,7 +281,7 @@ public: typedef bool (*_pfn_srs_path_exists)(std::string path); // Build the file path from request r. -extern std::string srs_http_fs_fullpath(std::string dir, std::string upath, std::string pattern); +extern std::string srs_http_fs_fullpath(std::string dir, std::string pattern, std::string upath); // FileServer returns a handler that serves HTTP requests // with the contents of the file system rooted at root. diff --git a/trunk/src/utest/srs_utest_http.cpp b/trunk/src/utest/srs_utest_http.cpp index 5aaa863bd..32de06d0c 100644 --- a/trunk/src/utest/srs_utest_http.cpp +++ b/trunk/src/utest/srs_utest_http.cpp @@ -185,7 +185,7 @@ public: } }; -bool _mock_srs_path_exists(std::string path) +bool _mock_srs_path_exists(std::string /*path*/) { return true; } @@ -195,7 +195,15 @@ VOID TEST(ProtocolHTTPTest, BasicHandlers) srs_error_t err; if (true) { - EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp", "/tmp/index.html", "/").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp", "/", "/").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp", "/", "/index.html").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp/", "/", "/index.html").c_str()); + EXPECT_STREQ("/tmp/ndex.html", srs_http_fs_fullpath("/tmp/", "//", "/index.html").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp/", "/api", "/api/index.html").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp/", "ossrs.net/api", "/api/index.html").c_str()); + EXPECT_STREQ("/tmp/views/index.html", srs_http_fs_fullpath("/tmp/", "/api", "/api/views/index.html").c_str()); + EXPECT_STREQ("/tmp/index.html", srs_http_fs_fullpath("/tmp/", "/api/", "/api/index.html").c_str()); + EXPECT_STREQ("/tmp/ndex.html", srs_http_fs_fullpath("/tmp/", "/api//", "/api/index.html").c_str()); } if (true) {