mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
Merge pull request #978 from lightpanda-io/dynamic_cdp_read_buffer
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Make the CDP read buffer heap allocated & dynamic
This commit is contained in:
@@ -36,7 +36,7 @@ const MAX_HTTP_REQUEST_SIZE = 4096;
|
|||||||
// max message size
|
// max message size
|
||||||
// +14 for max websocket payload overhead
|
// +14 for max websocket payload overhead
|
||||||
// +140 for the max control packet that might be interleaved in a message
|
// +140 for the max control packet that might be interleaved in a message
|
||||||
const MAX_MESSAGE_SIZE = 512 * 1024 + 14;
|
const MAX_MESSAGE_SIZE = 512 * 1024 + 14 + 140;
|
||||||
|
|
||||||
pub const Server = struct {
|
pub const Server = struct {
|
||||||
app: *App,
|
app: *App,
|
||||||
@@ -188,12 +188,15 @@ pub const Client = struct {
|
|||||||
// we expect the socket to come to us as nonblocking
|
// we expect the socket to come to us as nonblocking
|
||||||
std.debug.assert(socket_flags & nonblocking == nonblocking);
|
std.debug.assert(socket_flags & nonblocking == nonblocking);
|
||||||
|
|
||||||
|
var reader = try Reader(true).init(server.allocator);
|
||||||
|
errdefer reader.deinit();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.socket = socket,
|
.socket = socket,
|
||||||
.server = server,
|
.server = server,
|
||||||
|
.reader = reader,
|
||||||
.mode = .{ .http = {} },
|
.mode = .{ .http = {} },
|
||||||
.socket_flags = socket_flags,
|
.socket_flags = socket_flags,
|
||||||
.reader = .{ .allocator = server.allocator },
|
|
||||||
.send_arena = ArenaAllocator.init(server.allocator),
|
.send_arena = ArenaAllocator.init(server.allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -537,14 +540,23 @@ fn Reader(comptime EXPECT_MASK: bool) type {
|
|||||||
|
|
||||||
// we add 140 to allow 1 control message (ping/pong/close) to be
|
// we add 140 to allow 1 control message (ping/pong/close) to be
|
||||||
// fragmented into a normal message.
|
// fragmented into a normal message.
|
||||||
buf: [MAX_MESSAGE_SIZE + 140]u8 = undefined,
|
buf: []u8,
|
||||||
|
|
||||||
fragments: ?Fragments = null,
|
fragments: ?Fragments = null,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
fn init(allocator: Allocator) !Self {
|
||||||
|
const buf = try allocator.alloc(u8, 16 * 1024);
|
||||||
|
return .{
|
||||||
|
.buf = buf,
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(self: *Self) void {
|
fn deinit(self: *Self) void {
|
||||||
self.cleanup();
|
self.cleanup();
|
||||||
|
self.allocator.free(self.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cleanup(self: *Self) void {
|
fn cleanup(self: *Self) void {
|
||||||
@@ -613,9 +625,14 @@ fn Reader(comptime EXPECT_MASK: bool) type {
|
|||||||
}
|
}
|
||||||
} else if (message_len > MAX_MESSAGE_SIZE) {
|
} else if (message_len > MAX_MESSAGE_SIZE) {
|
||||||
return error.TooLarge;
|
return error.TooLarge;
|
||||||
}
|
} else if (message_len > self.buf.len) {
|
||||||
|
const len = self.buf.len;
|
||||||
if (buf.len < message_len) {
|
self.buf = try growBuffer(self.allocator, self.buf, message_len);
|
||||||
|
buf = self.buf[0..len];
|
||||||
|
// we need more data
|
||||||
|
return null;
|
||||||
|
} else if (buf.len < message_len) {
|
||||||
|
// we need more data
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,13 +770,32 @@ fn Reader(comptime EXPECT_MASK: bool) type {
|
|||||||
|
|
||||||
// We're here because we either don't have enough bytes of the next
|
// We're here because we either don't have enough bytes of the next
|
||||||
// message, or we know that it won't fit in our buffer as-is.
|
// message, or we know that it won't fit in our buffer as-is.
|
||||||
std.mem.copyForwards(u8, &self.buf, partial);
|
std.mem.copyForwards(u8, self.buf, partial);
|
||||||
self.pos = 0;
|
self.pos = 0;
|
||||||
self.len = partial_bytes;
|
self.len = partial_bytes;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn growBuffer(allocator: Allocator, buf: []u8, required_capacity: usize) ![]u8 {
|
||||||
|
// from std.ArrayList
|
||||||
|
var new_capacity = buf.len;
|
||||||
|
while (true) {
|
||||||
|
new_capacity +|= new_capacity / 2 + 8;
|
||||||
|
if (new_capacity >= required_capacity) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug(.app, "CDP buffer growth", .{ .from = buf.len, .to = new_capacity });
|
||||||
|
|
||||||
|
if (allocator.resize(buf, new_capacity)) {
|
||||||
|
return buf.ptr[0..new_capacity];
|
||||||
|
}
|
||||||
|
const new_buffer = try allocator.alloc(u8, new_capacity);
|
||||||
|
@memcpy(new_buffer[0..buf.len], buf);
|
||||||
|
allocator.free(buf);
|
||||||
|
return new_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
const Fragments = struct {
|
const Fragments = struct {
|
||||||
type: Message.Type,
|
type: Message.Type,
|
||||||
message: std.ArrayListUnmanaged(u8),
|
message: std.ArrayListUnmanaged(u8),
|
||||||
@@ -1037,8 +1073,8 @@ test "Client: read invalid websocket message" {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// length of message is 0000 0401, i.e: 1024 * 512 + 1
|
// length of message is 0000 0810, i.e: 1024 * 512 + 265
|
||||||
try assertWebSocketError(1009, &.{ 129, 255, 0, 0, 0, 0, 0, 8, 0, 1, 'm', 'a', 's', 'k' });
|
try assertWebSocketError(1009, &.{ 129, 255, 0, 0, 0, 0, 0, 8, 1, 0, 'm', 'a', 's', 'k' });
|
||||||
|
|
||||||
// continuation type message must come after a normal message
|
// continuation type message must come after a normal message
|
||||||
// even when not a fin frame
|
// even when not a fin frame
|
||||||
@@ -1260,7 +1296,10 @@ fn createTestClient() !TestClient {
|
|||||||
try posix.setsockopt(stream.handle, posix.SOL.SOCKET, posix.SO.SNDTIMEO, &timeout);
|
try posix.setsockopt(stream.handle, posix.SOL.SOCKET, posix.SO.SNDTIMEO, &timeout);
|
||||||
return .{
|
return .{
|
||||||
.stream = stream,
|
.stream = stream,
|
||||||
.reader = .{ .allocator = testing.allocator },
|
.reader = .{
|
||||||
|
.allocator = testing.allocator,
|
||||||
|
.buf = try testing.allocator.alloc(u8, 1024 * 16),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user