@@ -322,11 +322,19 @@ const Connection = struct {
322322
323323 const TLSClient = union (enum ) {
324324 blocking : tls .Connection (std .net .Stream ),
325+ blocking_tls_in_tls : struct {
326+ proxy : tls .Connection (std .net .Stream ),
327+ destination : tls .Connection (* tls .Connection (std .net .Stream )),
328+ },
325329 nonblocking : tls.nonblock.Connection ,
326330
327331 fn close (self : * TLSClient ) void {
328332 switch (self .* ) {
329333 .blocking = > | * tls_client | tls_client .close () catch {},
334+ .blocking_tls_in_tls = > {}, // |*tls_in_tls| {
335+ // tls_in_tls.destination.close() catch {}; // Crashes
336+ // tls_in_tls.proxy.close() catch {};
337+ // },
330338 .nonblocking = > {},
331339 }
332340 }
@@ -657,18 +665,32 @@ pub const Request = struct {
657665
658666 const is_connect_proxy = self ._client .isConnectProxy ();
659667 if (is_connect_proxy ) {
660- try SyncHandler .connect (self );
661- }
662-
663- if (self ._secure ) {
664- self ._connection .? .tls = .{
665- .blocking = try tls .client (std.net.Stream { .handle = socket }, .{
666- .host = if (is_connect_proxy ) self ._request_host else self ._connect_host ,
668+ var connect_connection = try SyncHandler .connect (self );
669+ if (self ._secure ) { // TODO separate _secure for proxy and desination
670+ const tls_in_tls = try tls .client (& connect_connection , .{
671+ .host = self ._request_host ,
667672 .root_ca = self ._client .root_ca ,
668673 .insecure_skip_verify = self ._tls_verify_host == false ,
669674 // .key_log_callback = tls.config.key_log.callback,
670- }),
671- };
675+ });
676+ self ._connection .? .tls = .{
677+ .blocking_tls_in_tls = .{
678+ .proxy = connect_connection ,
679+ .destination = tls_in_tls ,
680+ },
681+ };
682+ }
683+ } else {
684+ if (self ._secure ) {
685+ self ._connection .? .tls = .{
686+ .blocking = try tls .client (std.net.Stream { .handle = socket }, .{
687+ .host = if (is_connect_proxy ) self ._request_host else self ._connect_host ,
688+ .root_ca = self ._client .root_ca ,
689+ .insecure_skip_verify = self ._tls_verify_host == false ,
690+ // .key_log_callback = tls.config.key_log.callback,
691+ }),
692+ };
693+ }
672694 }
673695
674696 self ._connection_from_keepalive = false ;
@@ -1721,7 +1743,15 @@ const SyncHandler = struct {
17211743 var conn : Conn = blk : {
17221744 const c = request ._connection .? ;
17231745 if (c .tls ) | * tls_client | {
1724- break :blk .{ .tls = & tls_client .blocking };
1746+ switch (tls_client .* ) {
1747+ .nonblocking = > unreachable ,
1748+ .blocking = > | * blocking | {
1749+ break :blk .{ .tls = blocking };
1750+ },
1751+ .blocking_tls_in_tls = > | * blocking_tls_in_tls | {
1752+ break :blk .{ .tls_in_tls = & blocking_tls_in_tls .destination };
1753+ },
1754+ }
17251755 }
17261756 break :blk .{ .plain = c .socket };
17271757 };
@@ -1804,11 +1834,18 @@ const SyncHandler = struct {
18041834
18051835 // Unfortunately, this is called from the Request doSendSync since we need
18061836 // to do this before setting up our TLS connection.
1807- fn connect (request : * Request ) ! void {
1837+ fn connect (request : * Request ) ! tls. Connection ( std . net . Stream ) {
18081838 const socket = request ._connection .? .socket ;
18091839
18101840 const header = try request .buildConnectHeader ();
1811- try Conn .writeAll (socket , header );
1841+ // try Conn.writeAll(socket, header);
1842+ var tls_client = try tls .client (std.net.Stream { .handle = socket }, .{
1843+ .host = request ._connect_host ,
1844+ .root_ca = request ._client .root_ca ,
1845+ .insecure_skip_verify = request ._tls_verify_host == false ,
1846+ .key_log_callback = tls .config .key_log .callback ,
1847+ });
1848+ try tls_client .writeAll (header );
18121849
18131850 var pos : usize = 0 ;
18141851 var reader = request .newReader ();
@@ -1819,18 +1856,24 @@ const SyncHandler = struct {
18191856 // we only send CONNECT requests on newly established connections
18201857 // and maybeRetryOrErr is only for connections that might have been
18211858 // closed while being kept-alive
1822- const n = try posix .read (socket , read_buf [pos .. ]);
1859+ // const n = try posix.read(socket, read_buf[pos..]);
1860+ // const n = switch (self.*) {
1861+ // .tls => |tls_client| try tls_client.read(buf),
1862+ // .plain => |socket| try posix.read(socket, buf),
1863+ // };
1864+ const n = try tls_client .read (read_buf [pos .. ]);
18231865 if (n == 0 ) {
18241866 return error .ConnectionResetByPeer ;
18251867 }
18261868 pos += n ;
18271869 if (try reader .connectResponse (read_buf [0.. pos ])) {
18281870 // returns true if we have a successful connect response
1829- return ;
1871+ return tls_client ;
18301872 }
18311873
18321874 // we don't have enough data yet.
18331875 }
1876+ return tls_client ;
18341877 }
18351878
18361879 fn maybeRetryOrErr (self : * SyncHandler , err : anyerror ) ! Response {
@@ -1880,11 +1923,18 @@ const SyncHandler = struct {
18801923 }
18811924
18821925 const Conn = union (enum ) {
1926+ tls_in_tls : * tls .Connection (* tls .Connection (std .net .Stream )),
18831927 tls : * tls .Connection (std .net .Stream ),
18841928 plain : posix.socket_t ,
18851929
18861930 fn sendRequest (self : * Conn , header : []const u8 , body : ? []const u8 ) ! void {
18871931 switch (self .* ) {
1932+ .tls_in_tls = > | tls_client | {
1933+ try tls_client .writeAll (header );
1934+ if (body ) | b | {
1935+ try tls_client .writeAll (b );
1936+ }
1937+ },
18881938 .tls = > | tls_client | {
18891939 try tls_client .writeAll (header );
18901940 if (body ) | b | {
@@ -1906,6 +1956,7 @@ const SyncHandler = struct {
19061956
19071957 fn read (self : * Conn , buf : []u8 ) ! usize {
19081958 const n = switch (self .* ) {
1959+ .tls_in_tls = > | tls_client | try tls_client .read (buf ),
19091960 .tls = > | tls_client | try tls_client .read (buf ),
19101961 .plain = > | socket | try posix .read (socket , buf ),
19111962 };
@@ -2081,6 +2132,7 @@ const Reader = struct {
20812132 if (result .done == false ) {
20822133 // CONNECT responses should not have a body. If the header is
20832134 // done, then the entire response should be done.
2135+ log .err (.http_client , "InvalidConnectResponse" , .{ .unprocessed = result .unprocessed .? });
20842136 return error .InvalidConnectResponse ;
20852137 }
20862138
0 commit comments