std.http: fix leaked connections (#16341)

The early return in pool release was causing leaked connections.
Closes #16282.
This commit is contained in:
Nameless 2023-07-07 15:08:19 -05:00 committed by GitHub
parent 80404cc928
commit b9fc0d2908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 4 deletions

View File

@ -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) {

View File

@ -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);