Repository navigation
fix!: validate HTTP message statusCode and store it as int - #52
Conversation
HttpMessageBinding parsed `statusCode` with int.TryParse and ignored the value when parsing failed, so e.g. `statusCode: not-found` was read with no diagnostics and dropped on write. It now uses GetIntegerValue(), which records "Value could not parse to integer." like the other bindings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 28 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
HttpStatusCode doesn't contain all status codes, unfortunately. I agree on the potential validation |
RFC 9110 defines status codes as three-digit integers from 100 to 599. Values outside that range (e.g. `statusCode: 42`) were accepted without any diagnostic. They are now reported in diagnostic.Errors with a pointer to the field. The value is still kept on the binding so the document can be written back unchanged. The check lives in the binding parser because the core validation rules cannot reference the bindings assembly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Good point. I checked: HttpStatusCode only defines 61 of the 500 codes in 100–599 (no 418, 425, 499, 520–530, 599…). It doesn't lose data though: the enum is an int underneath, so (HttpStatusCode)418 reads fine and we write (int)StatusCode, so it round-trips as statusCode: 418. The tests in this PR already round-trip values the enum doesn't define (599, 42). The downside is only on the API side (ToString() gives "418", Enum.IsDefined is false, and a switch can't name them). I'd keep this PR as the parsing/range fix and switch StatusCode to int? in a follow-up, since that changes the public API. Happy to fold it in here instead if you'd rather take the break now while 3.1 is still beta. Your call. |
I think int would be better or one of the newer status code types (i forget the name). This lib has always been about type correctness, so the enum feels like a miss on my behalf. |
System.Net.HttpStatusCode only defines 61 of the 500 codes in 100-599. Codes such as 425 Too Early (RFC 8470), nginx 499 or Cloudflare 520 round-tripped through the enum cast, but could not be named, printed as bare numbers and failed Enum.IsDefined, so the type implied they were invalid. StatusCode is now a plain int?, validated by the 100-599 range check. BREAKING CHANGE: `HttpMessageBinding.StatusCode` is now `int?` instead of `HttpStatusCode?`. Cast when assigning from the enum, e.g. `StatusCode = (int)HttpStatusCode.OK`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@VisualBean done :) |
Problem
HttpMessageBindingparsedstatusCodelike this:That caused three problems:
statusCode: not-foundreads with no errors,StatusCodestaysnull, and the field is gone when the document is written back. It's the same silent drop fix: report invalid MQTT and ROS2 binding scalars as errors #48 fixed for the MQTT and ROS2 fields.statusCode: 42,0or600read without any diagnostic.System.Net.HttpStatusCodedoesn't cover real-world codes. It defines only 61 of the 500 codes in 100–599. Missing ones include425 Too Early(RFC 8470, IANA-registered), nginx499, Cloudflare520–530and599. Thanks to the enum cast they still round-tripped, but they couldn't be named,ToString()printed a bare number, andEnum.IsDefinedreturnedfalse, so the type implied they were invalid.Change
statusCodeis parsed withn.GetIntegerValue(), so a non-integer value recordsValue could not parse to integer.indiagnostic.Errors.statusCode <n> is not a valid HTTP status code. It must be between 100 and 599., with a pointer to the field. The value is still kept on the binding, so the document can be written back unchanged.HttpMessageBinding.StatusCodeis nowint?instead ofHttpStatusCode?, as agreed in review. To migrate, cast when assigning from the enum, e.g.StatusCode = (int)HttpStatusCode.OK. The YAML/JSON output is unchanged, since it was already written as a number.The range check lives in the binding parser rather than in a validation rule. The validation rules are in the core
ByteBard.AsyncAPIassembly, which can't referenceByteBard.AsyncAPI.Bindings.Tests
In
HttpBindings_Should:V3_HttpMessageBinding_ReadsStatusCode: a valid404reads as404.V3_HttpMessageBinding_WithInvalidStatusCode_ReportsError(not-found,200.5).V3_HttpMessageBinding_WithValidStatusCode_ReportsNoErrorAndRoundTrips(100,599, plus425,499and520, none of which areHttpStatusCodemembers): no error, and each is written back.V3_HttpMessageBinding_WithOutOfRangeStatusCode_ReportsErrorAndKeepsValue(0,42,99,600,-200): checks the error and its pointer, that the value is kept, and that it is written back.StatusCode = 200.The full suite (331 tests) passes on net8.0/net9.0/net10.0.
🤖 Generated with Claude Code