URL.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. * Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/String.h>
  8. #include <LibCore/System.h>
  9. #include <LibFileSystem/FileSystem.h>
  10. #include <LibWebView/URL.h>
  11. #if defined(ENABLE_PUBLIC_SUFFIX)
  12. # include <LibWebView/PublicSuffixData.h>
  13. #endif
  14. namespace WebView {
  15. static Optional<URL> query_public_suffix_list(StringView url_string)
  16. {
  17. auto out = MUST(String::from_utf8(url_string));
  18. if (!out.contains("://"sv))
  19. out = MUST(String::formatted("https://{}"sv, out));
  20. auto url = URL::create_with_url_or_path(out.to_deprecated_string());
  21. if (!url.is_valid())
  22. return {};
  23. #if defined(ENABLE_PUBLIC_SUFFIX)
  24. if (url.host().has<URL::IPv4Address>() || url.host().has<URL::IPv6Address>())
  25. return url;
  26. if (url.scheme() != "http"sv && url.scheme() != "https"sv)
  27. return url;
  28. if (url.host().has<String>()) {
  29. auto const& host = url.host().get<String>();
  30. if (auto public_suffix = MUST(PublicSuffixData::the()->get_public_suffix(host)); public_suffix.has_value())
  31. return url;
  32. if (host.ends_with_bytes(".local"sv) || host.ends_with_bytes("localhost"sv))
  33. return url;
  34. }
  35. return {};
  36. #else
  37. return url;
  38. #endif
  39. }
  40. Optional<URL> sanitize_url(StringView url, Optional<StringView> search_engine, AppendTLD append_tld)
  41. {
  42. if (FileSystem::exists(url)) {
  43. auto path = FileSystem::real_path(url);
  44. if (path.is_error())
  45. return {};
  46. return URL::create_with_file_scheme(path.value().to_deprecated_string());
  47. }
  48. auto format_search_engine = [&]() -> Optional<URL> {
  49. if (!search_engine.has_value())
  50. return {};
  51. return MUST(String::formatted(*search_engine, URL::percent_decode(url)));
  52. };
  53. String url_buffer;
  54. if (append_tld == AppendTLD::Yes) {
  55. // FIXME: Expand the list of top level domains.
  56. if (!url.ends_with(".com"sv) && !url.ends_with(".net"sv) && !url.ends_with(".org"sv)) {
  57. url_buffer = MUST(String::formatted("{}.com", url));
  58. url = url_buffer;
  59. }
  60. }
  61. auto result = query_public_suffix_list(url);
  62. if (!result.has_value())
  63. return format_search_engine();
  64. return result.release_value();
  65. }
  66. }