summaryrefslogtreecommitdiff
path: root/src/modules/m_httpd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/m_httpd.cpp')
-rw-r--r--src/modules/m_httpd.cpp27
1 files changed, 26 insertions, 1 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);