mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +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);
|
||||
}
|
||||
|
||||
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 {
|
||||
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);
|
||||
|
||||
transfer.req.notification.dispatch(.http_request_start, &.{ .transfer = transfer });
|
||||
@@ -886,6 +941,32 @@ fn processMessages(self: *Client) !bool {
|
||||
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 = transfer,
|
||||
});
|
||||
@@ -1081,6 +1162,7 @@ pub const LiveTransfer = struct {
|
||||
// total bytes received in the response, including the response status line,
|
||||
// the headers, and the [encoded] body.
|
||||
bytes_received: usize = 0,
|
||||
body: std.ArrayListUnmanaged(u8) = .empty,
|
||||
|
||||
aborted: bool = false,
|
||||
|
||||
@@ -1507,6 +1589,11 @@ pub const LiveTransfer = struct {
|
||||
}
|
||||
|
||||
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| {
|
||||
log.err(.http, "data_callback", .{ .err = err, .req = transfer });
|
||||
return Net.writefunc_error;
|
||||
|
||||
Reference in New Issue
Block a user