summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2022-04-08 01:46:47 +0430
committerAndreas Kling <kling@serenityos.org>2022-04-09 12:21:43 +0200
commita42e03b01a7c2c98377f3851cb4e5f07d7e3ba35 (patch)
tree812e97db21dee65573b5a669a2b643ee4ea83426 /Userland
parentf9fc28931fe42700bbfc8964a0a7ceb5940a46f7 (diff)
downloadserenity-a42e03b01a7c2c98377f3851cb4e5f07d7e3ba35.zip
Browser+LibWeb+WebContent: Implement per-URL-pattern proxies
...at least for SOCKS5.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/Browser/Browser.h2
-rw-r--r--Userland/Applications/Browser/BrowserWindow.cpp29
-rw-r--r--Userland/Applications/Browser/BrowserWindow.h1
-rw-r--r--Userland/Applications/Browser/Tab.cpp7
-rw-r--r--Userland/Applications/Browser/Tab.h1
-rw-r--r--Userland/Applications/Browser/main.cpp16
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/Loader/ProxyMappings.cpp41
-rw-r--r--Userland/Libraries/LibWeb/Loader/ProxyMappings.h31
-rw-r--r--Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp6
-rw-r--r--Userland/Libraries/LibWeb/OutOfProcessWebView.cpp5
-rw-r--r--Userland/Libraries/LibWeb/OutOfProcessWebView.h1
-rw-r--r--Userland/Services/WebContent/ConnectionFromClient.cpp18
-rw-r--r--Userland/Services/WebContent/ConnectionFromClient.h1
-rw-r--r--Userland/Services/WebContent/WebContentServer.ipc1
15 files changed, 155 insertions, 6 deletions
diff --git a/Userland/Applications/Browser/Browser.h b/Userland/Applications/Browser/Browser.h
index fccb78d47b..b9d186e4ae 100644
--- a/Userland/Applications/Browser/Browser.h
+++ b/Userland/Applications/Browser/Browser.h
@@ -14,6 +14,8 @@ namespace Browser {
extern String g_home_url;
extern String g_search_engine;
extern Vector<String> g_content_filters;
+extern Vector<String> g_proxies;
+extern HashMap<String, size_t> g_proxy_mappings;
extern bool g_content_filters_enabled;
extern IconBag g_icon_bag;
diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp
index 7cf6e186e1..f67501427b 100644
--- a/Userland/Applications/Browser/BrowserWindow.cpp
+++ b/Userland/Applications/Browser/BrowserWindow.cpp
@@ -575,15 +575,34 @@ void BrowserWindow::content_filters_changed()
});
}
+void BrowserWindow::proxy_mappings_changed()
+{
+ tab_widget().for_each_child_of_type<Browser::Tab>([](auto& tab) {
+ tab.proxy_mappings_changed();
+ return IterationDecision::Continue;
+ });
+}
+
void BrowserWindow::config_string_did_change(String const& domain, String const& group, String const& key, String const& value)
{
- if (domain != "Browser" || group != "Preferences")
+ if (domain != "Browser")
return;
- if (key == "SearchEngine")
- Browser::g_search_engine = value;
- else if (key == "Home")
- Browser::g_home_url = value;
+ if (group == "Preferences") {
+ if (key == "SearchEngine")
+ Browser::g_search_engine = value;
+ else if (key == "Home")
+ Browser::g_home_url = value;
+ } else if (group.starts_with("Proxy:")) {
+ dbgln("Proxy mapping changed: {}/{} = {}", group, key, value);
+ auto proxy_spec = group.substring_view(6);
+ auto existing_proxy = Browser::g_proxies.find(proxy_spec);
+ if (existing_proxy.is_end())
+ Browser::g_proxies.append(proxy_spec);
+
+ Browser::g_proxy_mappings.set(key, existing_proxy.index());
+ proxy_mappings_changed();
+ }
// TODO: ColorScheme
}
diff --git a/Userland/Applications/Browser/BrowserWindow.h b/Userland/Applications/Browser/BrowserWindow.h
index 88e4496349..fe6e9e3efe 100644
--- a/Userland/Applications/Browser/BrowserWindow.h
+++ b/Userland/Applications/Browser/BrowserWindow.h
@@ -41,6 +41,7 @@ public:
GUI::Action& inspect_dom_node_action() { return *m_inspect_dom_node_action; }
void content_filters_changed();
+ void proxy_mappings_changed();
private:
explicit BrowserWindow(CookieJar&, URL);
diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp
index e634b2e58f..745ae88556 100644
--- a/Userland/Applications/Browser/Tab.cpp
+++ b/Userland/Applications/Browser/Tab.cpp
@@ -118,6 +118,8 @@ Tab::Tab(BrowserWindow& window)
else
m_web_content_view->set_content_filters({});
+ m_web_content_view->set_proxy_mappings(g_proxies, g_proxy_mappings);
+
auto& go_back_button = toolbar.add_action(window.go_back_action());
go_back_button.on_context_menu_request = [this](auto& context_menu_event) {
if (!m_history.can_go_back())
@@ -516,6 +518,11 @@ void Tab::content_filters_changed()
m_web_content_view->set_content_filters({});
}
+void Tab::proxy_mappings_changed()
+{
+ m_web_content_view->set_proxy_mappings(g_proxies, g_proxy_mappings);
+}
+
void Tab::action_entered(GUI::Action& action)
{
m_statusbar->set_override_text(action.status_tip());
diff --git a/Userland/Applications/Browser/Tab.h b/Userland/Applications/Browser/Tab.h
index 2e2ee353a7..a7bd6f33dc 100644
--- a/Userland/Applications/Browser/Tab.h
+++ b/Userland/Applications/Browser/Tab.h
@@ -51,6 +51,7 @@ public:
void did_become_active();
void context_menu_requested(Gfx::IntPoint const& screen_position);
void content_filters_changed();
+ void proxy_mappings_changed();
void action_entered(GUI::Action&);
void action_left(GUI::Action&);
diff --git a/Userland/Applications/Browser/main.cpp b/Userland/Applications/Browser/main.cpp
index 1842e32f1c..e963e312c3 100644
--- a/Userland/Applications/Browser/main.cpp
+++ b/Userland/Applications/Browser/main.cpp
@@ -31,6 +31,8 @@ String g_search_engine;
String g_home_url;
Vector<String> g_content_filters;
bool g_content_filters_enabled { true };
+Vector<String> g_proxies;
+HashMap<String, size_t> g_proxy_mappings;
IconBag g_icon_bag;
}
@@ -96,6 +98,20 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(load_content_filters());
+ for (auto& group : Config::list_groups("Browser")) {
+ if (!group.starts_with("Proxy:"))
+ continue;
+
+ for (auto& key : Config::list_keys("Browser", group)) {
+ auto proxy_spec = group.substring_view(6);
+ auto existing_proxy = Browser::g_proxies.find(proxy_spec);
+ if (existing_proxy.is_end())
+ Browser::g_proxies.append(proxy_spec);
+
+ Browser::g_proxy_mappings.set(key, existing_proxy.index());
+ }
+ }
+
URL first_url = Browser::url_from_user_input(Browser::g_home_url);
if (specified_url) {
if (Core::File::exists(specified_url)) {
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index 499c8cfbd3..ae3f664a38 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -280,6 +280,7 @@ set(SOURCES
Loader/ImageLoader.cpp
Loader/ImageResource.cpp
Loader/LoadRequest.cpp
+ Loader/ProxyMappings.cpp
Loader/Resource.cpp
Loader/ResourceLoader.cpp
MimeSniff/MimeType.cpp
diff --git a/Userland/Libraries/LibWeb/Loader/ProxyMappings.cpp b/Userland/Libraries/LibWeb/Loader/ProxyMappings.cpp
new file mode 100644
index 0000000000..4230a72862
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Loader/ProxyMappings.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "ProxyMappings.h"
+
+Web::ProxyMappings& Web::ProxyMappings::the()
+{
+ static ProxyMappings instance {};
+ return instance;
+}
+
+Core::ProxyData Web::ProxyMappings::proxy_for_url(AK::URL const& url) const
+{
+ auto url_string = url.to_string();
+ for (auto& it : m_mappings) {
+ dbgln("Checking {} against {}...", url, it.key);
+ if (url_string.matches(it.key)) {
+ dbgln("Matched!");
+ auto result = Core::ProxyData::parse_url(m_proxies[it.value]);
+ if (result.is_error()) {
+ dbgln("Failed to parse proxy URL: {}", m_proxies[it.value]);
+ continue;
+ }
+ return result.release_value();
+ }
+ }
+
+ dbgln("No luck!");
+ return {};
+}
+
+void Web::ProxyMappings::set_mappings(Vector<String> proxies, OrderedHashMap<String, size_t> mappings)
+{
+ m_proxies = move(proxies);
+ m_mappings = move(mappings);
+
+ dbgln("Proxy mappings updated: proxies: {}", m_proxies);
+}
diff --git a/Userland/Libraries/LibWeb/Loader/ProxyMappings.h b/Userland/Libraries/LibWeb/Loader/ProxyMappings.h
new file mode 100644
index 0000000000..afa7f63ae2
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Loader/ProxyMappings.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/HashMap.h>
+#include <AK/URL.h>
+#include <AK/Vector.h>
+#include <LibCore/Proxy.h>
+
+namespace Web {
+
+class ProxyMappings {
+public:
+ static ProxyMappings& the();
+
+ Core::ProxyData proxy_for_url(AK::URL const&) const;
+ void set_mappings(Vector<String> proxies, OrderedHashMap<String, size_t> mappings);
+
+private:
+ ProxyMappings() = default;
+ ~ProxyMappings() = default;
+
+ Vector<String> m_proxies;
+ OrderedHashMap<String, size_t> m_mappings;
+};
+
+}
diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
index 737598cc3d..76a634f80f 100644
--- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
+++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
@@ -14,6 +14,7 @@
#include <LibProtocol/RequestClient.h>
#include <LibWeb/Loader/ContentFilter.h>
#include <LibWeb/Loader/LoadRequest.h>
+#include <LibWeb/Loader/ProxyMappings.h>
#include <LibWeb/Loader/Resource.h>
#include <LibWeb/Loader/ResourceLoader.h>
#include <serenity.h>
@@ -213,6 +214,9 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has
}
if (url.protocol() == "http" || url.protocol() == "https" || url.protocol() == "gemini") {
+ auto proxy = ProxyMappings::the().proxy_for_url(url);
+ dbgln("Proxy for {} is {}", url, proxy.type == decltype(proxy.type)::SOCKS5 ? IPv4Address(proxy.host_ipv4).to_string() : "(direct)");
+
HashMap<String, String> headers;
headers.set("User-Agent", m_user_agent);
headers.set("Accept-Encoding", "gzip, deflate");
@@ -221,7 +225,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has
headers.set(it.key, it.value);
}
- auto protocol_request = protocol_client().start_request(request.method(), url, headers, request.body());
+ auto protocol_request = protocol_client().start_request(request.method(), url, headers, request.body(), proxy);
if (!protocol_request) {
auto start_request_failure_msg = "Failed to initiate load"sv;
log_failure(request, start_request_failure_msg);
diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp
index 04dfb260ed..887993671d 100644
--- a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp
+++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp
@@ -500,6 +500,11 @@ void OutOfProcessWebView::set_content_filters(Vector<String> filters)
client().async_set_content_filters(filters);
}
+void OutOfProcessWebView::set_proxy_mappings(Vector<String> proxies, HashMap<String, size_t> mappings)
+{
+ client().async_set_proxy_mappings(move(proxies), move(mappings));
+}
+
void OutOfProcessWebView::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme)
{
client().async_set_preferred_color_scheme(color_scheme);
diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.h b/Userland/Libraries/LibWeb/OutOfProcessWebView.h
index cf54557f19..55f513c47c 100644
--- a/Userland/Libraries/LibWeb/OutOfProcessWebView.h
+++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.h
@@ -55,6 +55,7 @@ public:
OrderedHashMap<String, String> get_local_storage_entries();
void set_content_filters(Vector<String>);
+ void set_proxy_mappings(Vector<String> proxies, HashMap<String, size_t> mappings);
void set_preferred_color_scheme(Web::CSS::PreferredColorScheme);
Function<void(Gfx::IntPoint const& screen_position)> on_context_menu_request;
diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp
index 4798233a19..48db742020 100644
--- a/Userland/Services/WebContent/ConnectionFromClient.cpp
+++ b/Userland/Services/WebContent/ConnectionFromClient.cpp
@@ -7,6 +7,7 @@
#include <AK/Debug.h>
#include <AK/JsonObject.h>
+#include <AK/QuickSort.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/FontDatabase.h>
#include <LibGfx/SystemTheme.h>
@@ -24,6 +25,7 @@
#include <LibWeb/HTML/Window.h>
#include <LibWeb/Layout/InitialContainingBlock.h>
#include <LibWeb/Loader/ContentFilter.h>
+#include <LibWeb/Loader/ProxyMappings.h>
#include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/StackingContext.h>
@@ -454,6 +456,22 @@ void ConnectionFromClient::set_content_filters(Vector<String> const& filters)
Web::ContentFilter::the().add_pattern(filter);
}
+void ConnectionFromClient::set_proxy_mappings(Vector<String> const& proxies, HashMap<String, size_t> const& mappings)
+{
+ auto keys = mappings.keys();
+ quick_sort(keys, [&](auto& a, auto& b) { return a.length() < b.length(); });
+
+ OrderedHashMap<String, size_t> sorted_mappings;
+ for (auto& key : keys) {
+ auto value = *mappings.get(key);
+ if (value >= proxies.size())
+ continue;
+ sorted_mappings.set(key, value);
+ }
+
+ Web::ProxyMappings::the().set_mappings(proxies, move(sorted_mappings));
+}
+
void ConnectionFromClient::set_preferred_color_scheme(Web::CSS::PreferredColorScheme const& color_scheme)
{
m_page_host->set_preferred_color_scheme(color_scheme);
diff --git a/Userland/Services/WebContent/ConnectionFromClient.h b/Userland/Services/WebContent/ConnectionFromClient.h
index 05a3dcc15f..9af25ca3a7 100644
--- a/Userland/Services/WebContent/ConnectionFromClient.h
+++ b/Userland/Services/WebContent/ConnectionFromClient.h
@@ -59,6 +59,7 @@ private:
virtual Messages::WebContentServer::GetHoveredNodeIdResponse get_hovered_node_id() override;
virtual Messages::WebContentServer::DumpLayoutTreeResponse dump_layout_tree() override;
virtual void set_content_filters(Vector<String> const&) override;
+ virtual void set_proxy_mappings(Vector<String> const&, HashMap<String, size_t> const&) override;
virtual void set_preferred_color_scheme(Web::CSS::PreferredColorScheme const&) override;
virtual void set_has_focus(bool) override;
virtual void set_is_scripting_enabled(bool) override;
diff --git a/Userland/Services/WebContent/WebContentServer.ipc b/Userland/Services/WebContent/WebContentServer.ipc
index 89467abe50..6cf876f62e 100644
--- a/Userland/Services/WebContent/WebContentServer.ipc
+++ b/Userland/Services/WebContent/WebContentServer.ipc
@@ -43,6 +43,7 @@ endpoint WebContentServer
select_all() =|
set_content_filters(Vector<String> filters) =|
+ set_proxy_mappings(Vector<String> proxies, HashMap<String,size_t> mappings) =|
set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme) =|
set_has_focus(bool has_focus) =|
set_is_scripting_enabled(bool is_scripting_enabled) =|