Skip to content

req.fresh returns false for QUERY requests, so 304 Not Modified is never sent #7365

Description

@Cherry

Environment information

Version: 5.2.1 (also present on the 4.x line — same req.fresh implementation)

Platform: Microsoft Windows NT 10.0.26200.0 x64

Node.js version: v24.18.0 (QUERY requires Node >= 22, where http.METHODS includes QUERY)

Any other relevant information:
req.fresh (lib/request.js) short-circuits to false for any method other than GET/HEAD, so res.send/res.json never emit a 304 Not Modified for a QUERY request even when the client sends a matching If-None-Match.

As far as I can tell, QUERY is a safe, idempotent, cacheable method whose responses explicitly support conditional revalidation, as per https://datatracker.ietf.org/doc/rfc10008/, so it should behave like GET/HEAD here.

What steps will reproduce the bug?

Minimal app:

const express = require('express')
const app = express()

app.query('/search', (req, res) => {
  res.set('ETag', '"abc"')
  res.json({ results: [] })
})

app.listen(3000)

Send a conditional QUERY with a matching If-None-Match:

# Sends a body (the point of QUERY) and the ETag the server previously returned
curl -i -X QUERY http://localhost:3000/search \
  -H 'Content-Type: application/json' \
  -H 'If-None-Match: "abc"' \
  --data '{"q":"x"}'

Observed: 200 OK with the full response body every time.

Expected: 304 Not Modified with an empty body — the same behavior an identical GET produces, since the response ETag matches the request's If-None-Match.

Equivalent reproduction against req.fresh directly (mirrors the test suite style):

const app = express()
app.use((req, res) => {
  res.set('ETag', '"12345"')
  res.send(req.fresh) // GET -> true (304); QUERY -> false (200) before the fix
})
// request(app).query('/').set('If-None-Match', '"12345"') => 200 'false', expected 304

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions