/* * Copyright (c) 2023, Tim Flynn * Copyright (c) 2023, Cameron Youell * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #if defined(ENABLE_PUBLIC_SUFFIX) # include #endif namespace WebView { static Optional query_public_suffix_list(StringView url_string) { auto out = MUST(String::from_utf8(url_string)); if (!out.contains("://"sv)) out = MUST(String::formatted("https://{}"sv, out)); auto url = URL::create_with_url_or_path(out.to_deprecated_string()); if (!url.is_valid()) return {}; #if defined(ENABLE_PUBLIC_SUFFIX) if (url.host().has() || url.host().has()) return url; if (url.scheme() != "http"sv && url.scheme() != "https"sv) return url; if (url.host().has()) { auto const& host = url.host().get(); if (auto public_suffix = MUST(PublicSuffixData::the()->get_public_suffix(host)); public_suffix.has_value()) return url; if (host.ends_with_bytes(".local"sv) || host.ends_with_bytes("localhost"sv)) return url; } return {}; #else return url; #endif } Optional sanitize_url(StringView url, Optional search_engine, AppendTLD append_tld) { if (FileSystem::exists(url)) { auto path = FileSystem::real_path(url); if (path.is_error()) return {}; return URL::create_with_file_scheme(path.value().to_deprecated_string()); } auto format_search_engine = [&]() -> Optional { if (!search_engine.has_value()) return {}; return MUST(String::formatted(*search_engine, URL::percent_decode(url))); }; String url_buffer; if (append_tld == AppendTLD::Yes) { // FIXME: Expand the list of top level domains. if (!url.ends_with(".com"sv) && !url.ends_with(".net"sv) && !url.ends_with(".org"sv)) { url_buffer = MUST(String::formatted("{}.com", url)); url = url_buffer; } } auto result = query_public_suffix_list(url); if (!result.has_value()) return format_search_engine(); return result.release_value(); } }