@@ -71,9 +71,6 @@ allocator: Allocator,
7171// request. These wil come and go with each request.
7272transfer_pool : std .heap .MemoryPool (Transfer ),
7373
74- //@newhttp
75- http_proxy : ? std.Uri = null ,
76-
7774// see ScriptManager.blockingGet
7875blocking : Handle ,
7976
@@ -87,6 +84,10 @@ blocking_active: if (builtin.mode == .Debug) bool else void = if (builtin.mode =
8784// can result in makeRequest being re-called (from a doneCallback).
8885arena : ArenaAllocator ,
8986
87+ // only needed for CDP which can change the proxy and then restore it. When
88+ // restoring, this originally-configured value is what it goes to.
89+ http_proxy : ? [:0 ]const u8 = null ,
90+
9091const RequestQueue = std .DoublyLinkedList (Request );
9192
9293pub 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
117118 .handles = handles ,
118119 .blocking = blocking ,
119120 .allocator = allocator ,
121+ .http_proxy = opts .http_proxy ,
120122 .transfer_pool = transfer_pool ,
121123 .queue_node_pool = queue_node_pool ,
122124 .arena = ArenaAllocator .init (allocator ),
@@ -208,6 +210,36 @@ pub fn blockingRequest(self: *Client, req: Request) !void {
208210 return self .makeRequest (& self .blocking , req );
209211}
210212
213+ // Restrictive since it'll only work if there are no inflight requests. In some
214+ // cases, the libcurl documentation is clear that changing settings while a
215+ // connection is inflight is undefined. It doesn't say anything about CURLOPT_PROXY,
216+ // but better to be safe than sorry.
217+ // For now, this restriction is ok, since it's only called by CDP on
218+ // createBrowserContext, at which point, if we do have an active connection,
219+ // that's probably a bug (a previous abort failed?). But if we need to call this
220+ // at any point in time, it could be worth digging into libcurl to see if this
221+ // can be changed at any point in the easy's lifecycle.
222+ pub fn changeProxy (self : * Client , proxy : [:0 ]const u8 ) ! void {
223+ try self .ensureNoActiveConnection ();
224+
225+ for (self .handles .handles ) | h | {
226+ try errorCheck (c .curl_easy_setopt (h .conn .easy , c .CURLOPT_PROXY , proxy .ptr ));
227+ }
228+ try errorCheck (c .curl_easy_setopt (self .blocking .conn .easy , c .CURLOPT_PROXY , proxy .ptr ));
229+ }
230+
231+ // Same restriction as changeProxy. Should be ok since this is only called on
232+ // BrowserContext deinit.
233+ pub fn restoreOriginalProxy (self : * Client ) ! void {
234+ try self .ensureNoActiveConnection ();
235+
236+ const proxy = if (self .http_proxy ) | p | p .ptr else null ;
237+ for (self .handles .handles ) | h | {
238+ try errorCheck (c .curl_easy_setopt (h .conn .easy , c .CURLOPT_PROXY , proxy ));
239+ }
240+ try errorCheck (c .curl_easy_setopt (self .blocking .conn .easy , c .CURLOPT_PROXY , proxy ));
241+ }
242+
211243fn makeRequest (self : * Client , handle : * Handle , req : Request ) ! void {
212244 const conn = handle .conn ;
213245 const easy = conn .easy ;
@@ -339,6 +371,17 @@ fn endTransfer(self: *Client, transfer: *Transfer) void {
339371 self .active -= 1 ;
340372}
341373
374+ fn ensureNoActiveConnection (self : * const Client ) ! void {
375+ if (self .active > 0 ) {
376+ return error .InflightConnection ;
377+ }
378+ if (comptime builtin .mode == .Debug ) {
379+ if (self .blocking_active ) {
380+ return error .InflightConnection ;
381+ }
382+ }
383+ }
384+
342385const Handles = struct {
343386 handles : []Handle ,
344387 in_use : HandleList ,
0 commit comments