mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
support CDP proxy override
This commit is contained in:
@@ -338,10 +338,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
inspector: Inspector,
|
inspector: Inspector,
|
||||||
isolated_world: ?IsolatedWorld,
|
isolated_world: ?IsolatedWorld,
|
||||||
|
|
||||||
// Used to restore the proxy after the CDP session ends. If CDP never over-wrote it, it won't restore it (the first null).
|
http_proxy_changed: bool = false,
|
||||||
// If the CDP is restoring it, but the original value was null, that's the 2nd null.
|
|
||||||
// If you only have 1 null it would be ambiguous, does null mean it shouldn't be restored, or should it be restored to null?
|
|
||||||
http_proxy_before: ??std.Uri = null,
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@@ -397,7 +394,13 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
self.node_search_list.deinit();
|
self.node_search_list.deinit();
|
||||||
self.cdp.browser.notification.unregisterAll(self);
|
self.cdp.browser.notification.unregisterAll(self);
|
||||||
|
|
||||||
if (self.http_proxy_before) |prev_proxy| self.cdp.browser.http_client.http_proxy = prev_proxy;
|
if (self.http_proxy_changed) {
|
||||||
|
// has to be called after browser.closeSession, since it won't
|
||||||
|
// work if there are active connections.
|
||||||
|
self.cdp.browser.http_client.restoreOriginalProxy() catch |err| {
|
||||||
|
log.warn(.http, "restoreOriginalProxy", .{ .err = err });
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(self: *Self) void {
|
pub fn reset(self: *Self) void {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ fn getBrowserContexts(cmd: anytype) !void {
|
|||||||
fn createBrowserContext(cmd: anytype) !void {
|
fn createBrowserContext(cmd: anytype) !void {
|
||||||
const params = try cmd.params(struct {
|
const params = try cmd.params(struct {
|
||||||
disposeOnDetach: bool = false,
|
disposeOnDetach: bool = false,
|
||||||
proxyServer: ?[]const u8 = null,
|
proxyServer: ?[:0]const u8 = null,
|
||||||
proxyBypassList: ?[]const u8 = null,
|
proxyBypassList: ?[]const u8 = null,
|
||||||
originsWithUniversalNetworkAccess: ?[]const []const u8 = null,
|
originsWithUniversalNetworkAccess: ?[]const []const u8 = null,
|
||||||
});
|
});
|
||||||
@@ -84,9 +84,8 @@ fn createBrowserContext(cmd: anytype) !void {
|
|||||||
if (params) |p| {
|
if (params) |p| {
|
||||||
if (p.proxyServer) |proxy| {
|
if (p.proxyServer) |proxy| {
|
||||||
// For now the http client is not in the browser context so we assume there is just 1.
|
// For now the http client is not in the browser context so we assume there is just 1.
|
||||||
bc.http_proxy_before = cmd.cdp.browser.http_client.http_proxy;
|
try cmd.cdp.browser.http_client.changeProxy(proxy);
|
||||||
const proxy_cp = try cmd.cdp.browser.http_client.allocator.dupe(u8, proxy);
|
bc.http_proxy_changed = true;
|
||||||
cmd.cdp.browser.http_client.http_proxy = try std.Uri.parse(proxy_cp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ allocator: Allocator,
|
|||||||
// request. These wil come and go with each request.
|
// request. These wil come and go with each request.
|
||||||
transfer_pool: std.heap.MemoryPool(Transfer),
|
transfer_pool: std.heap.MemoryPool(Transfer),
|
||||||
|
|
||||||
//@newhttp
|
|
||||||
http_proxy: ?std.Uri = null,
|
|
||||||
|
|
||||||
// see ScriptManager.blockingGet
|
// see ScriptManager.blockingGet
|
||||||
blocking: Handle,
|
blocking: Handle,
|
||||||
|
|
||||||
@@ -87,6 +84,10 @@ blocking_active: if (builtin.mode == .Debug) bool else void = if (builtin.mode =
|
|||||||
// can result in makeRequest being re-called (from a doneCallback).
|
// can result in makeRequest being re-called (from a doneCallback).
|
||||||
arena: ArenaAllocator,
|
arena: ArenaAllocator,
|
||||||
|
|
||||||
|
// only needed for CDP which can change the proxy and then restore it. When
|
||||||
|
// restoring, this originally-configured value is what it goes to.
|
||||||
|
http_proxy: ?[:0]const u8 = null,
|
||||||
|
|
||||||
const RequestQueue = std.DoublyLinkedList(Request);
|
const RequestQueue = std.DoublyLinkedList(Request);
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, ca_blob: ?c.curl_blob, opts: Http.Opts) !*Client {
|
pub fn init(allocator: Allocator, ca_blob: ?c.curl_blob, opts: Http.Opts) !*Client {
|
||||||
@@ -117,6 +118,7 @@ pub fn init(allocator: Allocator, ca_blob: ?c.curl_blob, opts: Http.Opts) !*Clie
|
|||||||
.handles = handles,
|
.handles = handles,
|
||||||
.blocking = blocking,
|
.blocking = blocking,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
.http_proxy = opts.http_proxy,
|
||||||
.transfer_pool = transfer_pool,
|
.transfer_pool = transfer_pool,
|
||||||
.queue_node_pool = queue_node_pool,
|
.queue_node_pool = queue_node_pool,
|
||||||
.arena = ArenaAllocator.init(allocator),
|
.arena = ArenaAllocator.init(allocator),
|
||||||
@@ -208,6 +210,36 @@ pub fn blockingRequest(self: *Client, req: Request) !void {
|
|||||||
return self.makeRequest(&self.blocking, req);
|
return self.makeRequest(&self.blocking, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restrictive since it'll only work if there are no inflight requests. In some
|
||||||
|
// cases, the libcurl documentation is clear that changing settings while a
|
||||||
|
// connection is inflight is undefined. It doesn't say anything about CURLOPT_PROXY,
|
||||||
|
// but better to be safe than sorry.
|
||||||
|
// For now, this restriction is ok, since it's only called by CDP on
|
||||||
|
// createBrowserContext, at which point, if we do have an active connection,
|
||||||
|
// that's probably a bug (a previous abort failed?). But if we need to call this
|
||||||
|
// at any point in time, it could be worth digging into libcurl to see if this
|
||||||
|
// can be changed at any point in the easy's lifecycle.
|
||||||
|
pub fn changeProxy(self: *Client, proxy: [:0]const u8) !void {
|
||||||
|
try self.ensureNoActiveConnection();
|
||||||
|
|
||||||
|
for (self.handles.handles) |h| {
|
||||||
|
try errorCheck(c.curl_easy_setopt(h.conn.easy, c.CURLOPT_PROXY, proxy.ptr));
|
||||||
|
}
|
||||||
|
try errorCheck(c.curl_easy_setopt(self.blocking.conn.easy, c.CURLOPT_PROXY, proxy.ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same restriction as changeProxy. Should be ok since this is only called on
|
||||||
|
// BrowserContext deinit.
|
||||||
|
pub fn restoreOriginalProxy(self: *Client) !void {
|
||||||
|
try self.ensureNoActiveConnection();
|
||||||
|
|
||||||
|
const proxy = if (self.http_proxy) |p| p.ptr else null;
|
||||||
|
for (self.handles.handles) |h| {
|
||||||
|
try errorCheck(c.curl_easy_setopt(h.conn.easy, c.CURLOPT_PROXY, proxy));
|
||||||
|
}
|
||||||
|
try errorCheck(c.curl_easy_setopt(self.blocking.conn.easy, c.CURLOPT_PROXY, proxy));
|
||||||
|
}
|
||||||
|
|
||||||
fn makeRequest(self: *Client, handle: *Handle, req: Request) !void {
|
fn makeRequest(self: *Client, handle: *Handle, req: Request) !void {
|
||||||
const conn = handle.conn;
|
const conn = handle.conn;
|
||||||
const easy = conn.easy;
|
const easy = conn.easy;
|
||||||
@@ -339,6 +371,17 @@ fn endTransfer(self: *Client, transfer: *Transfer) void {
|
|||||||
self.active -= 1;
|
self.active -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ensureNoActiveConnection(self: *const Client) !void {
|
||||||
|
if (self.active > 0) {
|
||||||
|
return error.InflightConnection;
|
||||||
|
}
|
||||||
|
if (comptime builtin.mode == .Debug) {
|
||||||
|
if (self.blocking_active) {
|
||||||
|
return error.InflightConnection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Handles = struct {
|
const Handles = struct {
|
||||||
handles: []Handle,
|
handles: []Handle,
|
||||||
in_use: HandleList,
|
in_use: HandleList,
|
||||||
|
|||||||
@@ -768,7 +768,7 @@ fn serveCDP(address: std.net.Address, platform: *const Platform) !void {
|
|||||||
.run_mode = .serve,
|
.run_mode = .serve,
|
||||||
.tls_verify_host = false,
|
.tls_verify_host = false,
|
||||||
.platform = platform,
|
.platform = platform,
|
||||||
.max_concurrent_transfers = 2,
|
.http_max_concurrent = 2,
|
||||||
});
|
});
|
||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user