diff --git a/src/browser/HttpClient.zig b/src/browser/HttpClient.zig index 7fb4864b0..b64c55f89 100644 --- a/src/browser/HttpClient.zig +++ b/src/browser/HttpClient.zig @@ -2098,7 +2098,12 @@ pub const Transfer = struct { return result; } - fn dataCallback(buffer: [*]const u8, chunk_count: usize, chunk_len: usize, data: *anyopaque) usize { + fn dataCallback( + buffer: [*]const u8, + chunk_count: usize, + chunk_len: usize, + data: *anyopaque, + ) callconv(.c) usize { // libcurl should only ever emit 1 chunk at a time if (comptime IS_DEBUG) { std.debug.assert(chunk_count == 1); diff --git a/src/browser/webapi/net/WebSocket.zig b/src/browser/webapi/net/WebSocket.zig index a98efc591..dd33d99a8 100644 --- a/src/browser/webapi/net/WebSocket.zig +++ b/src/browser/webapi/net/WebSocket.zig @@ -545,11 +545,16 @@ fn dispatchCloseEvent(self: *WebSocket, code: u16, reason: []const u8, was_clean } } -fn sendDataCallback(buffer: [*]u8, buf_count: usize, buf_len: usize, data: *anyopaque) usize { +fn sendDataCallback( + buffer: [*c]u8, + buf_count: usize, + buf_len: usize, + raw_connection: ?*anyopaque, +) callconv(.c) usize { if (comptime IS_DEBUG) { std.debug.assert(buf_count == 1); } - const conn: *http.Connection = @ptrCast(@alignCast(data)); + const conn: *http.Connection = @ptrCast(@alignCast(raw_connection)); return _sendDataCallback(conn, buffer[0..buf_len]) catch |err| { log.warn(.websocket, "send callback", .{ .err = err }); return http.readfunc_pause; @@ -624,7 +629,12 @@ fn writeContent(self: *WebSocket, conn: *http.Connection, buf: []u8, byte_msg: M return to_copy; } -fn receivedDataCallback(buffer: [*]const u8, buf_count: usize, buf_len: usize, data: *anyopaque) usize { +fn receivedDataCallback( + buffer: [*]const u8, + buf_count: usize, + buf_len: usize, + data: *anyopaque, +) callconv(.c) usize { if (comptime IS_DEBUG) { std.debug.assert(buf_count == 1); } @@ -695,7 +705,12 @@ fn _receivedDataCallback(conn: *http.Connection, data: []const u8) !void { // libcurl has no mechanism to signal that the connection is established. The // best option I could come up with was looking for an upgrade header response. -fn receivedHeaderCallback(buffer: [*]const u8, header_count: usize, buf_len: usize, data: *anyopaque) usize { +fn receivedHeaderCallback( + buffer: [*]const u8, + header_count: usize, + buf_len: usize, + data: *anyopaque, +) callconv(.c) usize { if (comptime IS_DEBUG) { std.debug.assert(header_count == 1); } diff --git a/src/network/http.zig b/src/network/http.zig index ace8fa270..337df8711 100644 --- a/src/network/http.zig +++ b/src/network/http.zig @@ -328,11 +328,13 @@ pub const ResponseHead = struct { /// Returns CURL_SOCKET_BAD to block; otherwise creates and returns a real socket fd. /// clientp is a *const IpFilter passed via CURLOPT_OPENSOCKETDATA. fn opensocketCallback( - purpose: libcurl.CurlSockType, - address: *libcurl.CurlSockAddr, - clientp: ?*anyopaque, -) libcurl.CurlSocket { - const filter: *const IpFilter = @ptrCast(@alignCast(clientp orelse return libcurl.CURL_SOCKET_BAD)); + raw_ip_filter: ?*anyopaque, + _: c_uint, + addr: [*c]libcurl.CurlSockAddr, +) callconv(.c) libcurl.CurlSocket { + const address: *libcurl.CurlSockAddr = @ptrCast(addr); + const filter: *const IpFilter = @ptrCast(@alignCast(raw_ip_filter orelse return libcurl.CURL_SOCKET_BAD)); + if (filter.isBlockedSockaddr(address)) { if (address.family == posix.AF.INET or address.family == posix.AF.INET6) { const ip = std.net.Address.initPosix(@ptrCast(&address.addr)); @@ -342,7 +344,7 @@ fn opensocketCallback( } return libcurl.CURL_SOCKET_BAD; } - _ = purpose; // purpose is informational; we always open the same socket type + const fd = posix.socket( @intCast(address.family), @intCast(address.socktype), @@ -464,7 +466,7 @@ pub const Connection = struct { pub fn setWriteCallback( self: *Connection, - comptime data_cb: libcurl.CurlWriteFunction, + comptime data_cb: libcurl.WriteFunction, ) !void { try libcurl.curl_easy_setopt(self._easy, .write_data, self); try libcurl.curl_easy_setopt(self._easy, .write_function, data_cb); @@ -472,7 +474,7 @@ pub const Connection = struct { pub fn setReadCallback( self: *Connection, - comptime data_cb: libcurl.CurlReadFunction, + comptime data_cb: libcurl.ReadFunction, upload: bool, ) !void { try libcurl.curl_easy_setopt(self._easy, .read_data, self); @@ -484,7 +486,7 @@ pub const Connection = struct { pub fn setHeaderCallback( self: *Connection, - comptime data_cb: libcurl.CurlHeaderFunction, + comptime data_cb: libcurl.HeaderFunction, ) !void { try libcurl.curl_easy_setopt(self._easy, .header_data, self); try libcurl.curl_easy_setopt(self._easy, .header_function, data_cb); @@ -576,7 +578,7 @@ pub const Connection = struct { } } - fn discardBody(_: [*]const u8, count: usize, len: usize, _: ?*anyopaque) usize { + fn discardBody(_: [*]const u8, count: usize, len: usize, _: ?*anyopaque) callconv(.c) usize { return count * len; } @@ -864,7 +866,7 @@ test "opensocketCallback: private IPv4 returns CURL_SOCKET_BAD" { const filter = IpFilter.init(true, null); var sa = makeSockAddrV4(.{ 127, 0, 0, 1 }); - const result = opensocketCallback(.ipcxn, &sa, @ptrCast(@constCast(&filter))); + const result = opensocketCallback(@ptrCast(@constCast(&filter)), @intFromEnum(libcurl.CurlSockType.ipcxn), &sa); try testing.expectEqual(libcurl.CURL_SOCKET_BAD, result); } @@ -873,7 +875,7 @@ test "opensocketCallback: public IPv4 opens a real socket" { const filter = IpFilter.init(true, null); var sa = makeSockAddrV4(.{ 8, 8, 8, 8 }); - const fd = opensocketCallback(.ipcxn, &sa, @ptrCast(@constCast(&filter))); + const fd = opensocketCallback(@ptrCast(@constCast(&filter)), @intFromEnum(libcurl.CurlSockType.ipcxn), &sa); defer posix.close(fd); // A real fd is always >= 0 @@ -882,7 +884,7 @@ test "opensocketCallback: public IPv4 opens a real socket" { test "opensocketCallback: null clientp returns CURL_SOCKET_BAD (fail-closed)" { var sa = makeSockAddrV4(.{ 8, 8, 8, 8 }); - const result = opensocketCallback(.ipcxn, &sa, null); + const result = opensocketCallback(null, @intFromEnum(libcurl.CurlSockType.ipcxn), &sa); try testing.expectEqual(libcurl.CURL_SOCKET_BAD, result); } @@ -890,7 +892,7 @@ test "opensocketCallback: block_private=false allows private IP" { // When block_private is false the filter blocks nothing const filter = IpFilter.init(false, null); var sa = makeSockAddrV4(.{ 127, 0, 0, 1 }); - const fd = opensocketCallback(.ipcxn, &sa, @ptrCast(@constCast(&filter))); + const fd = opensocketCallback(@ptrCast(@constCast(&filter)), @intFromEnum(libcurl.CurlSockType.ipcxn), &sa); defer posix.close(fd); try testing.expect(fd >= 0);