mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
add basic caching support
This commit is contained in:
@@ -292,7 +292,62 @@ pub fn request(self: *Client, req: Request) !void {
|
|||||||
return self.fetchRobotsThenProcessRequest(robots_url, req);
|
return self.fetchRobotsThenProcessRequest(robots_url, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serveFromCache(allocator: std.mem.Allocator, req: Request, cached: *const CachedResponse) !void {
|
||||||
|
const response = Response.fromCached(req.ctx, cached);
|
||||||
|
defer cached.metadata.deinit(allocator);
|
||||||
|
|
||||||
|
if (req.start_callback) |cb| {
|
||||||
|
try cb(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
const proceed = try req.header_callback(response);
|
||||||
|
if (!proceed) {
|
||||||
|
req.error_callback(req.ctx, error.Abort);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cached.data) {
|
||||||
|
.buffer => |data| {
|
||||||
|
if (data.len > 0) {
|
||||||
|
try req.data_callback(response, data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.file => |file| {
|
||||||
|
var buf: [1024]u8 = undefined;
|
||||||
|
var file_reader = file.reader(&buf);
|
||||||
|
|
||||||
|
const reader = &file_reader.interface;
|
||||||
|
var read_buf: [1024]u8 = undefined;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const curr = try reader.readSliceShort(&read_buf);
|
||||||
|
if (curr == 0) break;
|
||||||
|
try req.data_callback(response, read_buf[0..curr]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
try req.done_callback(req.ctx);
|
||||||
|
}
|
||||||
|
|
||||||
fn processRequest(self: *Client, req: Request) !void {
|
fn processRequest(self: *Client, req: Request) !void {
|
||||||
|
if (self.network.cache) |*cache| {
|
||||||
|
if (req.method == .GET) {
|
||||||
|
if (cache.get(self.allocator, req.url)) |cached| {
|
||||||
|
log.debug(.browser, "http.cache.get", .{
|
||||||
|
.url = req.url,
|
||||||
|
.found = true,
|
||||||
|
.metadata = cached.metadata,
|
||||||
|
});
|
||||||
|
|
||||||
|
defer req.headers.deinit();
|
||||||
|
return serveFromCache(self.allocator, req, &cached);
|
||||||
|
} else {
|
||||||
|
log.debug(.browser, "http.cache.get", .{ .url = req.url, .found = false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const transfer = try self.makeTransfer(req);
|
const transfer = try self.makeTransfer(req);
|
||||||
|
|
||||||
transfer.req.notification.dispatch(.http_request_start, &.{ .transfer = transfer });
|
transfer.req.notification.dispatch(.http_request_start, &.{ .transfer = transfer });
|
||||||
@@ -886,6 +941,32 @@ fn processMessages(self: *Client) !bool {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (self.network.cache) |*cache| {
|
||||||
|
var headers = &transfer.response_header.?;
|
||||||
|
|
||||||
|
if (transfer.req.method == .GET and headers.status == 200) {
|
||||||
|
cache.put(
|
||||||
|
transfer.req.url,
|
||||||
|
.{
|
||||||
|
.url = transfer.req.url,
|
||||||
|
.content_type = headers.contentType() orelse "application/octet-stream",
|
||||||
|
.status = headers.status,
|
||||||
|
.stored_at = std.time.timestamp(),
|
||||||
|
.age_at_store = 0,
|
||||||
|
.max_age = 3600,
|
||||||
|
.etag = null,
|
||||||
|
.last_modified = null,
|
||||||
|
.must_revalidate = false,
|
||||||
|
.no_cache = false,
|
||||||
|
.immutable = false,
|
||||||
|
.vary = null,
|
||||||
|
},
|
||||||
|
transfer.body.items,
|
||||||
|
) catch |err| log.warn(.http, "cache put failed", .{ .err = err });
|
||||||
|
log.debug(.browser, "http.cache.put", .{ .url = transfer.req.url });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transfer.req.notification.dispatch(.http_request_done, &.{
|
transfer.req.notification.dispatch(.http_request_done, &.{
|
||||||
.transfer = transfer,
|
.transfer = transfer,
|
||||||
});
|
});
|
||||||
@@ -1081,6 +1162,7 @@ pub const LiveTransfer = struct {
|
|||||||
// 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.
|
||||||
bytes_received: usize = 0,
|
bytes_received: usize = 0,
|
||||||
|
body: std.ArrayListUnmanaged(u8) = .empty,
|
||||||
|
|
||||||
aborted: bool = false,
|
aborted: bool = false,
|
||||||
|
|
||||||
@@ -1507,6 +1589,11 @@ pub const LiveTransfer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const chunk = buffer[0..chunk_len];
|
const chunk = buffer[0..chunk_len];
|
||||||
|
transfer.body.appendSlice(transfer.arena.allocator(), chunk) catch |err| {
|
||||||
|
log.err(.http, "cache body append", .{ .err = err, .req = transfer });
|
||||||
|
return Net.writefunc_error;
|
||||||
|
};
|
||||||
|
|
||||||
transfer.req.data_callback(Response.fromLive(transfer), chunk) catch |err| {
|
transfer.req.data_callback(Response.fromLive(transfer), chunk) catch |err| {
|
||||||
log.err(.http, "data_callback", .{ .err = err, .req = transfer });
|
log.err(.http, "data_callback", .{ .err = err, .req = transfer });
|
||||||
return Net.writefunc_error;
|
return Net.writefunc_error;
|
||||||
|
|||||||
Reference in New Issue
Block a user