mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Protect against transfer.abort() being called during callback
This was already handled in most cases, but not for a body-less response. It's safe to call transfer.abort() during a callback, so long as the performing flag is set to true. This was set during the normal libcurl callbacks, but for a body-less response, we manually invoke the header_done_callback and were not setting the performing flag.
This commit is contained in:
@@ -789,25 +789,30 @@ fn processMessages(self: *Client) !bool {
|
||||
if (msg.err) |err| {
|
||||
requestFailed(transfer, err, true);
|
||||
} else blk: {
|
||||
// In case of request w/o data, we need to call the header done
|
||||
// callback now.
|
||||
if (!transfer._header_done_called) {
|
||||
const proceed = transfer.headerDoneCallback(&msg.conn) catch |err| {
|
||||
log.err(.http, "header_done_callback", .{ .err = err });
|
||||
{
|
||||
self.handles.performing = true;
|
||||
defer self.handles.performing = false;
|
||||
|
||||
// In case of request w/o data, we need to call the header done
|
||||
// callback now.
|
||||
if (!transfer._header_done_called) {
|
||||
const proceed = transfer.headerDoneCallback(&msg.conn) catch |err| {
|
||||
log.err(.http, "header_done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
if (!proceed) {
|
||||
requestFailed(transfer, error.Abort, true);
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
transfer.req.done_callback(transfer.ctx) catch |err| {
|
||||
// transfer isn't valid at this point, don't use it.
|
||||
log.err(.http, "done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
if (!proceed) {
|
||||
requestFailed(transfer, error.Abort, true);
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
transfer.req.done_callback(transfer.ctx) catch |err| {
|
||||
// transfer isn't valid at this point, don't use it.
|
||||
log.err(.http, "done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
|
||||
transfer.req.notification.dispatch(.http_request_done, &.{
|
||||
.transfer = transfer,
|
||||
@@ -1041,10 +1046,6 @@ pub const Transfer = struct {
|
||||
|
||||
pub fn abort(self: *Transfer, err: anyerror) void {
|
||||
requestFailed(self, err, true);
|
||||
if (self._conn == null) {
|
||||
self.deinit();
|
||||
return;
|
||||
}
|
||||
|
||||
const client = self.client;
|
||||
if (client.handles.performing) {
|
||||
|
||||
Reference in New Issue
Block a user