mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-30 15:41:48 +00:00 
			
		
		
		
	basic/bearer proxy authentication
This commit is contained in:
		| @@ -46,6 +46,34 @@ pub const ProxyType = enum { | ||||
|     connect, | ||||
| }; | ||||
|  | ||||
| pub const ProxyAuth = union(enum) { | ||||
|     basic: struct { user_pass: []const u8 }, | ||||
|     bearer: struct { token: []const u8 }, | ||||
|  | ||||
|     pub fn header_value(self: ProxyAuth, allocator: Allocator) ![]const u8 { | ||||
|         switch (self) { | ||||
|             .basic => |*auth| { | ||||
|                 if (std.mem.indexOfScalar(u8, auth.user_pass, ':') == null) return error.InvalidProxyAuth; | ||||
|  | ||||
|                 const prefix = "Basic "; | ||||
|                 var encoder = std.base64.standard.Encoder; | ||||
|                 const size = encoder.calcSize(auth.user_pass.len); | ||||
|                 var buffer = try allocator.alloc(u8, size + prefix.len); | ||||
|                 std.mem.copyForwards(u8, buffer, prefix); | ||||
|                 _ = std.base64.standard.Encoder.encode(buffer[prefix.len..], auth.user_pass); | ||||
|                 return buffer; | ||||
|             }, | ||||
|             .bearer => |*auth| { | ||||
|                 const prefix = "Bearer "; | ||||
|                 var buffer = try allocator.alloc(u8, auth.token.len + prefix.len); | ||||
|                 std.mem.copyForwards(u8, buffer, prefix); | ||||
|                 std.mem.copyForwards(u8, buffer[prefix.len..], auth.token); | ||||
|                 return buffer; | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // Thread-safe. Holds our root certificate, connection pool and state pool | ||||
| // Used to create Requests. | ||||
| pub const Client = struct { | ||||
| @@ -54,6 +82,7 @@ pub const Client = struct { | ||||
|     state_pool: StatePool, | ||||
|     http_proxy: ?Uri, | ||||
|     proxy_type: ?ProxyType, | ||||
|     proxy_auth: ?[]const u8, // Basic <user:pass; base64> or Bearer <token> | ||||
|     root_ca: tls.config.CertBundle, | ||||
|     tls_verify_host: bool = true, | ||||
|     connection_manager: ConnectionManager, | ||||
| @@ -63,6 +92,7 @@ pub const Client = struct { | ||||
|         max_concurrent: usize = 3, | ||||
|         http_proxy: ?std.Uri = null, | ||||
|         proxy_type: ?ProxyType = null, | ||||
|         proxy_auth: ?ProxyAuth = null, | ||||
|         tls_verify_host: bool = true, | ||||
|         max_idle_connection: usize = 10, | ||||
|     }; | ||||
| @@ -71,10 +101,10 @@ pub const Client = struct { | ||||
|         var root_ca: tls.config.CertBundle = if (builtin.is_test) .{} else try tls.config.CertBundle.fromSystem(allocator); | ||||
|         errdefer root_ca.deinit(allocator); | ||||
|  | ||||
|         const state_pool = try StatePool.init(allocator, opts.max_concurrent); | ||||
|         var state_pool = try StatePool.init(allocator, opts.max_concurrent); | ||||
|         errdefer state_pool.deinit(allocator); | ||||
|  | ||||
|         const connection_manager = ConnectionManager.init(allocator, opts.max_idle_connection); | ||||
|         var connection_manager = ConnectionManager.init(allocator, opts.max_idle_connection); | ||||
|         errdefer connection_manager.deinit(); | ||||
|  | ||||
|         return .{ | ||||
| @@ -84,6 +114,7 @@ pub const Client = struct { | ||||
|             .state_pool = state_pool, | ||||
|             .http_proxy = opts.http_proxy, | ||||
|             .proxy_type = if (opts.http_proxy == null) null else (opts.proxy_type orelse .connect), | ||||
|             .proxy_auth = if (opts.proxy_auth) |*auth| try auth.header_value(allocator) else null, | ||||
|             .tls_verify_host = opts.tls_verify_host, | ||||
|             .connection_manager = connection_manager, | ||||
|             .request_pool = std.heap.MemoryPool(Request).init(allocator), | ||||
| @@ -98,6 +129,10 @@ pub const Client = struct { | ||||
|         self.state_pool.deinit(allocator); | ||||
|         self.connection_manager.deinit(); | ||||
|         self.request_pool.deinit(); | ||||
|  | ||||
|         if (self.proxy_auth) |auth| { | ||||
|             allocator.free(auth); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn request(self: *Client, method: Request.Method, uri: *const Uri) !*Request { | ||||
| @@ -763,6 +798,13 @@ pub const Request = struct { | ||||
|  | ||||
|         try self.headers.append(arena, .{ .name = "User-Agent", .value = "Lightpanda/1.0" }); | ||||
|         try self.headers.append(arena, .{ .name = "Accept", .value = "*/*" }); | ||||
|  | ||||
|         if (self._client.isSimpleProxy()) { | ||||
|             if (self._client.proxy_auth) |proxy_auth| { | ||||
|                 try self.headers.append(arena, .{ .name = "Proxy-Authorization", .value = proxy_auth }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         self.requestStarting(); | ||||
|     } | ||||
|  | ||||
| @@ -887,7 +929,13 @@ pub const Request = struct { | ||||
|         var writer = fbs.writer(); | ||||
|  | ||||
|         try writer.print("CONNECT {s}:{d} HTTP/1.1\r\n", .{ self._request_host, self._request_port }); | ||||
|         try writer.print("Host: {s}:{d}\r\n\r\n", .{ self._request_host, self._request_port }); | ||||
|         try writer.print("Host: {s}:{d}\r\n", .{ self._request_host, self._request_port }); | ||||
|  | ||||
|         if (self._client.proxy_auth) |proxy_auth| { | ||||
|             try writer.print("Proxy-Authorization: {s}\r\n", .{proxy_auth}); | ||||
|         } | ||||
|  | ||||
|         _ = try writer.write("\r\n"); | ||||
|         return buf[0..fbs.pos]; | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 sjorsdonkers
					sjorsdonkers