mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +00:00
use renamed LiveTransfer instead of Transfer
This commit is contained in:
@@ -21,7 +21,7 @@ const lp = @import("lightpanda");
|
|||||||
|
|
||||||
const log = @import("log.zig");
|
const log = @import("log.zig");
|
||||||
const Page = @import("browser/Page.zig");
|
const Page = @import("browser/Page.zig");
|
||||||
const Transfer = @import("browser/HttpClient.zig").Transfer;
|
const LiveTransfer = @import("browser/HttpClient.zig").LiveTransfer;
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
@@ -138,34 +138,34 @@ pub const PageFrameCreated = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestStart = struct {
|
pub const RequestStart = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestIntercept = struct {
|
pub const RequestIntercept = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
wait_for_interception: *bool,
|
wait_for_interception: *bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestAuthRequired = struct {
|
pub const RequestAuthRequired = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
wait_for_interception: *bool,
|
wait_for_interception: *bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ResponseData = struct {
|
pub const ResponseData = struct {
|
||||||
data: []const u8,
|
data: []const u8,
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ResponseHeaderDone = struct {
|
pub const ResponseHeaderDone = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestDone = struct {
|
pub const RequestDone = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestFail = struct {
|
pub const RequestFail = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
err: anyerror,
|
err: anyerror,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ pending_robots_queue: std.StringHashMapUnmanaged(std.ArrayList(Request)) = .empt
|
|||||||
// Once we have a handle/easy to process a request with, we create a Transfer
|
// Once we have a handle/easy to process a request with, we create a Transfer
|
||||||
// which contains the Request as well as any state we need to process the
|
// which contains the Request as well as any state we need to process the
|
||||||
// request. These wil come and go with each request.
|
// request. These wil come and go with each request.
|
||||||
transfer_pool: std.heap.MemoryPool(Transfer),
|
transfer_pool: std.heap.MemoryPool(LiveTransfer),
|
||||||
|
|
||||||
// The current proxy. CDP can change it, restoreOriginalProxy restores
|
// The current proxy. CDP can change it, restoreOriginalProxy restores
|
||||||
// from config.
|
// from config.
|
||||||
@@ -135,7 +135,7 @@ pub const CDPClient = struct {
|
|||||||
const TransferQueue = std.DoublyLinkedList;
|
const TransferQueue = std.DoublyLinkedList;
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, network: *Network) !*Client {
|
pub fn init(allocator: Allocator, network: *Network) !*Client {
|
||||||
var transfer_pool = std.heap.MemoryPool(Transfer).init(allocator);
|
var transfer_pool = std.heap.MemoryPool(LiveTransfer).init(allocator);
|
||||||
errdefer transfer_pool.deinit();
|
errdefer transfer_pool.deinit();
|
||||||
|
|
||||||
const client = try allocator.create(Client);
|
const client = try allocator.create(Client);
|
||||||
@@ -199,7 +199,7 @@ fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32) void {
|
|||||||
while (n) |node| {
|
while (n) |node| {
|
||||||
n = node.next;
|
n = node.next;
|
||||||
const conn: *Net.Connection = @fieldParentPtr("node", node);
|
const conn: *Net.Connection = @fieldParentPtr("node", node);
|
||||||
var transfer = Transfer.fromConnection(conn) catch |err| {
|
var transfer = LiveTransfer.fromConnection(conn) catch |err| {
|
||||||
// Let's cleanup what we can
|
// Let's cleanup what we can
|
||||||
self.removeConn(conn);
|
self.removeConn(conn);
|
||||||
log.err(.http, "get private info", .{ .err = err, .source = "abort" });
|
log.err(.http, "get private info", .{ .err = err, .source = "abort" });
|
||||||
@@ -223,7 +223,7 @@ fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32) void {
|
|||||||
var n = q.first;
|
var n = q.first;
|
||||||
while (n) |node| {
|
while (n) |node| {
|
||||||
n = node.next;
|
n = node.next;
|
||||||
const transfer: *Transfer = @fieldParentPtr("_node", node);
|
const transfer: *LiveTransfer = @fieldParentPtr("_node", node);
|
||||||
if (comptime abort_all) {
|
if (comptime abort_all) {
|
||||||
transfer.kill();
|
transfer.kill();
|
||||||
} else if (transfer.req.frame_id == frame_id) {
|
} else if (transfer.req.frame_id == frame_id) {
|
||||||
@@ -253,7 +253,7 @@ pub fn tick(self: *Client, timeout_ms: u32) !PerformStatus {
|
|||||||
self.queue.prepend(queue_node);
|
self.queue.prepend(queue_node);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
const transfer: *Transfer = @fieldParentPtr("_node", queue_node);
|
const transfer: *LiveTransfer = @fieldParentPtr("_node", queue_node);
|
||||||
try self.makeRequest(conn, transfer);
|
try self.makeRequest(conn, transfer);
|
||||||
}
|
}
|
||||||
return self.perform(@intCast(timeout_ms));
|
return self.perform(@intCast(timeout_ms));
|
||||||
@@ -376,7 +376,7 @@ fn fetchRobotsThenProcessRequest(self: *Client, robots_url: [:0]const u8, req: R
|
|||||||
try entry.value_ptr.append(self.allocator, req);
|
try entry.value_ptr.append(self.allocator, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn robotsHeaderCallback(transfer: *Transfer) !bool {
|
fn robotsHeaderCallback(transfer: *LiveTransfer) !bool {
|
||||||
const ctx: *RobotsRequestContext = @ptrCast(@alignCast(transfer.ctx));
|
const ctx: *RobotsRequestContext = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
if (transfer.response_header) |hdr| {
|
if (transfer.response_header) |hdr| {
|
||||||
@@ -391,7 +391,7 @@ fn robotsHeaderCallback(transfer: *Transfer) !bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn robotsDataCallback(transfer: *Transfer, data: []const u8) !void {
|
fn robotsDataCallback(transfer: *LiveTransfer, data: []const u8) !void {
|
||||||
const ctx: *RobotsRequestContext = @ptrCast(@alignCast(transfer.ctx));
|
const ctx: *RobotsRequestContext = @ptrCast(@alignCast(transfer.ctx));
|
||||||
try ctx.buffer.appendSlice(ctx.client.allocator, data);
|
try ctx.buffer.appendSlice(ctx.client.allocator, data);
|
||||||
}
|
}
|
||||||
@@ -488,7 +488,7 @@ fn robotsShutdownCallback(ctx_ptr: *anyopaque) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn waitForInterceptedResponse(self: *Client, transfer: *Transfer) !bool {
|
fn waitForInterceptedResponse(self: *Client, transfer: *LiveTransfer) !bool {
|
||||||
// The request was intercepted and is blocking. This is messy, but our
|
// The request was intercepted and is blocking. This is messy, but our
|
||||||
// callers, the ScriptManager -> Page, don't have a great way to stop the
|
// callers, the ScriptManager -> Page, don't have a great way to stop the
|
||||||
// parser and return control to the CDP server to wait for the interception
|
// parser and return control to the CDP server to wait for the interception
|
||||||
@@ -533,7 +533,7 @@ fn waitForInterceptedResponse(self: *Client, transfer: *Transfer) !bool {
|
|||||||
// Above, request will not process if there's an interception request. In such
|
// Above, request will not process if there's an interception request. In such
|
||||||
// cases, the interecptor is expected to call resume to continue the transfer
|
// cases, the interecptor is expected to call resume to continue the transfer
|
||||||
// or transfer.abort() to abort it.
|
// or transfer.abort() to abort it.
|
||||||
fn process(self: *Client, transfer: *Transfer) !void {
|
fn process(self: *Client, transfer: *LiveTransfer) !void {
|
||||||
// libcurl doesn't allow recursive calls, if we're in a `perform()` operation
|
// libcurl doesn't allow recursive calls, if we're in a `perform()` operation
|
||||||
// then we _have_ to queue this.
|
// then we _have_ to queue this.
|
||||||
if (self.performing == false) {
|
if (self.performing == false) {
|
||||||
@@ -546,7 +546,7 @@ fn process(self: *Client, transfer: *Transfer) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For an intercepted request
|
// For an intercepted request
|
||||||
pub fn continueTransfer(self: *Client, transfer: *Transfer) !void {
|
pub fn continueTransfer(self: *Client, transfer: *LiveTransfer) !void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
||||||
log.debug(.http, "continue transfer", .{ .intercepted = self.intercepted });
|
log.debug(.http, "continue transfer", .{ .intercepted = self.intercepted });
|
||||||
@@ -560,7 +560,7 @@ pub fn continueTransfer(self: *Client, transfer: *Transfer) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For an intercepted request
|
// For an intercepted request
|
||||||
pub fn abortTransfer(self: *Client, transfer: *Transfer) void {
|
pub fn abortTransfer(self: *Client, transfer: *LiveTransfer) void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
||||||
log.debug(.http, "abort transfer", .{ .intercepted = self.intercepted });
|
log.debug(.http, "abort transfer", .{ .intercepted = self.intercepted });
|
||||||
@@ -574,7 +574,7 @@ pub fn abortTransfer(self: *Client, transfer: *Transfer) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For an intercepted request
|
// For an intercepted request
|
||||||
pub fn fulfillTransfer(self: *Client, transfer: *Transfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
pub fn fulfillTransfer(self: *Client, transfer: *LiveTransfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
std.debug.assert(transfer._intercept_state != .not_intercepted);
|
||||||
log.debug(.http, "filfull transfer", .{ .intercepted = self.intercepted });
|
log.debug(.http, "filfull transfer", .{ .intercepted = self.intercepted });
|
||||||
@@ -599,7 +599,7 @@ pub fn incrReqId(self: *Client) u32 {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeTransfer(self: *Client, req: Request) !*Transfer {
|
fn makeTransfer(self: *Client, req: Request) !*LiveTransfer {
|
||||||
errdefer req.headers.deinit();
|
errdefer req.headers.deinit();
|
||||||
|
|
||||||
const transfer = try self.transfer_pool.create();
|
const transfer = try self.transfer_pool.create();
|
||||||
@@ -618,7 +618,7 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer {
|
|||||||
return transfer;
|
return transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn requestFailed(transfer: *Transfer, err: anyerror, comptime execute_callback: bool) void {
|
fn requestFailed(transfer: *LiveTransfer, err: anyerror, comptime execute_callback: bool) void {
|
||||||
if (transfer._notified_fail) {
|
if (transfer._notified_fail) {
|
||||||
// we can force a failed request within a callback, which will eventually
|
// we can force a failed request within a callback, which will eventually
|
||||||
// result in this being called again in the more general loop. We do this
|
// result in this being called again in the more general loop. We do this
|
||||||
@@ -677,7 +677,7 @@ pub fn setTlsVerify(self: *Client, verify: bool) !void {
|
|||||||
self.tls_verify = verify;
|
self.tls_verify = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeRequest(self: *Client, conn: *Net.Connection, transfer: *Transfer) anyerror!void {
|
fn makeRequest(self: *Client, conn: *Net.Connection, transfer: *LiveTransfer) anyerror!void {
|
||||||
const req = &transfer.req;
|
const req = &transfer.req;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -689,7 +689,7 @@ fn makeRequest(self: *Client, conn: *Net.Connection, transfer: *Transfer) anyerr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set callbacks and per-client settings on the pooled connection.
|
// Set callbacks and per-client settings on the pooled connection.
|
||||||
try conn.setCallbacks(Transfer.headerCallback, Transfer.dataCallback);
|
try conn.setCallbacks(LiveTransfer.headerCallback, LiveTransfer.dataCallback);
|
||||||
try conn.setProxy(self.http_proxy);
|
try conn.setProxy(self.http_proxy);
|
||||||
try conn.setTlsVerify(self.tls_verify, self.use_proxy);
|
try conn.setTlsVerify(self.tls_verify, self.use_proxy);
|
||||||
|
|
||||||
@@ -804,7 +804,7 @@ fn perform(self: *Client, timeout_ms: c_int) !PerformStatus {
|
|||||||
fn processMessages(self: *Client) !bool {
|
fn processMessages(self: *Client) !bool {
|
||||||
var processed = false;
|
var processed = false;
|
||||||
while (self.handles.readMessage()) |msg| {
|
while (self.handles.readMessage()) |msg| {
|
||||||
const transfer = try Transfer.fromConnection(&msg.conn);
|
const transfer = try LiveTransfer.fromConnection(&msg.conn);
|
||||||
|
|
||||||
// In case of auth challenge
|
// In case of auth challenge
|
||||||
// TODO give a way to configure the number of auth retries.
|
// TODO give a way to configure the number of auth retries.
|
||||||
@@ -891,7 +891,7 @@ fn processMessages(self: *Client) !bool {
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn endTransfer(self: *Client, transfer: *Transfer) void {
|
fn endTransfer(self: *Client, transfer: *LiveTransfer) void {
|
||||||
const conn = transfer._conn.?;
|
const conn = transfer._conn.?;
|
||||||
self.removeConn(conn);
|
self.removeConn(conn);
|
||||||
transfer._conn = null;
|
transfer._conn = null;
|
||||||
@@ -962,9 +962,9 @@ pub const Request = struct {
|
|||||||
// arbitrary data that can be associated with this request
|
// arbitrary data that can be associated with this request
|
||||||
ctx: *anyopaque = undefined,
|
ctx: *anyopaque = undefined,
|
||||||
|
|
||||||
start_callback: ?*const fn (transfer: *Transfer) anyerror!void = null,
|
start_callback: ?*const fn (transfer: *LiveTransfer) anyerror!void = null,
|
||||||
header_callback: *const fn (transfer: *Transfer) anyerror!bool,
|
header_callback: *const fn (transfer: *LiveTransfer) anyerror!bool,
|
||||||
data_callback: *const fn (transfer: *Transfer, data: []const u8) anyerror!void,
|
data_callback: *const fn (transfer: *LiveTransfer, data: []const u8) anyerror!void,
|
||||||
done_callback: *const fn (ctx: *anyopaque) anyerror!void,
|
done_callback: *const fn (ctx: *anyopaque) anyerror!void,
|
||||||
error_callback: *const fn (ctx: *anyopaque, err: anyerror) void,
|
error_callback: *const fn (ctx: *anyopaque, err: anyerror) void,
|
||||||
shutdown_callback: ?*const fn (ctx: *anyopaque) void = null,
|
shutdown_callback: ?*const fn (ctx: *anyopaque) void = null,
|
||||||
@@ -993,11 +993,65 @@ pub const Request = struct {
|
|||||||
const AuthChallenge = Net.AuthChallenge;
|
const AuthChallenge = Net.AuthChallenge;
|
||||||
|
|
||||||
pub const Transfer = struct {
|
pub const Transfer = struct {
|
||||||
|
inner: union(enum) {
|
||||||
|
live: LiveTransfer,
|
||||||
|
},
|
||||||
|
|
||||||
|
pub fn fromLive(transfer: *LiveTransfer) Transfer {
|
||||||
|
return .{ .ctx = transfer.req.ctx, .inner = .{ .live = transfer } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn status(self: Transfer) ?u16 {
|
||||||
|
return switch (self.inner) {
|
||||||
|
.live => |live| if (live.response_header) |rh| rh.status else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contentType(self: Transfer) ?[]const u8 {
|
||||||
|
return switch (self.inner) {
|
||||||
|
.live => |live| if (live.response_header) |*rh| rh.contentType() else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contentLength(self: Transfer) ?u32 {
|
||||||
|
return switch (self.inner) {
|
||||||
|
.live => |live| live.getContentLength(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redirectCount(self: Transfer) ?u32 {
|
||||||
|
return switch (self.inner) {
|
||||||
|
.live => |live| if (live.response_header) |rh| rh.redirect_count else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn url(self: Transfer) [:0]const u8 {
|
||||||
|
return switch (self.inner) {
|
||||||
|
.live => |live| live.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Headers Iterator.
|
||||||
|
|
||||||
|
pub fn abort(self: Transfer, err: anyerror) void {
|
||||||
|
switch (self.inner) {
|
||||||
|
.live => |live| live.abort(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn terminate(self: Transfer) void {
|
||||||
|
switch (self.inner) {
|
||||||
|
.live => |live| live.terminate(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const LiveTransfer = struct {
|
||||||
|
ctx: *anyopaque,
|
||||||
arena: ArenaAllocator,
|
arena: ArenaAllocator,
|
||||||
id: u32 = 0,
|
id: u32 = 0,
|
||||||
req: Request,
|
req: Request,
|
||||||
url: [:0]const u8,
|
url: [:0]const u8,
|
||||||
ctx: *anyopaque, // copied from req.ctx to make it easier for callback handlers
|
|
||||||
client: *Client,
|
client: *Client,
|
||||||
// total bytes received in the response, including the response status line,
|
// total bytes received in the response, including the response status line,
|
||||||
// the headers, and the [encoded] body.
|
// the headers, and the [encoded] body.
|
||||||
@@ -1037,7 +1091,7 @@ pub const Transfer = struct {
|
|||||||
fulfilled,
|
fulfilled,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn reset(self: *Transfer) void {
|
pub fn reset(self: *LiveTransfer) void {
|
||||||
// There's an assertion in ScriptManager that's failing. Seemingly because
|
// There's an assertion in ScriptManager that's failing. Seemingly because
|
||||||
// the headerCallback is being called multiple times. This shouldn't be
|
// the headerCallback is being called multiple times. This shouldn't be
|
||||||
// possible (hence the assertion). Previously, this `reset` would set
|
// possible (hence the assertion). Previously, this `reset` would set
|
||||||
@@ -1057,7 +1111,7 @@ pub const Transfer = struct {
|
|||||||
self._tries += 1;
|
self._tries += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Transfer) void {
|
fn deinit(self: *LiveTransfer) void {
|
||||||
self.req.headers.deinit();
|
self.req.headers.deinit();
|
||||||
if (self._conn) |conn| {
|
if (self._conn) |conn| {
|
||||||
self.client.removeConn(conn);
|
self.client.removeConn(conn);
|
||||||
@@ -1066,7 +1120,7 @@ pub const Transfer = struct {
|
|||||||
self.client.transfer_pool.destroy(self);
|
self.client.transfer_pool.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buildResponseHeader(self: *Transfer, conn: *const Net.Connection) !void {
|
fn buildResponseHeader(self: *LiveTransfer, conn: *const Net.Connection) !void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(self.response_header == null);
|
std.debug.assert(self.response_header == null);
|
||||||
}
|
}
|
||||||
@@ -1093,12 +1147,12 @@ pub const Transfer = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: *Transfer, writer: *std.Io.Writer) !void {
|
pub fn format(self: *LiveTransfer, writer: *std.Io.Writer) !void {
|
||||||
const req = self.req;
|
const req = self.req;
|
||||||
return writer.print("{s} {s}", .{ @tagName(req.method), req.url });
|
return writer.print("{s} {s}", .{ @tagName(req.method), req.url });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updateURL(self: *Transfer, url: [:0]const u8) !void {
|
pub fn updateURL(self: *LiveTransfer, url: [:0]const u8) !void {
|
||||||
// for cookies
|
// for cookies
|
||||||
self.url = url;
|
self.url = url;
|
||||||
|
|
||||||
@@ -1106,11 +1160,11 @@ pub const Transfer = struct {
|
|||||||
self.req.url = url;
|
self.req.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updateCredentials(self: *Transfer, userpwd: [:0]const u8) void {
|
pub fn updateCredentials(self: *LiveTransfer, userpwd: [:0]const u8) void {
|
||||||
self.req.credentials = userpwd;
|
self.req.credentials = userpwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replaceRequestHeaders(self: *Transfer, allocator: Allocator, headers: []const Net.Header) !void {
|
pub fn replaceRequestHeaders(self: *LiveTransfer, allocator: Allocator, headers: []const Net.Header) !void {
|
||||||
self.req.headers.deinit();
|
self.req.headers.deinit();
|
||||||
|
|
||||||
var buf: std.ArrayList(u8) = .empty;
|
var buf: std.ArrayList(u8) = .empty;
|
||||||
@@ -1126,7 +1180,7 @@ pub const Transfer = struct {
|
|||||||
self.req.headers = new_headers;
|
self.req.headers = new_headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn abort(self: *Transfer, err: anyerror) void {
|
pub fn abort(self: *LiveTransfer, err: anyerror) void {
|
||||||
requestFailed(self, err, true);
|
requestFailed(self, err, true);
|
||||||
|
|
||||||
const client = self.client;
|
const client = self.client;
|
||||||
@@ -1146,7 +1200,7 @@ pub const Transfer = struct {
|
|||||||
self.deinit();
|
self.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn terminate(self: *Transfer) void {
|
pub fn terminate(self: *LiveTransfer) void {
|
||||||
requestFailed(self, error.Shutdown, false);
|
requestFailed(self, error.Shutdown, false);
|
||||||
if (self._conn != null) {
|
if (self._conn != null) {
|
||||||
self.client.endTransfer(self);
|
self.client.endTransfer(self);
|
||||||
@@ -1156,7 +1210,7 @@ pub const Transfer = struct {
|
|||||||
|
|
||||||
// internal, when the page is shutting down. Doesn't have the same ceremony
|
// internal, when the page is shutting down. Doesn't have the same ceremony
|
||||||
// as abort (doesn't send a notification, doesn't invoke an error callback)
|
// as abort (doesn't send a notification, doesn't invoke an error callback)
|
||||||
fn kill(self: *Transfer) void {
|
fn kill(self: *LiveTransfer) void {
|
||||||
if (self._conn != null) {
|
if (self._conn != null) {
|
||||||
self.client.endTransfer(self);
|
self.client.endTransfer(self);
|
||||||
}
|
}
|
||||||
@@ -1169,7 +1223,7 @@ pub const Transfer = struct {
|
|||||||
// abortAuthChallenge is called when an auth challenge interception is
|
// abortAuthChallenge is called when an auth challenge interception is
|
||||||
// abort. We don't call self.client.endTransfer here b/c it has been done
|
// abort. We don't call self.client.endTransfer here b/c it has been done
|
||||||
// before interception process.
|
// before interception process.
|
||||||
pub fn abortAuthChallenge(self: *Transfer) void {
|
pub fn abortAuthChallenge(self: *LiveTransfer) void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(self._intercept_state != .not_intercepted);
|
std.debug.assert(self._intercept_state != .not_intercepted);
|
||||||
log.debug(.http, "abort auth transfer", .{ .intercepted = self.client.intercepted });
|
log.debug(.http, "abort auth transfer", .{ .intercepted = self.client.intercepted });
|
||||||
@@ -1185,7 +1239,7 @@ pub const Transfer = struct {
|
|||||||
// redirectionCookies manages cookies during redirections handled by Curl.
|
// redirectionCookies manages cookies during redirections handled by Curl.
|
||||||
// It sets the cookies from the current response to the cookie jar.
|
// It sets the cookies from the current response to the cookie jar.
|
||||||
// It also immediately sets cookies for the following request.
|
// It also immediately sets cookies for the following request.
|
||||||
fn redirectionCookies(transfer: *Transfer, conn: *const Net.Connection) !void {
|
fn redirectionCookies(transfer: *LiveTransfer, conn: *const Net.Connection) !void {
|
||||||
const req = &transfer.req;
|
const req = &transfer.req;
|
||||||
const arena = transfer.arena.allocator();
|
const arena = transfer.arena.allocator();
|
||||||
|
|
||||||
@@ -1227,7 +1281,7 @@ pub const Transfer = struct {
|
|||||||
// headerDoneCallback is called once the headers have been read.
|
// headerDoneCallback is called once the headers have been read.
|
||||||
// It can be called either on dataCallback or once the request for those
|
// It can be called either on dataCallback or once the request for those
|
||||||
// w/o body.
|
// w/o body.
|
||||||
fn headerDoneCallback(transfer: *Transfer, conn: *const Net.Connection) !bool {
|
fn headerDoneCallback(transfer: *LiveTransfer, conn: *const Net.Connection) !bool {
|
||||||
lp.assert(transfer._header_done_called == false, "Transfer.headerDoneCallback", .{});
|
lp.assert(transfer._header_done_called == false, "Transfer.headerDoneCallback", .{});
|
||||||
defer transfer._header_done_called = true;
|
defer transfer._header_done_called = true;
|
||||||
|
|
||||||
@@ -1445,7 +1499,7 @@ pub const Transfer = struct {
|
|||||||
return @intCast(chunk_len);
|
return @intCast(chunk_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn responseHeaderIterator(self: *Transfer) HeaderIterator {
|
pub fn responseHeaderIterator(self: *LiveTransfer) HeaderIterator {
|
||||||
if (self._conn) |conn| {
|
if (self._conn) |conn| {
|
||||||
// If we have a connection, than this is a real curl request and we
|
// If we have a connection, than this is a real curl request and we
|
||||||
// iterate through the header that curl maintains.
|
// iterate through the header that curl maintains.
|
||||||
@@ -1458,12 +1512,12 @@ pub const Transfer = struct {
|
|||||||
return .{ .list = .{ .list = self.response_header.?._injected_headers } };
|
return .{ .list = .{ .list = self.response_header.?._injected_headers } };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromConnection(conn: *const Net.Connection) !*Transfer {
|
pub fn fromConnection(conn: *const Net.Connection) !*LiveTransfer {
|
||||||
const private = try conn.getPrivate();
|
const private = try conn.getPrivate();
|
||||||
return @ptrCast(@alignCast(private));
|
return @ptrCast(@alignCast(private));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fulfill(transfer: *Transfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
pub fn fulfill(transfer: *LiveTransfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
||||||
if (transfer._conn != null) {
|
if (transfer._conn != null) {
|
||||||
// should never happen, should have been intercepted/paused, and then
|
// should never happen, should have been intercepted/paused, and then
|
||||||
// either continued, aborted or fulfilled once.
|
// either continued, aborted or fulfilled once.
|
||||||
@@ -1477,7 +1531,7 @@ pub const Transfer = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _fulfill(transfer: *Transfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
fn _fulfill(transfer: *LiveTransfer, status: u16, headers: []const Net.Header, body: ?[]const u8) !void {
|
||||||
const req = &transfer.req;
|
const req = &transfer.req;
|
||||||
if (req.start_callback) |cb| {
|
if (req.start_callback) |cb| {
|
||||||
try cb(transfer);
|
try cb(transfer);
|
||||||
@@ -1513,12 +1567,12 @@ pub const Transfer = struct {
|
|||||||
|
|
||||||
// This function should be called during the dataCallback. Calling it after
|
// This function should be called during the dataCallback. Calling it after
|
||||||
// such as in the doneCallback is guaranteed to return null.
|
// such as in the doneCallback is guaranteed to return null.
|
||||||
pub fn getContentLength(self: *const Transfer) ?u32 {
|
pub fn getContentLength(self: *const LiveTransfer) ?u32 {
|
||||||
const cl = self.getContentLengthRawValue() orelse return null;
|
const cl = self.getContentLengthRawValue() orelse return null;
|
||||||
return std.fmt.parseInt(u32, cl, 10) catch null;
|
return std.fmt.parseInt(u32, cl, 10) catch null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getContentLengthRawValue(self: *const Transfer) ?[]const u8 {
|
fn getContentLengthRawValue(self: *const LiveTransfer) ?[]const u8 {
|
||||||
if (self._conn) |conn| {
|
if (self._conn) |conn| {
|
||||||
// If we have a connection, than this is a normal request. We can get the
|
// If we have a connection, than this is a normal request. We can get the
|
||||||
// header value from the connection.
|
// header value from the connection.
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ fn notifyParentLoadComplete(self: *Page) void {
|
|||||||
parent.iframeCompletedLoading(self.iframe.?);
|
parent.iframeCompletedLoading(self.iframe.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pageHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
fn pageHeaderDoneCallback(transfer: *HttpClient.LiveTransfer) !bool {
|
||||||
var self: *Page = @ptrCast(@alignCast(transfer.ctx));
|
var self: *Page = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
const header = &transfer.response_header.?;
|
const header = &transfer.response_header.?;
|
||||||
@@ -849,7 +849,7 @@ fn pageHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pageDataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
fn pageDataCallback(transfer: *HttpClient.LiveTransfer, data: []const u8) !void {
|
||||||
var self: *Page = @ptrCast(@alignCast(transfer.ctx));
|
var self: *Page = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
if (self._parse_state == .pre) {
|
if (self._parse_state == .pre) {
|
||||||
|
|||||||
@@ -694,11 +694,11 @@ pub const Script = struct {
|
|||||||
self.manager.page.releaseArena(self.arena);
|
self.manager.page.releaseArena(self.arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn startCallback(transfer: *HttpClient.Transfer) !void {
|
fn startCallback(transfer: *HttpClient.LiveTransfer) !void {
|
||||||
log.debug(.http, "script fetch start", .{ .req = transfer });
|
log.debug(.http, "script fetch start", .{ .req = transfer });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headerCallback(transfer: *HttpClient.Transfer) !bool {
|
fn headerCallback(transfer: *HttpClient.LiveTransfer) !bool {
|
||||||
const self: *Script = @ptrCast(@alignCast(transfer.ctx));
|
const self: *Script = @ptrCast(@alignCast(transfer.ctx));
|
||||||
const header = &transfer.response_header.?;
|
const header = &transfer.response_header.?;
|
||||||
self.status = header.status;
|
self.status = header.status;
|
||||||
@@ -765,14 +765,14 @@ pub const Script = struct {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
fn dataCallback(transfer: *HttpClient.LiveTransfer, data: []const u8) !void {
|
||||||
const self: *Script = @ptrCast(@alignCast(transfer.ctx));
|
const self: *Script = @ptrCast(@alignCast(transfer.ctx));
|
||||||
self._dataCallback(transfer, data) catch |err| {
|
self._dataCallback(transfer, data) catch |err| {
|
||||||
log.err(.http, "SM.dataCallback", .{ .err = err, .transfer = transfer, .len = data.len });
|
log.err(.http, "SM.dataCallback", .{ .err = err, .transfer = transfer, .len = data.len });
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn _dataCallback(self: *Script, _: *HttpClient.Transfer, data: []const u8) !void {
|
fn _dataCallback(self: *Script, _: *HttpClient.LiveTransfer, data: []const u8) !void {
|
||||||
try self.source.remote.appendSlice(self.arena, data);
|
try self.source.remote.appendSlice(self.arena, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ fn handleBlobUrl(url: []const u8, resolver: js.PromiseResolver, page: *Page) !js
|
|||||||
return resolver.promise();
|
return resolver.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpStartCallback(transfer: *HttpClient.Transfer) !void {
|
fn httpStartCallback(transfer: *HttpClient.LiveTransfer) !void {
|
||||||
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
log.debug(.http, "request start", .{ .url = self._url, .source = "fetch" });
|
log.debug(.http, "request start", .{ .url = self._url, .source = "fetch" });
|
||||||
@@ -134,7 +134,7 @@ fn httpStartCallback(transfer: *HttpClient.Transfer) !void {
|
|||||||
self._response._transfer = transfer;
|
self._response._transfer = transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
fn httpHeaderDoneCallback(transfer: *HttpClient.LiveTransfer) !bool {
|
||||||
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
if (self._signal) |signal| {
|
if (self._signal) |signal| {
|
||||||
@@ -190,7 +190,7 @@ fn httpHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpDataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
fn httpDataCallback(transfer: *HttpClient.LiveTransfer, data: []const u8) !void {
|
||||||
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
// Check if aborted
|
// Check if aborted
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ _type: Type,
|
|||||||
_status_text: []const u8,
|
_status_text: []const u8,
|
||||||
_url: [:0]const u8,
|
_url: [:0]const u8,
|
||||||
_is_redirected: bool,
|
_is_redirected: bool,
|
||||||
_transfer: ?*HttpClient.Transfer = null,
|
_transfer: ?*HttpClient.LiveTransfer = null,
|
||||||
|
|
||||||
const InitOpts = struct {
|
const InitOpts = struct {
|
||||||
status: u16 = 200,
|
status: u16 = 200,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const XMLHttpRequest = @This();
|
|||||||
_page: *Page,
|
_page: *Page,
|
||||||
_proto: *XMLHttpRequestEventTarget,
|
_proto: *XMLHttpRequestEventTarget,
|
||||||
_arena: Allocator,
|
_arena: Allocator,
|
||||||
_transfer: ?*HttpClient.Transfer = null,
|
_transfer: ?*HttpClient.LiveTransfer = null,
|
||||||
|
|
||||||
_url: [:0]const u8 = "",
|
_url: [:0]const u8 = "",
|
||||||
_method: net_http.Method = .GET,
|
_method: net_http.Method = .GET,
|
||||||
@@ -382,7 +382,7 @@ pub fn getResponseXML(self: *XMLHttpRequest, page: *Page) !?*Node.Document {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpStartCallback(transfer: *HttpClient.Transfer) !void {
|
fn httpStartCallback(transfer: *HttpClient.LiveTransfer) !void {
|
||||||
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
log.debug(.http, "request start", .{ .method = self._method, .url = self._url, .source = "xhr" });
|
log.debug(.http, "request start", .{ .method = self._method, .url = self._url, .source = "xhr" });
|
||||||
@@ -390,13 +390,13 @@ fn httpStartCallback(transfer: *HttpClient.Transfer) !void {
|
|||||||
self._transfer = transfer;
|
self._transfer = transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpHeaderCallback(transfer: *HttpClient.Transfer, header: net_http.Header) !void {
|
fn httpHeaderCallback(transfer: *HttpClient.LiveTransfer, header: net_http.Header) !void {
|
||||||
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
||||||
const joined = try std.fmt.allocPrint(self._arena, "{s}: {s}", .{ header.name, header.value });
|
const joined = try std.fmt.allocPrint(self._arena, "{s}: {s}", .{ header.name, header.value });
|
||||||
try self._response_headers.append(self._arena, joined);
|
try self._response_headers.append(self._arena, joined);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
fn httpHeaderDoneCallback(transfer: *HttpClient.LiveTransfer) !bool {
|
||||||
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
||||||
|
|
||||||
const header = &transfer.response_header.?;
|
const header = &transfer.response_header.?;
|
||||||
@@ -446,7 +446,7 @@ fn httpHeaderDoneCallback(transfer: *HttpClient.Transfer) !bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn httpDataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
fn httpDataCallback(transfer: *HttpClient.LiveTransfer, data: []const u8) !void {
|
||||||
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
const self: *XMLHttpRequest = @ptrCast(@alignCast(transfer.ctx));
|
||||||
try self._response_data.appendSlice(self._arena, data);
|
try self._response_data.appendSlice(self._arena, data);
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
// Stored in CDP
|
// Stored in CDP
|
||||||
pub const InterceptState = struct {
|
pub const InterceptState = struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
waiting: std.AutoArrayHashMapUnmanaged(u32, *HttpClient.Transfer),
|
waiting: std.AutoArrayHashMapUnmanaged(u32, *HttpClient.LiveTransfer),
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) !InterceptState {
|
pub fn init(allocator: Allocator) !InterceptState {
|
||||||
return .{
|
return .{
|
||||||
@@ -63,11 +63,11 @@ pub const InterceptState = struct {
|
|||||||
return self.waiting.count() == 0;
|
return self.waiting.count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put(self: *InterceptState, transfer: *HttpClient.Transfer) !void {
|
pub fn put(self: *InterceptState, transfer: *HttpClient.LiveTransfer) !void {
|
||||||
return self.waiting.put(self.allocator, transfer.id, transfer);
|
return self.waiting.put(self.allocator, transfer.id, transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(self: *InterceptState, request_id: u32) ?*HttpClient.Transfer {
|
pub fn remove(self: *InterceptState, request_id: u32) ?*HttpClient.LiveTransfer {
|
||||||
const entry = self.waiting.fetchSwapRemove(request_id) orelse return null;
|
const entry = self.waiting.fetchSwapRemove(request_id) orelse return null;
|
||||||
return entry.value;
|
return entry.value;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ pub const InterceptState = struct {
|
|||||||
self.waiting.deinit(self.allocator);
|
self.waiting.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pendingTransfers(self: *const InterceptState) []*HttpClient.Transfer {
|
pub fn pendingTransfers(self: *const InterceptState) []*HttpClient.LiveTransfer {
|
||||||
return self.waiting.values();
|
return self.waiting.values();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const CdpStorage = @import("storage.zig");
|
|||||||
|
|
||||||
const id = @import("../id.zig");
|
const id = @import("../id.zig");
|
||||||
const URL = @import("../../browser/URL.zig");
|
const URL = @import("../../browser/URL.zig");
|
||||||
const Transfer = @import("../../browser/HttpClient.zig").Transfer;
|
const LiveTransfer = @import("../../browser/HttpClient.zig").LiveTransfer;
|
||||||
const Notification = @import("../../Notification.zig");
|
const Notification = @import("../../Notification.zig");
|
||||||
const Mime = @import("../../browser/Mime.zig");
|
const Mime = @import("../../browser/Mime.zig");
|
||||||
|
|
||||||
@@ -294,9 +294,9 @@ pub fn httpRequestDone(bc: anytype, msg: *const Notification.RequestDone) !void
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const TransferAsRequestWriter = struct {
|
pub const TransferAsRequestWriter = struct {
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
|
|
||||||
pub fn init(transfer: *Transfer) TransferAsRequestWriter {
|
pub fn init(transfer: *LiveTransfer) TransferAsRequestWriter {
|
||||||
return .{
|
return .{
|
||||||
.transfer = transfer,
|
.transfer = transfer,
|
||||||
};
|
};
|
||||||
@@ -348,9 +348,9 @@ pub const TransferAsRequestWriter = struct {
|
|||||||
|
|
||||||
const TransferAsResponseWriter = struct {
|
const TransferAsResponseWriter = struct {
|
||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
transfer: *Transfer,
|
transfer: *LiveTransfer,
|
||||||
|
|
||||||
fn init(arena: Allocator, transfer: *Transfer) TransferAsResponseWriter {
|
fn init(arena: Allocator, transfer: *LiveTransfer) TransferAsResponseWriter {
|
||||||
return .{
|
return .{
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
.transfer = transfer,
|
.transfer = transfer,
|
||||||
|
|||||||
Reference in New Issue
Block a user