mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
TLS connect proxy WIP
This commit is contained in:
@@ -322,11 +322,19 @@ const Connection = struct {
|
||||
|
||||
const TLSClient = union(enum) {
|
||||
blocking: tls.Connection(std.net.Stream),
|
||||
blocking_tls_in_tls: struct {
|
||||
proxy: tls.Connection(std.net.Stream),
|
||||
destination: tls.Connection(*tls.Connection(std.net.Stream)),
|
||||
},
|
||||
nonblocking: tls.nonblock.Connection,
|
||||
|
||||
fn close(self: *TLSClient) void {
|
||||
switch (self.*) {
|
||||
.blocking => |*tls_client| tls_client.close() catch {},
|
||||
.blocking_tls_in_tls => {}, // |*tls_in_tls| {
|
||||
// tls_in_tls.destination.close() catch {}; // Crashes
|
||||
// tls_in_tls.proxy.close() catch {};
|
||||
// },
|
||||
.nonblocking => {},
|
||||
}
|
||||
}
|
||||
@@ -657,9 +665,22 @@ pub const Request = struct {
|
||||
|
||||
const is_connect_proxy = self._client.isConnectProxy();
|
||||
if (is_connect_proxy) {
|
||||
try SyncHandler.connect(self);
|
||||
var connect_connection = try SyncHandler.connect(self);
|
||||
if (self._secure) { // TODO separate _secure for proxy and desination
|
||||
const tls_in_tls = try tls.client(&connect_connection, .{
|
||||
.host = self._request_host,
|
||||
.root_ca = self._client.root_ca,
|
||||
.insecure_skip_verify = self._tls_verify_host == false,
|
||||
// .key_log_callback = tls.config.key_log.callback,
|
||||
});
|
||||
self._connection.?.tls = .{
|
||||
.blocking_tls_in_tls = .{
|
||||
.proxy = connect_connection,
|
||||
.destination = tls_in_tls,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
} else {
|
||||
if (self._secure) {
|
||||
self._connection.?.tls = .{
|
||||
.blocking = try tls.client(std.net.Stream{ .handle = socket }, .{
|
||||
@@ -670,6 +691,7 @@ pub const Request = struct {
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
self._connection_from_keepalive = false;
|
||||
}
|
||||
@@ -1723,7 +1745,15 @@ const SyncHandler = struct {
|
||||
var conn: Conn = blk: {
|
||||
const c = request._connection.?;
|
||||
if (c.tls) |*tls_client| {
|
||||
break :blk .{ .tls = &tls_client.blocking };
|
||||
switch (tls_client.*) {
|
||||
.nonblocking => unreachable,
|
||||
.blocking => |*blocking| {
|
||||
break :blk .{ .tls = blocking };
|
||||
},
|
||||
.blocking_tls_in_tls => |*blocking_tls_in_tls| {
|
||||
break :blk .{ .tls_in_tls = &blocking_tls_in_tls.destination };
|
||||
},
|
||||
}
|
||||
}
|
||||
break :blk .{ .plain = c.socket };
|
||||
};
|
||||
@@ -1806,11 +1836,18 @@ const SyncHandler = struct {
|
||||
|
||||
// Unfortunately, this is called from the Request doSendSync since we need
|
||||
// to do this before setting up our TLS connection.
|
||||
fn connect(request: *Request) !void {
|
||||
fn connect(request: *Request) !tls.Connection(std.net.Stream) {
|
||||
const socket = request._connection.?.socket;
|
||||
|
||||
const header = try request.buildConnectHeader();
|
||||
try Conn.writeAll(socket, header);
|
||||
// try Conn.writeAll(socket, header);
|
||||
var tls_client = try tls.client(std.net.Stream{ .handle = socket }, .{
|
||||
.host = request._connect_host,
|
||||
.root_ca = request._client.root_ca,
|
||||
.insecure_skip_verify = request._tls_verify_host == false,
|
||||
.key_log_callback = tls.config.key_log.callback,
|
||||
});
|
||||
try tls_client.writeAll(header);
|
||||
|
||||
var pos: usize = 0;
|
||||
var reader = request.newReader();
|
||||
@@ -1821,18 +1858,24 @@ const SyncHandler = struct {
|
||||
// we only send CONNECT requests on newly established connections
|
||||
// and maybeRetryOrErr is only for connections that might have been
|
||||
// closed while being kept-alive
|
||||
const n = try posix.read(socket, read_buf[pos..]);
|
||||
// const n = try posix.read(socket, read_buf[pos..]);
|
||||
// const n = switch (self.*) {
|
||||
// .tls => |tls_client| try tls_client.read(buf),
|
||||
// .plain => |socket| try posix.read(socket, buf),
|
||||
// };
|
||||
const n = try tls_client.read(read_buf[pos..]);
|
||||
if (n == 0) {
|
||||
return error.ConnectionResetByPeer;
|
||||
}
|
||||
pos += n;
|
||||
if (try reader.connectResponse(read_buf[0..pos])) {
|
||||
// returns true if we have a successful connect response
|
||||
return;
|
||||
return tls_client;
|
||||
}
|
||||
|
||||
// we don't have enough data yet.
|
||||
}
|
||||
return tls_client;
|
||||
}
|
||||
|
||||
fn maybeRetryOrErr(self: *SyncHandler, err: anyerror) !Response {
|
||||
@@ -1882,11 +1925,18 @@ const SyncHandler = struct {
|
||||
}
|
||||
|
||||
const Conn = union(enum) {
|
||||
tls_in_tls: *tls.Connection(*tls.Connection(std.net.Stream)),
|
||||
tls: *tls.Connection(std.net.Stream),
|
||||
plain: posix.socket_t,
|
||||
|
||||
fn sendRequest(self: *Conn, header: []const u8, body: ?[]const u8) !void {
|
||||
switch (self.*) {
|
||||
.tls_in_tls => |tls_client| {
|
||||
try tls_client.writeAll(header);
|
||||
if (body) |b| {
|
||||
try tls_client.writeAll(b);
|
||||
}
|
||||
},
|
||||
.tls => |tls_client| {
|
||||
try tls_client.writeAll(header);
|
||||
if (body) |b| {
|
||||
@@ -1908,6 +1958,7 @@ const SyncHandler = struct {
|
||||
|
||||
fn read(self: *Conn, buf: []u8) !usize {
|
||||
const n = switch (self.*) {
|
||||
.tls_in_tls => |tls_client| try tls_client.read(buf),
|
||||
.tls => |tls_client| try tls_client.read(buf),
|
||||
.plain => |socket| try posix.read(socket, buf),
|
||||
};
|
||||
@@ -2083,6 +2134,7 @@ const Reader = struct {
|
||||
if (result.done == false) {
|
||||
// CONNECT responses should not have a body. If the header is
|
||||
// done, then the entire response should be done.
|
||||
log.err(.http_client, "InvalidConnectResponse", .{ .unprocessed = result.unprocessed.? });
|
||||
return error.InvalidConnectResponse;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user