mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-28 15:40:04 +00:00
Merge pull request #1946 from lightpanda-io/cdp-response-body
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / wba-demo-scripts (push) Has been cancelled
e2e-test / wba-test (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig fmt (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (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 / wba-demo-scripts (push) Has been cancelled
e2e-test / wba-test (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig fmt (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
Encode non-utf8 Network.getResponseBody in base64
This commit is contained in:
@@ -386,6 +386,14 @@ pub fn isHTML(self: *const Mime) bool {
|
||||
return self.content_type == .text_html;
|
||||
}
|
||||
|
||||
pub fn isText(mime: *const Mime) bool {
|
||||
return switch (mime.content_type) {
|
||||
.text_xml, .text_html, .text_javascript, .text_plain, .text_css => true,
|
||||
.application_json => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
// we expect value to be lowercase
|
||||
fn parseContentType(value: []const u8) !struct { ContentType, usize } {
|
||||
const end = std.mem.indexOfScalarPos(u8, value, 0, ';') orelse value.len;
|
||||
|
||||
@@ -33,6 +33,7 @@ const Page = @import("../browser/Page.zig");
|
||||
const Incrementing = @import("id.zig").Incrementing;
|
||||
const Notification = @import("../Notification.zig");
|
||||
const InterceptState = @import("domains/fetch.zig").InterceptState;
|
||||
const Mime = @import("../browser/Mime.zig");
|
||||
|
||||
pub const URL_BASE = "chrome://newtab/";
|
||||
|
||||
@@ -315,6 +316,11 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
const Node = @import("Node.zig");
|
||||
const AXNode = @import("AXNode.zig");
|
||||
|
||||
const CapturedResponse = struct {
|
||||
must_encode: bool,
|
||||
data: std.ArrayList(u8),
|
||||
};
|
||||
|
||||
return struct {
|
||||
id: []const u8,
|
||||
cdp: *CDP_T,
|
||||
@@ -375,7 +381,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
// ever streamed. So if CDP is the only thing that needs bodies in
|
||||
// memory for an arbitrary amount of time, then that's where we're going
|
||||
// to store the,
|
||||
captured_responses: std.AutoHashMapUnmanaged(usize, std.ArrayList(u8)),
|
||||
captured_responses: std.AutoHashMapUnmanaged(usize, CapturedResponse),
|
||||
|
||||
notification: *Notification,
|
||||
|
||||
@@ -628,6 +634,35 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
pub fn onHttpResponseHeadersDone(ctx: *anyopaque, msg: *const Notification.ResponseHeaderDone) !void {
|
||||
const self: *Self = @ptrCast(@alignCast(ctx));
|
||||
defer self.resetNotificationArena();
|
||||
|
||||
const arena = self.page_arena;
|
||||
|
||||
// Prepare the captured response value.
|
||||
const id = msg.transfer.id;
|
||||
const gop = try self.captured_responses.getOrPut(arena, id);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{
|
||||
.data = .empty,
|
||||
// Encode the data in base64 by default, but don't encode
|
||||
// for well known content-type.
|
||||
.must_encode = blk: {
|
||||
const transfer = msg.transfer;
|
||||
if (transfer.response_header.?.contentType()) |ct| {
|
||||
const mime = try Mime.parse(ct);
|
||||
|
||||
if (!mime.isText()) {
|
||||
break :blk true;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, "UTF-8", mime.charsetString())) {
|
||||
break :blk false;
|
||||
}
|
||||
}
|
||||
break :blk true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return @import("domains/network.zig").httpResponseHeaderDone(self.notification_arena, self, msg);
|
||||
}
|
||||
|
||||
@@ -641,11 +676,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
const arena = self.page_arena;
|
||||
|
||||
const id = msg.transfer.id;
|
||||
const gop = try self.captured_responses.getOrPut(arena, id);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
try gop.value_ptr.appendSlice(arena, try arena.dupe(u8, msg.data));
|
||||
const resp = self.captured_responses.getPtr(id) orelse lp.assert(false, "onHttpResponseData missinf captured response", .{});
|
||||
|
||||
return resp.data.appendSlice(arena, msg.data);
|
||||
}
|
||||
|
||||
pub fn onHttpRequestAuthRequired(ctx: *anyopaque, data: *const Notification.RequestAuthRequired) !void {
|
||||
|
||||
@@ -208,11 +208,22 @@ fn getResponseBody(cmd: anytype) !void {
|
||||
|
||||
const request_id = try idFromRequestId(params.requestId);
|
||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||
const buf = bc.captured_responses.getPtr(request_id) orelse return error.RequestNotFound;
|
||||
const resp = bc.captured_responses.getPtr(request_id) orelse return error.RequestNotFound;
|
||||
|
||||
try cmd.sendResult(.{
|
||||
.body = buf.items,
|
||||
.base64Encoded = false,
|
||||
if (!resp.must_encode) {
|
||||
return cmd.sendResult(.{
|
||||
.body = resp.data.items,
|
||||
.base64Encoded = false,
|
||||
}, .{});
|
||||
}
|
||||
|
||||
const encoded_len = std.base64.standard.Encoder.calcSize(resp.data.items.len);
|
||||
const encoded = try cmd.arena.alloc(u8, encoded_len);
|
||||
_ = std.base64.standard.Encoder.encode(encoded, resp.data.items);
|
||||
|
||||
return cmd.sendResult(.{
|
||||
.body = encoded,
|
||||
.base64Encoded = true,
|
||||
}, .{});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user