chore: release SVR.JS Cache mod 1.1.0

This commit is contained in:
Dorian Niemiec 2024-12-24 12:50:51 +01:00
parent 6e7071ed1c
commit 8cd192a8e6
3 changed files with 79 additions and 1 deletions

View file

@ -1,4 +1,4 @@
{ {
"name": "SVR.JS Cache mod", "name": "SVR.JS Cache mod",
"version": "1.0.3" "version": "1.1.0"
} }

View file

@ -15,6 +15,9 @@ module.exports = function (req, res, logFacilities, config, next) {
const cacheVaryHeadersConfigured = config.cacheVaryHeaders const cacheVaryHeadersConfigured = config.cacheVaryHeaders
? config.cacheVaryHeaders ? config.cacheVaryHeaders
: []; : [];
const cacheIgnoreHeadersConfigured = config.cacheIgnoreHeaders
? config.cacheIgnoreHeaders
: [];
const maximumCachedResponseSize = config.maximumCachedResponseSize const maximumCachedResponseSize = config.maximumCachedResponseSize
? config.maximumCachedResponseSize ? config.maximumCachedResponseSize
: null; : null;
@ -174,6 +177,12 @@ module.exports = function (req, res, logFacilities, config, next) {
.join("\n"); .join("\n");
varyCache.set(cacheKey, processedVary); varyCache.set(cacheKey, processedVary);
// Ignore headers
cacheIgnoreHeadersConfigured.forEach((header) => {
delete writtenHeaders[header.toLowerCase()];
});
cache.set(cacheKeyWithVary, { cache.set(cacheKeyWithVary, {
body: responseBody, body: responseBody,
headers: writtenHeaders, headers: writtenHeaders,
@ -259,6 +268,9 @@ module.exports.configValidators = {
cacheVaryHeaders: (value) => cacheVaryHeaders: (value) =>
Array.isArray(value) && Array.isArray(value) &&
value.every((element) => typeof element === "string"), value.every((element) => typeof element === "string"),
cacheIgnoreHeaders: (value) =>
Array.isArray(value) &&
value.every((element) => typeof element === "string"),
maximumCachedResponseSize: (value) => maximumCachedResponseSize: (value) =>
typeof value === "number" || value === null typeof value === "number" || value === null
}; };

View file

@ -40,6 +40,7 @@ describe("SVR.JS Cache mod", () => {
config = { config = {
cacheVaryHeaders: ["accept"], cacheVaryHeaders: ["accept"],
cacheIgnoreHeaders: [],
maximumCachedResponseSize: 1024 maximumCachedResponseSize: 1024
}; };
@ -120,15 +121,76 @@ describe("SVR.JS Cache mod", () => {
expect(next).not.toHaveBeenCalled(); // No middleware should be called expect(next).not.toHaveBeenCalled(); // No middleware should be called
}); });
test("should cache the response and serve it on subsequent requests, while ignoring some headers", () => {
req.headers.host = "ignore.test.com";
req.headers.accept = "application/json";
// Headers to ignore
config.cacheIgnoreHeaders = ["x-header-ignored"];
parseCacheControl.mockReturnValue({});
parseVary.mockReturnValue(["accept"]);
shouldCacheResponse.mockReturnValue(true);
// Mock cache-control headers
res.getHeaders.mockReturnValue({ "cache-control": "max-age=300" });
// First request: cache the response
mod(req, res, logFacilities, config, next);
// Simulate the first response
res.writeHead(200, {
"content-type": "application/json",
"x-header-ignored": "no"
});
res.end("cached response body");
// Assertions for the first request
expect(next).toHaveBeenCalled(); // Proceed to next middleware during first request
// Reset mocks for the second invocation
jest.clearAllMocks();
next.mockReset();
res.setHeader = jest.fn();
res.removeHeader = jest.fn();
res.writeHead = jest.fn();
res.write = jest.fn();
res.end = jest.fn();
// Second request: retrieve from cache
parseCacheControl.mockReturnValue({});
isCacheValid.mockReturnValue(true); // Simulate a valid cache entry
mod(req, res, logFacilities, config, next);
// Assertions for the second request
expect(logFacilities.resmessage).toHaveBeenCalledWith(
"The response is cached."
);
expect(res.setHeader).toHaveBeenCalledWith("X-SVRJS-Cache", "HIT");
expect(res.writeHead).toHaveBeenCalledWith(200, {
"cache-control": "max-age=300",
"content-type": "application/json"
});
expect(res.end).toHaveBeenCalledWith(
Buffer.from("cached response body", "latin1")
);
expect(next).not.toHaveBeenCalled(); // No middleware should be called
});
test("should validate config values correctly", () => { test("should validate config values correctly", () => {
const validConfig = { const validConfig = {
cacheVaryHeaders: ["accept", "user-agent"], cacheVaryHeaders: ["accept", "user-agent"],
cacheIgnoreHeaders: ["set-cookie"],
maximumCachedResponseSize: 2048 maximumCachedResponseSize: 2048
}; };
expect( expect(
mod.configValidators.cacheVaryHeaders(validConfig.cacheVaryHeaders) mod.configValidators.cacheVaryHeaders(validConfig.cacheVaryHeaders)
).toBe(true); ).toBe(true);
expect(
mod.configValidators.cacheIgnoreHeaders(validConfig.cacheIgnoreHeaders)
).toBe(true);
expect( expect(
mod.configValidators.maximumCachedResponseSize( mod.configValidators.maximumCachedResponseSize(
validConfig.maximumCachedResponseSize validConfig.maximumCachedResponseSize
@ -137,12 +199,16 @@ describe("SVR.JS Cache mod", () => {
const invalidConfig = { const invalidConfig = {
cacheVaryHeaders: "invalid", cacheVaryHeaders: "invalid",
cacheIgnoreHeaders: "invalid",
maximumCachedResponseSize: "invalid" maximumCachedResponseSize: "invalid"
}; };
expect( expect(
mod.configValidators.cacheVaryHeaders(invalidConfig.cacheVaryHeaders) mod.configValidators.cacheVaryHeaders(invalidConfig.cacheVaryHeaders)
).toBe(false); ).toBe(false);
expect(
mod.configValidators.cacheIgnoreHeaders(invalidConfig.cacheIgnoreHeaders)
).toBe(false);
expect( expect(
mod.configValidators.maximumCachedResponseSize( mod.configValidators.maximumCachedResponseSize(
invalidConfig.maximumCachedResponseSize invalidConfig.maximumCachedResponseSize