From a1d6e23cc7d8178282a1dffc75d785d3abc0d9c5 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sun, 12 Jul 2026 18:15:19 +0100 Subject: [PATCH 1/2] feat: allow conditional revalidation for QUERY requests --- lib/request.js | 4 ++-- test/req.fresh.js | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/request.js b/lib/request.js index 3f1eeca6c1a..e33262f20df 100644 --- a/lib/request.js +++ b/lib/request.js @@ -469,8 +469,8 @@ defineGetter(req, 'fresh', function(){ var res = this.res var status = res.statusCode - // GET or HEAD for weak freshness validation only - if ('GET' !== method && 'HEAD' !== method) return false; + // GET, HEAD, or QUERY for weak freshness validation only + if ('GET' !== method && 'HEAD' !== method && 'QUERY' !== method) return false; // 2xx or 304 as per rfc2616 14.26 if ((status >= 200 && status < 300) || 304 === status) { diff --git a/test/req.fresh.js b/test/req.fresh.js index 9160e2caaf6..f22ce3f3062 100644 --- a/test/req.fresh.js +++ b/test/req.fresh.js @@ -2,6 +2,7 @@ var express = require('../') , request = require('supertest'); +var shouldSkipQuery = require('./support/utils').shouldSkipQuery describe('req', function(){ describe('.fresh', function(){ @@ -46,5 +47,42 @@ describe('req', function(){ .get('/') .expect(200, 'false', done); }) + + it('should return true for a QUERY request with a body when the resource is not modified', function(done){ + if (shouldSkipQuery(process.versions.node)) { + this.skip() + } + var app = express(); + var etag = '"12345"'; + + app.use(function(req, res){ + res.set('ETag', etag); + res.send(req.fresh); + }); + + request(app) + .query('/') + .set('If-None-Match', etag) + .send({ ids: ['a', 'b'] }) + .expect(304, done); + }) + + it('should return false for a QUERY request with a body when the resource is modified', function(done){ + if (shouldSkipQuery(process.versions.node)) { + this.skip() + } + var app = express(); + + app.use(function(req, res){ + res.set('ETag', '"123"'); + res.send(req.fresh); + }); + + request(app) + .query('/') + .set('If-None-Match', '"12345"') + .send({ ids: ['a', 'b'] }) + .expect(200, 'false', done); + }) }) }) From 741598e4d7d2fec16d6815b59c0114d61a740702 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sun, 12 Jul 2026 13:24:35 -0500 Subject: [PATCH 2/2] docs: history --- History.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/History.md b/History.md index 1505356e8d0..bbbc2534d0b 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +unreleased +========== + + * Allow conditional revalidation for QUERY requests + - `req.fresh` now includes QUERY in the freshness check, so QUERY responses can return 304 when a validator matches + 4.22.2 / 2026-05-11 ==========