mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
xhr: yield each fetch steps
This commit is contained in:
@@ -97,11 +97,16 @@ pub const XMLHttpRequest = struct {
|
||||
JSON,
|
||||
};
|
||||
|
||||
const PrivState = enum { new, open, send, finish, wait, done };
|
||||
|
||||
proto: XMLHttpRequestEventTarget,
|
||||
alloc: std.mem.Allocator,
|
||||
cli: Client,
|
||||
impl: YieldImpl,
|
||||
|
||||
priv_state: PrivState = .new,
|
||||
req: ?Client.Request = null,
|
||||
|
||||
method: std.http.Method,
|
||||
state: u16,
|
||||
url: ?[]const u8,
|
||||
@@ -143,6 +148,8 @@ pub const XMLHttpRequest = struct {
|
||||
if (self.url) |v| alloc.free(v);
|
||||
if (self.response_bytes) |v| alloc.free(v);
|
||||
if (self.response_headers) |v| alloc.free(v);
|
||||
|
||||
if (self.req) |*r| r.deinit();
|
||||
// TODO the client must be shared between requests.
|
||||
self.cli.deinit();
|
||||
}
|
||||
@@ -206,6 +213,11 @@ pub const XMLHttpRequest = struct {
|
||||
if (self.response_bytes) |v| alloc.free(v);
|
||||
|
||||
self.state = OPENED;
|
||||
self.priv_state = .new;
|
||||
if (self.req) |*r| {
|
||||
r.deinit();
|
||||
self.req = null;
|
||||
}
|
||||
}
|
||||
|
||||
const methods = [_]struct {
|
||||
@@ -259,26 +271,43 @@ pub const XMLHttpRequest = struct {
|
||||
self.impl.yield(self);
|
||||
}
|
||||
|
||||
// onYield is a callback called between each request's steps.
|
||||
// Between each step, the code is blocking.
|
||||
// Yielding allows pseudo-async and gives a chance to other async process
|
||||
// to be called.
|
||||
pub fn onYield(self: *XMLHttpRequest, err: ?anyerror) void {
|
||||
if (err) |e| return self.onerr(e);
|
||||
var req = self.cli.open(self.method, self.uri, self.headers, .{}) catch |e| return self.onerr(e);
|
||||
defer req.deinit();
|
||||
|
||||
req.send(.{}) catch |e| return self.onerr(e);
|
||||
req.finish() catch |e| return self.onerr(e);
|
||||
req.wait() catch |e| return self.onerr(e);
|
||||
|
||||
self.response_headers = req.response.headers.clone(self.response_headers.allocator) catch |e| return self.onerr(e);
|
||||
switch (self.priv_state) {
|
||||
.new => {
|
||||
self.priv_state = .open;
|
||||
self.req = self.cli.open(self.method, self.uri, self.headers, .{}) catch |e| return self.onerr(e);
|
||||
},
|
||||
.open => {
|
||||
self.priv_state = .send;
|
||||
self.req.?.send(.{}) catch |e| return self.onerr(e);
|
||||
},
|
||||
.send => {
|
||||
self.priv_state = .finish;
|
||||
self.req.?.finish() catch |e| return self.onerr(e);
|
||||
},
|
||||
.finish => {
|
||||
self.priv_state = .wait;
|
||||
self.req.?.wait() catch |e| return self.onerr(e);
|
||||
},
|
||||
.wait => {
|
||||
self.priv_state = .done;
|
||||
self.response_headers = self.req.?.response.headers.clone(self.response_headers.allocator) catch |e| return self.onerr(e);
|
||||
|
||||
self.state = HEADERS_RECEIVED;
|
||||
|
||||
self.response_status = @intFromEnum(req.response.status);
|
||||
self.response_status = @intFromEnum(self.req.?.response.status);
|
||||
|
||||
self.state = LOADING;
|
||||
|
||||
var buf: std.ArrayListUnmanaged(u8) = .{};
|
||||
|
||||
const reader = req.reader();
|
||||
const reader = self.req.?.reader();
|
||||
var buffer: [1024]u8 = undefined;
|
||||
var ln = buffer.len;
|
||||
while (ln > 0) {
|
||||
@@ -294,6 +323,12 @@ pub const XMLHttpRequest = struct {
|
||||
self.response_bytes = buf.items;
|
||||
|
||||
self.state = DONE;
|
||||
},
|
||||
.done => {
|
||||
if (self.req) |*r| {
|
||||
r.deinit();
|
||||
self.req = null;
|
||||
}
|
||||
|
||||
// TODO use events instead
|
||||
if (self.proto.onload_cbk) |cbk| {
|
||||
@@ -302,11 +337,23 @@ pub const XMLHttpRequest = struct {
|
||||
std.debug.print("--- CALLBACK ERROR: {any}\n", .{e});
|
||||
}; // TODO handle error
|
||||
}
|
||||
|
||||
// finalize fetch process.
|
||||
return;
|
||||
},
|
||||
}
|
||||
|
||||
self.impl.yield(self);
|
||||
}
|
||||
|
||||
fn onerr(self: *XMLHttpRequest, err: anyerror) void {
|
||||
self.err = err;
|
||||
self.state = DONE;
|
||||
self.priv_state = .done;
|
||||
if (self.req) |*r| {
|
||||
r.deinit();
|
||||
self.req = null;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_responseText(self: *XMLHttpRequest) ![]const u8 {
|
||||
|
||||
Reference in New Issue
Block a user