diff --git a/Services/WebServer/Client.cpp b/Services/WebServer/Client.cpp index c1ee2906cd..2de4c53fb6 100644 --- a/Services/WebServer/Client.cpp +++ b/Services/WebServer/Client.cpp @@ -38,9 +38,10 @@ namespace WebServer { -Client::Client(NonnullRefPtr socket, Core::Object* parent) +Client::Client(NonnullRefPtr socket, const String& root, Core::Object* parent) : Core::Object(parent) , m_socket(socket) + , m_root_path(root) { } @@ -86,7 +87,8 @@ void Client::handle_request(ByteBuffer raw_request) dbg() << "Canonical requested path: '" << requested_path << "'"; StringBuilder path_builder; - path_builder.append("/www/"); + path_builder.append(m_root_path); + path_builder.append('/'); path_builder.append(requested_path); auto real_path = path_builder.to_string(); diff --git a/Services/WebServer/Client.h b/Services/WebServer/Client.h index 35cdb4ab1c..d7791b3898 100644 --- a/Services/WebServer/Client.h +++ b/Services/WebServer/Client.h @@ -34,11 +34,12 @@ namespace WebServer { class Client final : public Core::Object { C_OBJECT(Client); + public: void start(); private: - Client(NonnullRefPtr, Core::Object* parent); + Client(NonnullRefPtr, const String&, Core::Object* parent); void handle_request(ByteBuffer); void send_response(StringView, const HTTP::HttpRequest&); @@ -49,6 +50,7 @@ private: void handle_directory_listing(const String& requested_path, const String& real_path, const HTTP::HttpRequest&); NonnullRefPtr m_socket; + String m_root_path; }; } diff --git a/Services/WebServer/main.cpp b/Services/WebServer/main.cpp index 7e218b8bb8..807f742e50 100644 --- a/Services/WebServer/main.cpp +++ b/Services/WebServer/main.cpp @@ -27,6 +27,7 @@ #include "Client.h" #include #include +#include #include #include #include @@ -34,11 +35,13 @@ int main(int argc, char** argv) { u16 default_port = 8000; + const char* root_path = "/www"; int port = default_port; Core::ArgsParser args_parser; - args_parser.add_positional_argument(port, "Port to listen on", "port", Core::ArgsParser::Required::No); + args_parser.add_option(port, "Port to listen on", "port", 'p', "port"); + args_parser.add_positional_argument(root_path, "Path to serve the contents of", "path", Core::ArgsParser::Required::No); args_parser.parse(argc, argv); if ((u16)port != port) { @@ -46,6 +49,13 @@ int main(int argc, char** argv) port = default_port; } + auto real_root_path = Core::File::real_path_for(root_path); + + if (!Core::File::exists(real_root_path)) { + fprintf(stderr, "Root path does not exist: '%s'\n", root_path); + return 1; + } + if (pledge("stdio accept rpath inet unix cpath fattr", nullptr) < 0) { perror("pledge"); return 1; @@ -58,14 +68,14 @@ int main(int argc, char** argv) server->on_ready_to_accept = [&] { auto client_socket = server->accept(); ASSERT(client_socket); - auto client = WebServer::Client::construct(client_socket.release_nonnull(), server); + auto client = WebServer::Client::construct(client_socket.release_nonnull(), real_root_path, server); client->start(); }; server->listen({}, port); printf("Listening on 0.0.0.0:%d\n", port); - if (unveil("/www", "r") < 0) { + if (unveil(real_root_path.characters(), "r") < 0) { perror("unveil"); return 1; }