-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDirectoryListingModule.hpp
More file actions
69 lines (58 loc) · 2.55 KB
/
DirectoryListingModule.hpp
File metadata and controls
69 lines (58 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <filesystem>
#include <fstream>
#include "ziapi/Config.hpp"
#include "ziapi/Module.hpp"
class DirectoryListingModule : public ziapi::IHandlerModule {
public:
void Init(const ziapi::config::Node &cfg) override
{
/// In our config, we can specify which folder our module serves.
/// We fetch the "modules.directoryListing.root" variable from the config
/// as a string.
root_ = cfg["modules"]["directoryListing"]["root"].AsString();
}
[[nodiscard]] ziapi::Version GetVersion() const noexcept override { return {4, 0, 0}; }
[[nodiscard]] ziapi::Version GetCompatibleApiVersion() const noexcept override { return {4, 0, 0}; }
[[nodiscard]] const char *GetName() const noexcept override { return "DirectoryListing"; }
[[nodiscard]] const char *GetDescription() const noexcept override
{
return "Give access to a filesystem over HTTP";
}
[[nodiscard]] double GetHandlerPriority() const noexcept override
{
/// Our module doesn't have any specific priority requirements.
return 0.5f;
}
[[nodiscard]] bool ShouldHandle(const ziapi::http::Context &ctx, const ziapi::http::Request &req) const override
{
/// We only want to handle GET requests.
return req.method == ziapi::http::method::kGet;
}
void Handle(ziapi::http::Context &ctx, const ziapi::http::Request &req, ziapi::http::Response &res) override
{
/// Here we concat the root path from our config (e.g /var/www/) with the target from our request (e.g.
/// index.html) to get the full path of our file.
auto filepath = std::filesystem::path(root_) / std::filesystem::path(req.target);
std::error_code ec;
/// If the file is a directory let's provide a list of all the files as a response.
if (std::filesystem::is_directory(filepath, ec)) {
std::ostringstream ss;
for (const auto &entry : std::filesystem::directory_iterator(filepath)) {
ss << entry.path().string() << "\n";
}
return;
} else {
/// If the file is not a directory, we assume it's a regular file and we just send its contents with the
/// response.
std::ifstream file_stream(filepath.filename());
std::ostringstream ss;
ss << file_stream.rdbuf();
res.body = ss.str();
return;
}
res.status_code = ziapi::http::Code::kNotFound;
res.reason = ziapi::http::reason::kNotFound;
}
private:
std::string root_;
};