diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-12 21:18:04 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-12 21:18:04 +0100 |
commit | 083f3edcb00769fa2a0b95ad8d9d2a46e54d3778 (patch) | |
tree | 43a315f8f88a94db408c09ede6fbdb35bdd495be /Servers | |
parent | 90fec9c7327fcee65bf40342d303641709dca070 (diff) | |
download | serenity-083f3edcb00769fa2a0b95ad8d9d2a46e54d3778.zip |
WebServer: Add basic directory listings
If a directory does not have an index.html file, we will now generate
a directory listing HTML document for that directory on the fly. :^)
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/WebServer/Client.cpp | 65 | ||||
-rw-r--r-- | Servers/WebServer/Client.h | 2 |
2 files changed, 59 insertions, 8 deletions
diff --git a/Servers/WebServer/Client.cpp b/Servers/WebServer/Client.cpp index 0114d19559..cd1984478d 100644 --- a/Servers/WebServer/Client.cpp +++ b/Servers/WebServer/Client.cpp @@ -28,6 +28,7 @@ #include <AK/FileSystemPath.h> #include <AK/StringBuilder.h> #include <LibCore/DateTime.h> +#include <LibCore/DirIterator.h> #include <LibCore/File.h> #include <LibCore/HttpRequest.h> #include <stdio.h> @@ -79,22 +80,37 @@ void Client::handle_request(ByteBuffer raw_request) return; } - FileSystemPath canonical_path(request.resource()); - dbg() << "Requested canonical path: '" << canonical_path.string() << "'"; + auto requested_path = canonicalized_path(request.resource()); + dbg() << "Canonical requested path: '" << requested_path << "'"; StringBuilder path_builder; path_builder.append("/www/"); - path_builder.append(canonical_path.string()); - - if (Core::File::is_directory(path_builder.to_string())) - path_builder.append("/index.html"); + path_builder.append(requested_path); + auto real_path = path_builder.to_string(); + + if (Core::File::is_directory(real_path)) { + StringBuilder index_html_path_builder; + index_html_path_builder.append(real_path); + index_html_path_builder.append("/index.html"); + auto index_html_path = index_html_path_builder.to_string(); + if (!Core::File::exists(index_html_path)) { + handle_directory_listing(requested_path, real_path, request); + return; + } + real_path = index_html_path; + } - auto file = Core::File::construct(path_builder.to_string()); + auto file = Core::File::construct(real_path); if (!file->open(Core::File::ReadOnly)) { send_error_response(404, "Not found, bro!", request); return; } + send_response(file->read_all(), request); +} + +void Client::send_response(StringView response, const Core::HttpRequest& request) +{ StringBuilder builder; builder.append("HTTP/1.0 200 OK\r\n"); builder.append("Server: WebServer (SerenityOS)\r\n"); @@ -102,11 +118,44 @@ void Client::handle_request(ByteBuffer raw_request) builder.append("\r\n"); m_socket->write(builder.to_string()); - m_socket->write(file->read_all()); + m_socket->write(response); log_response(200, request); } +void Client::handle_directory_listing(const String& requested_path, const String& real_path, const Core::HttpRequest& request) +{ + StringBuilder builder; + + builder.append("<!DOCTYPE html>\n"); + builder.append("<html>\n"); + builder.append("<head><title>Index of "); + builder.append(requested_path); + builder.append("</title></head>\n"); + builder.append("<body>\n"); + builder.append("<h1>Index of "); + builder.append(requested_path); + builder.append("</h1>\n"); + builder.append("<ul>\n"); + + Core::DirIterator dt(real_path); + while (dt.has_next()) { + auto name = dt.next_path(); + builder.append("<li>"); + builder.append("<a href=\""); + builder.append(name); + builder.append("\">"); + builder.append(name); + builder.append("</a></li>\n"); + } + + builder.append("</ul>\n"); + builder.append("</body>\n"); + builder.append("</html>\n"); + + send_response(builder.to_string(), request); +} + void Client::send_error_response(unsigned code, const StringView& message, const Core::HttpRequest& request) { StringBuilder builder; diff --git a/Servers/WebServer/Client.h b/Servers/WebServer/Client.h index aa57b17bba..9b0061b133 100644 --- a/Servers/WebServer/Client.h +++ b/Servers/WebServer/Client.h @@ -44,9 +44,11 @@ private: Client(NonnullRefPtr<Core::TCPSocket>, Core::Object* parent); void handle_request(ByteBuffer); + void send_response(StringView, const Core::HttpRequest&); void send_error_response(unsigned code, const StringView& message, const Core::HttpRequest&); void die(); void log_response(unsigned code, const Core::HttpRequest&); + void handle_directory_listing(const String& requested_path, const String& real_path, const Core::HttpRequest&); NonnullRefPtr<Core::TCPSocket> m_socket; }; |