Remove etag from response when modifying headers

This commit is contained in:
Sander Declerck 2025-11-13 16:27:42 +01:00
parent 752504dcc8
commit dc6f37b3ec
No known key found for this signature in database
3 changed files with 18 additions and 8 deletions

View file

@ -11,7 +11,7 @@ import { EventEmitter } from "events";
* @property {string} targetUrl * @property {string} targetUrl
* @property {(packageName: string | undefined, version: string | undefined) => void} blockMalware * @property {(packageName: string | undefined, version: string | undefined) => void} blockMalware
* @property {(modificationFunc: (headers: NodeJS.Dict<string | string[]>) => void) => void} modifyRequestHeaders * @property {(modificationFunc: (headers: NodeJS.Dict<string | string[]>) => void) => void} modifyRequestHeaders
* @property {(modificationFunc: (body: Buffer) => Buffer) => void} modifyBody * @property {(modificationFunc: (body: Buffer, headers: NodeJS.Dict<string | string[]> | undefined) => Buffer) => void} modifyBody
* @property {() => RequestInterceptionHandler} build * @property {() => RequestInterceptionHandler} build
* *
* *
@ -19,7 +19,7 @@ import { EventEmitter } from "events";
* @property {{statusCode: number, message: string} | undefined} blockResponse * @property {{statusCode: number, message: string} | undefined} blockResponse
* @property {(headers: NodeJS.Dict<string | string[]> | undefined) => void} modifyRequestHeaders * @property {(headers: NodeJS.Dict<string | string[]> | undefined) => void} modifyRequestHeaders
* @property {() => boolean} modifiesResponse * @property {() => boolean} modifiesResponse
* @property {(body: Buffer) => Buffer} modifyBody * @property {(body: Buffer, headers: NodeJS.Dict<string | string[]> | undefined) => Buffer} modifyBody
*/ */
/** /**
@ -67,7 +67,7 @@ function createRequestContext(targetUrl, eventEmitter) {
let blockResponse = undefined; let blockResponse = undefined;
/** @type {Array<(headers: NodeJS.Dict<string | string[]>) => void>} */ /** @type {Array<(headers: NodeJS.Dict<string | string[]>) => void>} */
let reqheaderModificationFuncs = []; let reqheaderModificationFuncs = [];
/** @type {Array<(body: Buffer) => Buffer>} */ /** @type {Array<(body: Buffer, headers: NodeJS.Dict<string | string[]> | undefined) => Buffer>} */
let modifyBodyFuncs = []; let modifyBodyFuncs = [];
/** /**
@ -102,13 +102,14 @@ function createRequestContext(targetUrl, eventEmitter) {
/** /**
* @param {Buffer} body * @param {Buffer} body
* @param {NodeJS.Dict<string | string[]> | undefined} headers
* @returns {Buffer} * @returns {Buffer}
*/ */
function modifyBody(body) { function modifyBody(body, headers) {
let modifiedBody = body; let modifiedBody = body;
for (var func of modifyBodyFuncs) { for (var func of modifyBodyFuncs) {
modifiedBody = func(body); modifiedBody = func(body, headers);
} }
return modifiedBody; return modifiedBody;

View file

@ -34,9 +34,10 @@ export function isPackageInfoUrl(url) {
/** /**
* *
* @param {Buffer} body * @param {Buffer} body
* @param {NodeJS.Dict<string | string[]> | undefined} headers
* @returns Buffer * @returns Buffer
*/ */
export function modifyNpmInfoResponse(body) { export function modifyNpmInfoResponse(body, headers) {
try { try {
if (body.byteLength === 0) { if (body.byteLength === 0) {
return body; return body;
@ -70,6 +71,11 @@ export function modifyNpmInfoResponse(body) {
if (timestamp > cutOff) { if (timestamp > cutOff) {
deleteVersionFromJson(bodyJson, version); deleteVersionFromJson(bodyJson, version);
if (headers) {
// When modifying the response, the etag no longer matches the content
// so the etag needs to be removed before sending the response.
delete headers["etag"];
}
continue; continue;
} }
} }

View file

@ -188,7 +188,8 @@ function createProxyRequest(hostname, req, res, requestHandler) {
res.end("Internal Server Error"); res.end("Internal Server Error");
return; return;
} }
res.writeHead(proxyRes.statusCode, proxyRes.headers);
const { statusCode, headers } = proxyRes;
if (requestHandler.modifiesResponse()) { if (requestHandler.modifiesResponse()) {
/** @type {Array<any>} */ /** @type {Array<any>} */
@ -204,17 +205,19 @@ function createProxyRequest(hostname, req, res, requestHandler) {
buffer = gunzipSync(buffer); buffer = gunzipSync(buffer);
} }
buffer = requestHandler.modifyBody(buffer); buffer = requestHandler.modifyBody(buffer, headers);
if (proxyRes.headers["content-encoding"] === "gzip") { if (proxyRes.headers["content-encoding"] === "gzip") {
buffer = gzipSync(buffer); buffer = gzipSync(buffer);
} }
res.writeHead(statusCode, headers);
res.end(buffer); res.end(buffer);
}); });
} else { } else {
// If the response is not being modified, we can // If the response is not being modified, we can
// just pipe without the need for buffering the output // just pipe without the need for buffering the output
res.writeHead(statusCode, headers);
proxyRes.pipe(res); proxyRes.pipe(res);
} }
}); });