diff --git a/src/http.zig b/src/http.zig index 62d4fb50ae..cfeecb7500 100644 --- a/src/http.zig +++ b/src/http.zig @@ -504,41 +504,48 @@ fn NewHTTPContext(comptime ssl: bool) type { success: i32, ssl_error: uws.us_bun_verify_error_t, ) void { - const authorized = if (success == 1) true else false; + const handshake_success = if (success == 1) true else false; const handshake_error = HTTPCertError{ .error_no = ssl_error.error_no, .code = if (ssl_error.code == null) "" else ssl_error.code[0..bun.len(ssl_error.code) :0], .reason = if (ssl_error.code == null) "" else ssl_error.reason[0..bun.len(ssl_error.reason) :0], }; - // log("onHandshake(0x{}) authorized: {} error: {s}", .{ bun.fmt.hexIntUpper(@intFromPtr(socket.socket)), authorized, handshake_error.code }); const active = getTagged(ptr); if (active.get(HTTPClient)) |client| { - if (handshake_error.error_no != 0 and (client.flags.reject_unauthorized or !authorized)) { - client.closeAndFail(BoringSSL.getCertErrorFromNo(handshake_error.error_no), comptime ssl, socket); - return; - } - // no handshake_error at this point - if (authorized) { - client.flags.did_have_handshaking_error = handshake_error.error_no != 0; + // handshake completed but we may have ssl errors + client.flags.did_have_handshaking_error = handshake_error.error_no != 0; + if (handshake_success) { + if(client.flags.reject_unauthorized) { + // only reject the connection if reject_unauthorized == true + if(client.flags.did_have_handshaking_error) { + client.closeAndFail(BoringSSL.getCertErrorFromNo(handshake_error.error_no), comptime ssl, socket); + return; + } - // if checkServerIdentity returns false, we dont call open this means that the connection was rejected - if (!client.checkServerIdentity(comptime ssl, socket, handshake_error)) { - client.flags.did_have_handshaking_error = true; + // if checkServerIdentity returns false, we dont call open this means that the connection was rejected + if (!client.checkServerIdentity(comptime ssl, socket, handshake_error)) { + client.flags.did_have_handshaking_error = true; - if (!socket.isClosed()) terminateSocket(socket); - return; + if (!socket.isClosed()) terminateSocket(socket); + return; + } } return client.firstCall(comptime ssl, socket); } else { - // if authorized it self is false, this means that the connection was rejected - terminateSocket(socket); - if (client.state.stage != .done and client.state.stage != .fail) - client.fail(error.ConnectionRefused); + // if we are here is because server rejected us, and the error_no is the cause of this + // if we set reject_unauthorized == false this means the server requires custom CA aka NODE_EXTRA_CA_CERTS + if(client.flags.did_have_handshaking_error) { + client.closeAndFail(BoringSSL.getCertErrorFromNo(handshake_error.error_no), comptime ssl, socket); + return; + } + // if handshake_success it self is false, this means that the connection was rejected + client.closeAndFail(error.ConnectionRefused, comptime ssl, socket); return; } + } if (socket.isClosed()) { @@ -550,7 +557,7 @@ fn NewHTTPContext(comptime ssl: bool) type { return; } - if (authorized) { + if (handshake_success) { if (active.is(PooledSocket)) { // Allow pooled sockets to be reused if the handshake was successful. socket.setTimeout(0); @@ -2851,11 +2858,11 @@ pub fn onWritable(this: *HTTPClient, comptime is_first_call: bool, comptime is_s } pub fn closeAndFail(this: *HTTPClient, err: anyerror, comptime is_ssl: bool, socket: NewHTTPContext(is_ssl).HTTPSocket) void { + if (!socket.isClosed()) { + NewHTTPContext(is_ssl).terminateSocket(socket); + } if (this.state.stage != .fail and this.state.stage != .done) { log("closeAndFail: {s}", .{@errorName(err)}); - if (!socket.isClosed()) { - NewHTTPContext(is_ssl).terminateSocket(socket); - } this.fail(err); } } diff --git a/src/http/websocket_http_client.zig b/src/http/websocket_http_client.zig index 05dd69780b..ad5d1f046c 100644 --- a/src/http/websocket_http_client.zig +++ b/src/http/websocket_http_client.zig @@ -391,18 +391,20 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { pub fn handleHandshake(this: *HTTPClient, socket: Socket, success: i32, ssl_error: uws.us_bun_verify_error_t) void { log("onHandshake({d})", .{success}); - const authorized = if (success == 1) true else false; + const handshake_success = if (success == 1) true else false; var reject_unauthorized = false; if (this.outgoing_websocket) |ws| { reject_unauthorized = ws.rejectUnauthorized(); } - if (ssl_error.error_no != 0 and (reject_unauthorized or !authorized)) { - this.fail(ErrorCode.tls_handshake_failed); - return; - } - if (authorized) { - if (reject_unauthorized) { + if (handshake_success) { + // handshake completed but we may have ssl errors + if(reject_unauthorized) { + // only reject the connection if reject_unauthorized == true + if(ssl_error.error_no != 0){ + this.fail(ErrorCode.tls_handshake_failed); + return; + } const ssl_ptr = @as(*BoringSSL.SSL, @ptrCast(socket.getNativeHandle())); if (BoringSSL.SSL_get_servername(ssl_ptr, 0)) |servername| { const hostname = servername[0..bun.len(servername)]; @@ -411,7 +413,12 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { } } } + } else { + // if we are here is because server rejected us, and the error_no is the cause of this + // if we set reject_unauthorized == false this means the server requires custom CA aka NODE_EXTRA_CA_CERTS + this.fail(ErrorCode.tls_handshake_failed); } + } pub fn handleOpen(this: *HTTPClient, socket: Socket) void {