diff options
author | Sadie Powell <sadie@witchery.services> | 2020-12-04 14:16:26 +0000 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2020-12-04 14:18:01 +0000 |
commit | 151a902ced88b0c1f1791d975332bbe293259acb (patch) | |
tree | 7c66b8a35444206766c83546605310b616912dc7 | |
parent | 08572a9376e6f41109e233cb45d7e491ad1ebf07 (diff) |
Normalise paths in the httpd module.
-rw-r--r-- | src/modules/m_httpd.cpp | 27 | ||||
-rw-r--r-- | src/modules/m_httpd_config.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_httpd_stats.cpp | 13 |
3 files changed, 31 insertions, 11 deletions
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index efed34799..a155dd278 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -351,7 +351,32 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru return false; if (url.field_set & (1 << UF_PATH)) - out.path = uri.substr(url.field_data[UF_PATH].off, url.field_data[UF_PATH].len); + { + // Normalise the path. + std::vector<std::string> pathsegments; + irc::sepstream pathstream(uri.substr(url.field_data[UF_PATH].off, url.field_data[UF_PATH].len), '/'); + for (std::string pathsegment; pathstream.GetToken(pathsegment); ) + { + if (pathsegment == ".") + { + // Stay at the current level. + continue; + } + + if (pathsegment == "..") + { + // Traverse up to the previous level. + if (!pathsegments.empty()) + pathsegment.pop_back(); + continue; + } + + pathsegments.push_back(pathsegment); + } + + out.path.reserve(url.field_data[UF_PATH].len); + out.path.append("/").append(stdalgo::string::join(pathsegments, '/')); + } if (url.field_set & (1 << UF_FRAGMENT)) out.fragment = uri.substr(url.field_data[UF_FRAGMENT].off, url.field_data[UF_FRAGMENT].len); diff --git a/src/modules/m_httpd_config.cpp b/src/modules/m_httpd_config.cpp index bc669dae3..b8b1fd7a7 100644 --- a/src/modules/m_httpd_config.cpp +++ b/src/modules/m_httpd_config.cpp @@ -39,7 +39,7 @@ class ModuleHttpConfig : public Module, public HTTPRequestEventListener ModResult OnHTTPRequest(HTTPRequest& request) CXX11_OVERRIDE { - if ((request.GetPath() != "/config") && (request.GetPath() != "/config/")) + if (request.GetPath() != "/config") return MOD_RES_PASSTHRU; ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling HTTP request for %s", request.GetPath().c_str()); diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 0b674cf64..f24fd9aec 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -423,32 +423,27 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener ModResult HandleRequest(HTTPRequest* http) { - std::string path = http->GetPath(); - - if (path != "/stats" && path.substr(0, 7) != "/stats/") + if (http->GetPath() != "/stats") return MOD_RES_PASSTHRU; - if (path[path.size() - 1] == '/') - path.erase(path.size() - 1, 1); - ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling HTTP request for %s", http->GetPath().c_str()); bool found = true; std::stringstream data; data << "<inspircdstats>"; - if (path == "/stats") + if (http->GetPath() == "/stats") { data << Stats::ServerInfo << Stats::General << Stats::XLines << Stats::Modules << Stats::Channels << Stats::Users << Stats::Servers << Stats::Commands; } - else if (path == "/stats/general") + else if (http->GetPath() == "/stats/general") { data << Stats::General; } - else if (path == "/stats/users") + else if (http->GetPath() == "/stats/users") { if (enableparams) Stats::ListUsers(data, http->GetParsedURI().query_params); |