zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit b9fc0d2908371dc4f7c95c03972d42e290d6e1e0 (tree)
parent 80404cc928c758f7063da42a0d68669998613969
Author: Nameless <truemedian@gmail.com>
Date:   Fri,  7 Jul 2023 15:08:19 -0500

std.http: fix leaked connections (#16341)

The early return in pool release was causing leaked connections.
Closes #16282.
Diffstat:
Mlib/std/http/Client.zig | 7+++----
Mtest/standalone/http.zig | 24++++++++++++++++++++++++
2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/lib/std/http/Client.zig b/lib/std/http/Client.zig @@ -92,16 +92,15 @@ pub const ConnectionPool = struct { if (node.data.closing) { node.data.deinit(client); - return client.allocator.destroy(node); } - if (pool.free_len + 1 >= pool.free_size) { + if (pool.free_len >= pool.free_size) { const popped = pool.free.popFirst() orelse unreachable; + pool.free_len -= 1; popped.data.deinit(client); - - return client.allocator.destroy(popped); + client.allocator.destroy(popped); } if (node.data.proxied) { diff --git a/test/standalone/http.zig b/test/standalone/http.zig @@ -571,6 +571,30 @@ pub fn main() !void { // connection has been kept alive try testing.expect(client.connection_pool.free_len == 1); + { // issue 16282 + const location = try std.fmt.allocPrint(calloc, "http://127.0.0.1:{d}/get", .{port}); + defer calloc.free(location); + const uri = try std.Uri.parse(location); + + const total_connections = client.connection_pool.free_size + 64; + var requests = try calloc.alloc(http.Client.Request, total_connections); + defer calloc.free(requests); + + for (0..total_connections) |i| { + var req = try client.request(.GET, uri, .{ .allocator = calloc }, .{}); + req.response.parser.done = true; + req.connection.?.data.closing = false; + requests[i] = req; + } + + for (0..total_connections) |i| { + requests[i].deinit(); + } + + // free connections should be full now + try testing.expect(client.connection_pool.free_len == client.connection_pool.free_size); + } + client.deinit(); killServer(server.socket.listen_address);