Commit 7fc5b19
feat: Non-JSON bodies (#53)
* fix: Reject NaN and Infinity as Number coercion results
Double.parseDouble accepts "NaN", "Infinity", and "-Infinity", which
are not valid JSON numbers. They would slip past NumberSchema coercion
and bypass numeric constraint validation (any comparison with NaN is
false). Reject non-finite results with the same type error used for
other coercion failures.
* fix: Case-insensitive Content-Type matching
Per RFC 9110/2045 media types are case-insensitive. Lower-case the
result of ContentTypeHeader.subtype() and lower-case spec content-type
keys at parse time so headers like "Application/JSON" or
"Text/Plain" match requestBody.content entries regardless of casing.
Also fixes a compile error in FormUrlEncodedParser.decodeComponent
which referenced a non-existent ValidationException constructor; the
URLDecoder failure path now wraps the IllegalArgumentException as a
proper ValidationError(/body, decode, ...).
* refactor: Address SonarQube findings on body parsing helpers
- ContentTypeHeader.parameter: replace dual-continue loop with a single
early-return guarded by an inline key check; extract quote-stripping
into a small unquote() helper.
- FormUrlEncodedParser.decodeComponent: chain the original
IllegalArgumentException via initCause() on the rethrown
ValidationException so the underlying cause is preserved.
- FormUrlEncodedParser.addEntry: replace get()+null-check+put() with
Map.merge(), which is the right primitive for collision handling.
- TextPlainParserTest: use isEmpty() instead of isEqualTo("").
* refactor: Rename ContentTypeHeader.subtype to mediaType
The method returns the full media type (e.g. "application/json"),
not the RFC 9110 subtype (e.g. "json"). Rename the method, its
single caller's local variable, and the test method names to match
what's actually returned.
* docs: Fix README inaccuracies on parser selection and form value types
- Selection is by the full media type (type/subtype), not the RFC
9110 subtype. Note that lookup is case-insensitive.
- After coercion, form list values are not strictly List<String> —
an integer-array property yields List<Long>, etc. Describe the
pre- and post-coercion shape correctly.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>1 parent 7447a0e commit 7fc5b19
18 files changed
Lines changed: 2248 additions & 53 deletions
File tree
- docs/superpowers
- plans
- specs
- src
- main/java/com/retailsvc/http
- internal
- spec
- test
- java/com/retailsvc/http
- internal
- start
- resources
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
103 | 117 | | |
104 | 118 | | |
105 | 119 | | |
| |||
0 commit comments