LibWeb: Use directory page when viewing a resource schemed directory URL

This commit is contained in:
Bastiaan van der Plaat 2023-12-26 10:12:35 +01:00 committed by Tim Flynn
parent b39d99cf2f
commit f8feca5d21
4 changed files with 28 additions and 18 deletions

View file

@ -43,7 +43,7 @@
<span class="folder" style="width: 24px; height: 24px;"></span>
<h1>Index of @path@</h1>
</header>
<p><a href="file://@parent_path@"><span class="open-parent"></span>Open Parent Directory</a></p>
<p><a href="@parent_url@"><span class="open-parent"></span>Open Parent Directory</a></p>
<hr>
@contents@
<hr>

View file

@ -52,10 +52,10 @@ ErrorOr<String> load_error_page(AK::URL const& url)
return TRY(String::from_utf8(generator.as_string_view()));
}
ErrorOr<String> load_file_directory_page(LoadRequest const& request)
ErrorOr<String> load_file_directory_page(AK::URL const& url)
{
// Generate HTML contents entries table
auto lexical_path = LexicalPath(request.url().serialize_path());
auto lexical_path = LexicalPath(url.serialize_path());
Core::DirIterator dt(lexical_path.string(), Core::DirIterator::Flags::SkipParentAndBaseDir);
Vector<ByteString> names;
while (dt.has_next())
@ -89,7 +89,7 @@ ErrorOr<String> load_file_directory_page(LoadRequest const& request)
StringBuilder builder;
SourceGenerator generator { builder };
generator.set("path", escape_html_entities(lexical_path.string()));
generator.set("parent_path", escape_html_entities(lexical_path.parent().string()));
generator.set("parent_url", TRY(String::formatted("file://{}", escape_html_entities(lexical_path.parent().string()))));
generator.set("contents", contents.to_byte_string());
generator.append(template_contents);
return TRY(String::from_utf8(generator.as_string_view()));

View file

@ -18,6 +18,6 @@ void set_directory_page_url(String);
ErrorOr<String> load_error_page(AK::URL const&);
ErrorOr<String> load_file_directory_page(LoadRequest const&);
ErrorOr<String> load_file_directory_page(AK::URL const&);
}

View file

@ -193,6 +193,21 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback
dbgln("ResourceLoader: Failed load of: \"{}\", \033[31;1mError: {}\033[0m, Duration: {}ms", url_for_logging, error_message, load_time_ms);
};
auto respond_directory_page = [log_success, log_failure](LoadRequest const& request, AK::URL const& url, SuccessCallback const& success_callback, ErrorCallback const& error_callback) {
auto maybe_response = load_file_directory_page(url);
if (maybe_response.is_error()) {
log_failure(request, maybe_response.error());
if (error_callback)
error_callback(ByteString::formatted("{}", maybe_response.error()), 500u, {}, {});
return;
}
log_success(request);
HashMap<ByteString, ByteString, CaseInsensitiveStringTraits> response_headers;
response_headers.set("Content-Type"sv, "text/html"sv);
success_callback(maybe_response.release_value().bytes(), response_headers, {});
};
if (is_port_blocked(url.port_or_default())) {
log_failure(request, ByteString::formatted("The port #{} is blocked", url.port_or_default()));
return;
@ -250,6 +265,12 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback
return;
}
// When resource URI is a directory use file directory loader to generate response
if (resource.value()->is_directory()) {
respond_directory_page(request, resource.value()->file_url(), success_callback, error_callback);
return;
}
auto data = resource.value()->data();
auto response_headers = response_headers_for_file(url.serialize_path());
@ -268,7 +289,7 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback
return;
}
FileRequest file_request(url.serialize_path(), [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request](ErrorOr<i32> file_or_error) {
FileRequest file_request(url.serialize_path(), [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request, respond_directory_page](ErrorOr<i32> file_or_error) {
--m_pending_loads;
if (on_load_counter_change)
on_load_counter_change();
@ -287,18 +308,7 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback
// When local file is a directory use file directory loader to generate response
auto maybe_is_valid_directory = Core::Directory::is_valid_directory(fd);
if (!maybe_is_valid_directory.is_error() && maybe_is_valid_directory.value()) {
auto maybe_response = load_file_directory_page(request);
if (maybe_response.is_error()) {
log_failure(request, maybe_response.error());
if (error_callback)
error_callback(ByteString::formatted("{}", maybe_response.error()), 500u, {}, {});
return;
}
log_success(request);
HashMap<ByteString, ByteString, CaseInsensitiveStringTraits> response_headers;
response_headers.set("Content-Type"sv, "text/html"sv);
success_callback(maybe_response.release_value().bytes(), response_headers, {});
respond_directory_page(request, request.url(), success_callback, error_callback);
return;
}