linters: add httpstatus linter

This commit is contained in:
2026-10-18 15:02:44 -07:00
parent 324de253c4
commit 01e6e04d14
9 changed files with 315 additions and 0 deletions

37
pkg/httpstatus/README.md Normal file
View File

@@ -0,0 +1,37 @@
# `httpstatus` linter
This linter imposes constraints on use of http status codes, targeted mainly at JSON APIs. The goal is to discourage use of non-typical status codes.
A "typical" status code is one which:
- is commonly used
- is significantly differentiated from all other "typical" status codes (i.e., there should never be more than one plausible choice of which code to return)
- programmers are expected to have it memorized.
These constraints impose a natural limit on how many "typical" status codes you can have.
A certain list of "typical" status codes is a config parameter. By default it includes:
- 200, 204
- Notes: 201 is disallowed. Use 200 instead
- 302
- Notes: all other 300-series are situationally valid, as they directly affect browser / cache behavior, but are less frequently used in JSON APIs. For this reason, `http.Redirect()` calls are exempt from the "restrict" rule.
- 400, 401, 403, 404, 429
- 409, 410 and 422 are disallowed; use 400 instead.
- Notes: explicit 405 is disallowed; router should return one automatically
- 502, 504
- Notes: explicit 500 is disallowed. Use panic instead
- All other status codes are considered "non-typical"
Status codes in the "typical" list require use of "magic numbers" (the opposite of `staticcheck`'s ST1013 check, on purpose); using `http.StatusBlahBlah` is disallowed. Only non-typical status codes are permitted to use the named `net/http` constants. "Magic numbers" are shorter and-- for typical status codes-- more readable.
If the optional "restrict" config value is set to "true", then setting non-typical status codes in HTTP handlers is also disallowed. As noted above, `http.Redirect()` and the 300-series is exempt from this.
---
## Implementation clarifications
- Check every reference to a `net/http` `Status*` constant, regardless of context. A typical constant is disallowed even in a declaration such as `const ok = http.StatusOK`.
- Inspect only status codes supplied to `http.Error` and the `WriteHeader` method declared by `http.ResponseWriter`. Do not inspect fixed-status helpers such as `http.NotFound()` or `ResponseWriter.Write()`.
- Do not diagnose a runtime value such as `w.WriteHeader(code)` when `code` is a variable.
- With `restrict: true`, reject statically known non-typical codes passed to `http.Error` or `http.ResponseWriter.WriteHeader`.
- `http.Redirect` is exempt from `restrict` for 300-series codes. Its use of a named typical `net/http` status constant remains disallowed by the general constant rule.
- A configured typical-status-code list replaces the default list.