Repository navigation
HEAD /query answers an empty page with 404 where POST /query answers 200 [] #304
Copy link
Copy link
Closed
Description
Summary
POST requests do not support HEAD. HEAD request handling should be removed from all POST routes and fail into a 'wrong method' response.
RFC 9110 defines HEAD as GET without content, so a route with no GET has nothing for HEAD to mirror. /query was the only POST route with a HEAD handler of its own (routes/query.js:9, queryHeadRequest at controllers/history.js:86). Every other POST route already answered HEAD with a 405 through its .all() fallback.
Why this matters
The 404 in the title was the smallest of the handler's problems:
- It answered a request it could not read.
/queryneeds its filter in the request body, andHEADhas no defined body semantics. Some clients refuse to send one at all; supertest (superagent) is one of them. - With no body it matched everything.
queryHeadRequestlacked the empty-body guardPOST /queryhas, so it randb.find(undefined). A bodilessHEAD /v1/api/queryreturned200withContent-Length: 536127against the dev collection, whilePOST /querywith{}is a400. - It disagreed with
POSTon an empty result, answering404wherePOST /queryanswers200 [].
Removing the handler resolves all three rather than repairing one.
Changes
routes/query.js: the.head(controller.queryHeadRequest)line is removed.HEAD /querynow falls into the route's existing.all()405, and so doesHEADon the legacy/v1/api/getByProperties.actionalias, which is rewritten to/query.controllers/history.js:queryHeadRequestis deleted, along with its export and thegetPaginationimport only it used.db-controller.jsno longer exports it.openapi/contracts/core-provider.openapi.yaml: thehead:operation under/api/queryis removed, and__tests__/core_provider_contract.test.jsno longer requires response codes forHEAD /api/query.routes/__tests__/query.test.js: theHEAD /querytests are removed.routes/__tests__/route_wrappers.test.js: every route in the existing 405 table that has noGEThandler is now asserted to have noHEADhandler of its own, so aHEADhandler cannot be reintroduced on aPOST,PUT,PATCH, orDELETEroute without a failing test.public/API.html: the result-ordering section no longer says/querypages "on bothPOSTandHEAD".
Not changed
HEADonGETroutes —/id/:_id,/id/:_id/expanded,/since/:_id, and/history/:_id— still answers200. Their identifier is in the URL, and Express answersHEADfrom theGEThandler, which is valid HTTP. HEAD history - since - query #96 should not be read as removing those.- The
.all()405 fallbacks still send noAllowheader, which RFC 9110 requires on a 405. That applies to every route with a method fallback and is left for a separate issue.
Verification
Against the local pm2 app:
HEAD /v1/api/query -> 405
HEAD /v1/api/getByProperties.action -> 405
HEAD /v1/api/search -> 405
HEAD /v1/api/create -> 405
HEAD /gog/fragmentsInManuscript -> 405
HEAD /v1/id/000000000000000000000001 -> 200
HEAD /v1/since/000000000000000000000001 -> 200
HEAD /v1/history/000000000000000000000001 -> 200
Acceptance criteria
-
HEADon everyPOSTroute answers 405 through the route's method fallback, including/queryand itsgetByPropertiesalias - A test fails if a route without a
GEThandler defines its ownHEADhandler -
queryHeadRequestand its export are removed -
HEAD /api/queryis removed from the OpenAPI contract and from the contract test's required response codes -
HEADon theGETroutes is unchanged -
public/API.htmlno longer describesHEADon/query
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
/queryand/searchhonest and self-describing #299