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;
|
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
|
// we expect value to be lowercase
|
||||||
fn parseContentType(value: []const u8) !struct { ContentType, usize } {
|
fn parseContentType(value: []const u8) !struct { ContentType, usize } {
|
||||||
const end = std.mem.indexOfScalarPos(u8, value, 0, ';') orelse value.len;
|
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 Incrementing = @import("id.zig").Incrementing;
|
||||||
const Notification = @import("../Notification.zig");
|
const Notification = @import("../Notification.zig");
|
||||||
const InterceptState = @import("domains/fetch.zig").InterceptState;
|
const InterceptState = @import("domains/fetch.zig").InterceptState;
|
||||||
|
const Mime = @import("../browser/Mime.zig");
|
||||||
|
|
||||||
pub const URL_BASE = "chrome://newtab/";
|
pub const URL_BASE = "chrome://newtab/";
|
||||||
|
|
||||||
@@ -315,6 +316,11 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
const Node = @import("Node.zig");
|
const Node = @import("Node.zig");
|
||||||
const AXNode = @import("AXNode.zig");
|
const AXNode = @import("AXNode.zig");
|
||||||
|
|
||||||
|
const CapturedResponse = struct {
|
||||||
|
must_encode: bool,
|
||||||
|
data: std.ArrayList(u8),
|
||||||
|
};
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
id: []const u8,
|
id: []const u8,
|
||||||
cdp: *CDP_T,
|
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
|
// 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
|
// memory for an arbitrary amount of time, then that's where we're going
|
||||||
// to store the,
|
// to store the,
|
||||||
captured_responses: std.AutoHashMapUnmanaged(usize, std.ArrayList(u8)),
|
captured_responses: std.AutoHashMapUnmanaged(usize, CapturedResponse),
|
||||||
|
|
||||||
notification: *Notification,
|
notification: *Notification,
|
||||||
|
|
||||||
@@ -628,6 +634,35 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
pub fn onHttpResponseHeadersDone(ctx: *anyopaque, msg: *const Notification.ResponseHeaderDone) !void {
|
pub fn onHttpResponseHeadersDone(ctx: *anyopaque, msg: *const Notification.ResponseHeaderDone) !void {
|
||||||
const self: *Self = @ptrCast(@alignCast(ctx));
|
const self: *Self = @ptrCast(@alignCast(ctx));
|
||||||
defer self.resetNotificationArena();
|
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);
|
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 arena = self.page_arena;
|
||||||
|
|
||||||
const id = msg.transfer.id;
|
const id = msg.transfer.id;
|
||||||
const gop = try self.captured_responses.getOrPut(arena, id);
|
const resp = self.captured_responses.getPtr(id) orelse lp.assert(false, "onHttpResponseData missinf captured response", .{});
|
||||||
if (!gop.found_existing) {
|
|
||||||
gop.value_ptr.* = .{};
|
return resp.data.appendSlice(arena, msg.data);
|
||||||
}
|
|
||||||
try gop.value_ptr.appendSlice(arena, try arena.dupe(u8, msg.data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onHttpRequestAuthRequired(ctx: *anyopaque, data: *const Notification.RequestAuthRequired) !void {
|
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 request_id = try idFromRequestId(params.requestId);
|
||||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
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(.{
|
if (!resp.must_encode) {
|
||||||
.body = buf.items,
|
return cmd.sendResult(.{
|
||||||
.base64Encoded = false,
|
.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