Skip to content

Commit b9fc0d2

Browse files
authored
std.http: fix leaked connections (#16341)
The early return in pool release was causing leaked connections. Closes #16282.
1 parent 80404cc commit b9fc0d2

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

lib/std/http/Client.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,15 @@ pub const ConnectionPool = struct {
9292

9393
if (node.data.closing) {
9494
node.data.deinit(client);
95-
9695
return client.allocator.destroy(node);
9796
}
9897

99-
if (pool.free_len + 1 >= pool.free_size) {
98+
if (pool.free_len >= pool.free_size) {
10099
const popped = pool.free.popFirst() orelse unreachable;
100+
pool.free_len -= 1;
101101

102102
popped.data.deinit(client);
103-
104-
return client.allocator.destroy(popped);
103+
client.allocator.destroy(popped);
105104
}
106105

107106
if (node.data.proxied) {

test/standalone/http.zig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,30 @@ pub fn main() !void {
571571
// connection has been kept alive
572572
try testing.expect(client.connection_pool.free_len == 1);
573573

574+
{ // issue 16282
575+
const location = try std.fmt.allocPrint(calloc, "http://127.0.0.1:{d}/get", .{port});
576+
defer calloc.free(location);
577+
const uri = try std.Uri.parse(location);
578+
579+
const total_connections = client.connection_pool.free_size + 64;
580+
var requests = try calloc.alloc(http.Client.Request, total_connections);
581+
defer calloc.free(requests);
582+
583+
for (0..total_connections) |i| {
584+
var req = try client.request(.GET, uri, .{ .allocator = calloc }, .{});
585+
req.response.parser.done = true;
586+
req.connection.?.data.closing = false;
587+
requests[i] = req;
588+
}
589+
590+
for (0..total_connections) |i| {
591+
requests[i].deinit();
592+
}
593+
594+
// free connections should be full now
595+
try testing.expect(client.connection_pool.free_len == client.connection_pool.free_size);
596+
}
597+
574598
client.deinit();
575599

576600
killServer(server.socket.listen_address);

0 commit comments

Comments
 (0)