A request method tells the server what the client is asking it to do. A read-only file origin has a narrow contract, but “static site” alone does not prove that proxies or imported handlers expose no write operations. Check the route actually serving the resource.
Safe and idempotent answer different questions
GET and HEAD are safe: the client does not request a state-changing action. Incidental logging, metrics, or accounting can still change server state. PUT and DELETE are idempotent in their defined semantics, but are not safe: repeating the same request is intended to have the same effect as performing it once. That does not require identical response statuses, and it does not make every retry after a network failure appropriate.
For a read-only static origin:
- GET retrieves a representation.
- HEAD describes the corresponding GET without response content.
- OPTIONS asks about the target’s communication options; a file handler may reject it.
- POST / PUT / DELETE / PATCH should not fall through to successful file serving unless a separate, intended handler implements their semantics.
A Caddy file handler’s method boundary
Caddy v2.10.2’s file-serving path accepts GET and HEAD and rejects other methods with 405 and Allow: GET, HEAD. Redirects, missing paths, error handlers, and other configured routes can answer earlier or differently, so this is not a universal response for every static-site URL.
The earlier note recorded:
$ curl -s -o /dev/null -w 'OPTIONS -> HTTP %{http_code}\n' -X OPTIONS https://www.xbcatm.com/
OPTIONS -> HTTP 405
The original response log is not retained here, and this review did not reproduce that live result. The command reports only status; it does not establish that the required Allow field was present. Inspect that field separately. 405 means a known method is not supported for this target; 501 Not Implemented is the usual distinction when the server does not recognize or implement a method at all.
HEAD parity allows documented omissions
HEAD should describe the same selected representation as GET, while omitting content. Fields calculated only while generating the content may be omitted. If Content-Length is present, it must describe the corresponding GET content, using the same content coding.
The earlier note reported this comparison:
HEAD content-length: 15890
GET bytes read : 15890
Those historical numbers are not a fixed expected size or a current verification result. A missing HEAD length alone is legal; a wrong supplied length needs investigation. Follow the head-request-parity note for paired probes. The downloadable check-http-headers.sh helper inspects a GET response and does not perform this comparison automatically.
Reject unintended writes without hiding the contract
For a method recognized but disallowed on the target, return 405 with Allow listing the methods actually supported. The list is not necessarily restricted to safe methods on an application route. Do not return a plausible 200 page for an ignored write request.
If browser clients need CORS preflight, define that OPTIONS behavior explicitly; method support and CORS permission are separate decisions. Test write rejection only against an authorized disposable fixture rather than assuming a public endpoint is harmless because the site looks static.
Sources
- RFC 9110 — HTTP Semantics, safe/idempotent methods and HEAD/405/501 semantics, checked 2026-10-15.
- MDN: HTTP request methods, method overview, checked 2026-10-15.
- curl manual, method and response-inspection options, checked 2026-10-15.
- Caddy v2.10.2 file-server source, method rejection after file selection, checked 2026-10-15.
- WHATWG Fetch Standard, CORS preflight processing, checked 2026-10-15.