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

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions