1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 08:47:34 +00:00

AK+Everywhere: Change URL::path() to serialize_path()

This now defaults to serializing the path with percent decoded segments
(which is what all callers expect), but has an option not to. This fixes
`file://` URLs with spaces in their paths.

The name has been changed to serialize_path() path to make it more clear
that this method will generate a new string each call (except for the
cannot_be_a_base_url() case). A few callers have then been updated to
avoid repeatedly calling this function.
This commit is contained in:
MacDue 2023-04-14 20:12:03 +01:00 committed by Andreas Kling
parent 5acd40c525
commit 35612c6a7f
42 changed files with 131 additions and 123 deletions

View file

@ -18,7 +18,7 @@ DeprecatedString Document::render_to_html() const
StringBuilder html_builder;
html_builder.append("<!DOCTYPE html>\n<html>\n"sv);
html_builder.append("<head>\n<title>"sv);
html_builder.append(m_url.path());
html_builder.append(m_url.serialize_path());
html_builder.append("</title>\n</head>\n"sv);
html_builder.append("<body>\n"sv);
for (auto& line : m_lines) {

View file

@ -49,9 +49,9 @@ ErrorOr<ByteBuffer> HttpRequest::to_raw_request() const
TRY(builder.try_append(method_name()));
TRY(builder.try_append(' '));
// NOTE: The percent_encode is so that e.g. spaces are properly encoded.
auto path = m_url.path();
auto path = m_url.serialize_path();
VERIFY(!path.is_empty());
TRY(builder.try_append(URL::percent_encode(m_url.path(), URL::PercentEncodeSet::EncodeURI)));
TRY(builder.try_append(URL::percent_encode(path, URL::PercentEncodeSet::EncodeURI)));
if (!m_url.query().is_empty()) {
TRY(builder.try_append('?'));
TRY(builder.try_append(m_url.query()));

View file

@ -867,7 +867,7 @@ void TerminalWidget::mousemove_event(GUI::MouseEvent& event)
auto handlers = Desktop::Launcher::get_handlers_for_url(attribute.href);
if (!handlers.is_empty()) {
auto url = URL(attribute.href);
auto path = url.path();
auto path = url.serialize_path();
auto app_file = Desktop::AppFile::get_for_app(LexicalPath::basename(handlers[0]));
auto app_name = app_file->is_valid() ? app_file->name() : LexicalPath::basename(handlers[0]);
@ -1146,7 +1146,7 @@ void TerminalWidget::context_menu_event(GUI::ContextMenuEvent& event)
}));
m_context_menu_for_hyperlink->add_action(GUI::Action::create("Copy &Name", [&](auto&) {
// file://courage/home/anon/something -> /home/anon/something
auto path = URL(m_context_menu_href).path();
auto path = URL(m_context_menu_href).serialize_path();
// /home/anon/something -> something
auto name = LexicalPath::basename(path);
GUI::Clipboard::the().set_plain_text(name);
@ -1177,7 +1177,7 @@ void TerminalWidget::drop_event(GUI::DropEvent& event)
send_non_user_input(" "sv.bytes());
if (url.scheme() == "file")
send_non_user_input(url.path().bytes());
send_non_user_input(url.serialize_path().bytes());
else
send_non_user_input(url.to_deprecated_string().bytes());

View file

@ -680,7 +680,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm& r
// a body.
// NOTE: URLs such as "about:config" are handled during navigation and result in a network error in the context
// of fetching.
if (request->current_url().path() == "blank"sv) {
if (request->current_url().serialize_path() == "blank"sv) {
auto response = Infrastructure::Response::create(vm);
response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes())));
auto header = MUST(Infrastructure::Header::from_string_pair("Content-Type"sv, "text/html;charset=utf-8"sv));

View file

@ -310,7 +310,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// - parsedReferrers origin is not same origin with origin
// then set requests referrer to "client".
// FIXME: Actually use the given origin once we have https://url.spec.whatwg.org/#concept-url-origin.
if ((parsed_referrer.scheme() == "about"sv && parsed_referrer.path() == "client"sv) || !HTML::Origin().is_same_origin(origin)) {
if ((parsed_referrer.scheme() == "about"sv && parsed_referrer.serialize_path() == "client"sv) || !HTML::Origin().is_same_origin(origin)) {
request->set_referrer(Infrastructure::Request::Referrer::Client);
}
// 4. Otherwise, set requests referrer to parsedReferrer.

View file

@ -39,7 +39,7 @@ static bool url_matches_about_blank(AK::URL const& url)
{
// A URL matches about:blank if its scheme is "about", its path contains a single string "blank", its username and password are the empty string, and its host is null.
return url.scheme() == "about"sv
&& url.path() == "blank"sv
&& url.serialize_path() == "blank"sv
&& url.username().is_empty()
&& url.password().is_empty()
&& url.host().is_null();

View file

@ -121,7 +121,7 @@ static bool url_matches_about_blank(AK::URL const& url)
{
// A URL matches about:blank if its scheme is "about", its path contains a single string "blank", its username and password are the empty string, and its host is null.
return url.scheme() == "about"sv
&& url.path() == "blank"sv
&& url.serialize_path() == "blank"sv
&& url.username().is_empty()
&& url.password().is_empty()
&& url.host().is_null();

View file

@ -293,7 +293,7 @@ DeprecatedString HTMLHyperlinkElementUtils::pathname() const
// 4. If url's cannot-be-a-base-URL is true, then return url's path[0].
// 5. If url's path is empty, then return the empty string.
// 6. Return "/", followed by the strings in url's path (including empty strings), separated from each other by "/".
return m_url->path();
return m_url->serialize_path();
}
// https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-pathname

View file

@ -233,7 +233,7 @@ WebIDL::ExceptionOr<String> Location::pathname() const
return WebIDL::SecurityError::create(realm(), "Location's relevant document is not same origin-domain with the entry settings object's origin"sv);
// 2. Return the result of URL path serializing this Location object's url.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url().path()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url().serialize_path()));
}
WebIDL::ExceptionOr<void> Location::set_pathname(String const&)

View file

@ -92,7 +92,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::pathname() const
{
auto& vm = realm().vm();
// The pathname getter steps are to return the result of URL path serializing this's WorkerGlobalScope object's url.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope->url().path()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope->url().serialize_path()));
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-search

View file

@ -144,7 +144,7 @@ static bool build_image_document(DOM::Document& document, ByteBuffer const& data
auto title_element = DOM::create_element(document, HTML::TagNames::title, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(head_element->append_child(title_element));
auto basename = LexicalPath::basename(document.url().path());
auto basename = LexicalPath::basename(document.url().serialize_path());
auto title_text = document.heap().allocate<DOM::Text>(document.realm(), document, DeprecatedString::formatted("{} [{}x{}]", basename, bitmap->width(), bitmap->height())).release_allocated_value_but_fixme_should_propagate_errors();
MUST(title_element->append_child(*title_text));

View file

@ -103,7 +103,7 @@ void Resource::did_load(Badge<ResourceLoader>, ReadonlyBytes data, HashMap<Depre
// FIXME: "The Quite OK Image Format" doesn't have an official mime type yet,
// and servers like nginx will send a generic octet-stream mime type instead.
// Let's use image/x-qoi for now, which is also what our Core::MimeData uses & would guess.
if (m_mime_type == "application/octet-stream" && url().path().ends_with(".qoi"sv))
if (m_mime_type == "application/octet-stream" && url().serialize_path().ends_with(".qoi"sv))
m_mime_type = "image/x-qoi";
} else if (url().scheme() == "data" && !url().data_mime_type().is_empty()) {
dbgln_if(RESOURCE_DEBUG, "This is a data URL with mime-type _{}_", url().data_mime_type());
@ -113,7 +113,7 @@ void Resource::did_load(Badge<ResourceLoader>, ReadonlyBytes data, HashMap<Depre
if (content_type_options.value_or("").equals_ignoring_ascii_case("nosniff"sv)) {
m_mime_type = "text/plain";
} else {
m_mime_type = Core::guess_mime_type_based_on_filename(url().path());
m_mime_type = Core::guess_mime_type_based_on_filename(url().serialize_path());
}
}

View file

@ -237,7 +237,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has
if (!m_page.has_value())
return;
FileRequest file_request(url.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](ErrorOr<i32> file_or_error) {
--m_pending_loads;
if (on_load_counter_change)
on_load_counter_change();
@ -275,7 +275,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has
// NOTE: For file:// URLs, we have to guess the MIME type, since there's no HTTP header to tell us what this is.
// We insert a fake Content-Type header here, so that clients can use it to learn the MIME type.
HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> response_headers;
auto mime_type = Core::guess_mime_type_based_on_filename(request.url().path());
auto mime_type = Core::guess_mime_type_based_on_filename(request.url().serialize_path());
response_headers.set("Content-Type"sv, mime_type);
success_callback(data, response_headers, {});

View file

@ -323,7 +323,7 @@ WebIDL::ExceptionOr<String> URL::pathname() const
auto& vm = realm().vm();
// The pathname getter steps are to return the result of URL path serializing thiss URL.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_url.path()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_url.serialize_path()));
}
// https://url.spec.whatwg.org/#ref-for-dom-url-pathname%E2%91%A0

View file

@ -26,10 +26,11 @@ DeprecatedString ConnectionInfo::resource_name() const
// The "resource-name" can be constructed by concatenating the following:
StringBuilder builder;
// "/" if the path component is empty
if (m_url.path().is_empty())
auto path = m_url.serialize_path();
if (path.is_empty())
builder.append('/');
// The path component
builder.append(m_url.path());
builder.append(path);
// "?" if the query component is non-empty
if (!m_url.query().is_empty())
builder.append('?');