Repository navigation
v0.42.0-rc1000
Pre-release
Pre-release
·
40 commits
to main
since this release
New packages
Hardened.Requests.Jwtvalidates JWT bearer tokens. It depends onMicrosoft.IdentityModel.JsonWebTokens8.23.0, and it is the only package that does.Hardened.Requests.Jwt.Testingmints tokens for tests (#510).
Breaking changes
Source and binary
Hardened.Shared.Runtime.Json.IJsonSerializerConfigurationandJsonSerializerConfigurationare renamed toISharedJsonConfigurationandSharedJsonConfiguration. TheHardened.Requests.Runtime.Configurationpair is unchanged (#506).- The constructors of
ExecutionRequestHandlerInfoandResponseCacheFiltergained trailing optional parameters, and the constructors ofAotJsonSerializerandJsonSerializerImplchanged a parameter type. A library compiled against 0.41.0-rc1000 must be rebuilt, because its generated handler info calls the old constructor (#476, #491, #506). [EnvironmentValue]is now valid on a method, a class and an assembly, withAllowMultiple = true. It no longer compiles on any other target (#482).Hardened.Refit.Testingdepends on Refit 16.3.0, up from 8.0.0. A test project that pins Refit 8 must move to 16.3.0 (#480).- The
hardened-webtemplate pins Refitter 2.2.1 and sets"optionalParameters": truein.refitter. A regenerated client makes optional parameters optional arguments, and a streamed operation returnsIAsyncEnumerable<T>(#480). - An OpenAPI scalar request body with a
formatbinds to the formatted type.int64binds tolong,date-timetoDateTimeOffsetandbinarytobyte[]. The handler's parameter type changes (#477).
Diagnostics
HSMT035is a new error. It fires on a Smithy@paginatedtrait that names a missing member or a member of the wrong type. The Smithy CLI already refuses these models, so only a committed AST reaches it (#511).HRDR011is reported at the handler's method name in the project that compiles the handler. A handler project with no entry point can now fail with it (#506).HRDW009is a new warning. It fires when a[CacheResponse<VaryByQuery>]key names no query key the operation binds (#506).HRDR012now covers contract-first operations. It warns on a declared media type that nothing writes (#472).- A build that skips the extract task reports that task's last warnings again, such as
HSMT006. With warnings as errors, every incremental build fails, not only the first (#479).
Wire behaviour
- Problem records such as
NotFound,ConflictandBadRequestimplementIProblemDetailsand go out asapplication/problem+json. A failure negotiates within the media types its operation declares for failures (#472). - A framework refusal at a status where the operation declares its own body sends that body. This covers validation, a malformed body, a deadline, a binding
BadRequestException, an unhandled 500 and the 406. A validation failure at a declared status carries no field errors (#473). - A path value that fails an OpenAPI
patternor a Smithy@patternlabel answers 400 naming the parameter. It used to answer 404 with no body (#475). - In throws mode, a thrown framework record under a contract that declares its own body at that status sends the declared body (#476).
- A Smithy
@httpPayloadblob and an OpenAPIformat: binarybody are the raw request body. A client that sent base64 in a JSON string must send the bytes (#477). - A Smithy error member with
@httpHeaderis sent as a response header and left out of the body. A service'serrorsapply to every operation in it, so an operation's 400 can become the service's declared error in place ofRequestValidationError(#478). [Authorize<TScheme>],[AuthorizeGrants]or anotherIAuthorizeAttributeon a[HardenedModule]class guards every handler compiled with that module. It used to guard nothing, so anonymous requests those handlers served now get 401.[AllowAnonymous]on a handler still exempts it (#470).- The health probes send
{"status":"Healthy"}over Kestrel and ASP.NET Core. They used to send an empty 200 (#487). - A handler that cleared
ShouldSerialize, set a status and then threw before writing answers with the failure's status and body. It used to answer the status it had set, with no body (#487). - A
CorsConfigurationregistered in a library module takes effect on the host. A route with[Cors], and every response once an origin is configured, carriesVary: Origin. A preflight allows the headers the operation reads (#506). - A response that compression would compress carries
Vary: Accept-Encodingeven when it goes out uncompressed, and so does/openapi.json(#506). - A
[CacheResponse<VaryByQuery>]with no keys varies on every query key the operation binds. It used to throw while the chain was built (#506). - In a contract-first implementation, the method's filters come before the class's, and the method's
[Timeout]wins. With a class and a method[CacheResponse], the method's key parts come first, so existing cache keys change (#506). - A stream that times out before its first item answers its timeout status, 504 by default, with its body. It used to answer 500 with no body (#506).
- A stream reads
Accept. UnderStrictnegotiation, a request whoseAcceptnames types but not the stream's media type gets 406 (#506). - On AWS Lambda and Azure Functions, a request with no
Acceptheader names nothing. These hosts used to read it asapplication/json(#506). - A request cancelled on its own token is logged as one Information line with event id 78006. It used to be logged at Error with a stack trace (#506).
- A body whose
Content-Typeno deserializer reads answers 415 with anAcceptheader. It used to be read as JSON. A body with noContent-Typeis still read as JSON, andtext/jsonand+jsontypes are now read as JSON (#506). - The test harness sends
application/jsonfor a body with noContent-Type(#506). - On Kestrel and ASP.NET Core, a body over
MaxRequestBodySizeanswers 413. It used to answer 500 (#506). - A
DateTimeOffsetin a JSON request body must state its offset.2030-01-01T00:00:00gets 400. Query, route and header values are unchanged (#506). - The 400 message for a value of the wrong type changed. "The JSON value could not be converted to System.Int32." is now "The value is not an integer this field can hold." (#506).
- A Lambda function with no
HARDENED_ENVIRONMENTdefaults toproductionwhenAWS_LAMBDA_RUNTIME_APIis set, so it no longer serves/docs. A local run throughLambdaEmulator.StartIfLocalstaysdevelopment(#506). - Environment values are parsed with the invariant culture, and a
Nullable<T>converts as its underlying type (#506). - A spec-first body whose constraints exist only in the models it holds is validated. Requests that used to reach the handler can now get 400 (#509).
- On Lambda, startup services run as the bootstrap's initializer, and one that throws is reported as an init error. A function whose
AWS_LAMBDA_LOG_FORMATis notJSONlogs a warning at startup.LambdaEmulator.StartIfLocalsets it toJSON(#508).
Published OpenAPI document
- A failure status whose bodies are all problem records is published under
application/problem+json(#472). - An operation guarded by a module-level requirement publishes
security, a 401 and a 403. An[AllowAnonymous]method under a guarded class no longer publishes its class's requirement (#470). - Every guarded operation publishes a 401 with
WWW-Authenticate. When the document declares exactly one scheme, a guarded operation that names none is published under it. The 403 lists aWWW-Authenticateheader (#486). - A
[Required]member no longer publishesnullin its schema (#506). - Without
[OpenApiInfo], the title is the assembly's name, not the module's class name (#506). [ConditionalGet]publishesIf-Modified-Sinceonly where the operation declaresLast-Modifiedon its 200, with[AnswersHeader(200, KnownHeaders.LastModified)](#506).[RateLimit]publishesRateLimit-Limit,RateLimit-RemainingandRateLimit-Reseton every response the operation lists (#506).- A header-bound Smithy member is no longer listed under the body schema's
properties(#478). - A path parameter with a pattern publishes the validation 400 (#475).
Testing
[Shared]is honoured by Kiota clients, by a factory that callscontext.CreateHttpClient, beside[Grants],[Subject]or[Anonymous], and by a sharedITestWebApp's clients. Tests that relied on a fresh container per request there now share one (#481).TestWebResponse.Deserialize<T>()andDeserializeAsyncEnumerable<T>()read with the application's JSON options and resolvers (#482).
What's Changed
- Store the handler's 200 when a revalidation fills the response cache by @ipjohnson in #468
- Apply [Authorize] on a module class to every handler compiled with it by @ipjohnson in #470
- Send problem documents as application/problem+json by @ipjohnson in #472
- Send the declared body for the framework's own refusals by @ipjohnson in #473
- Answer a path value that fails its pattern with 400, not a bodyless 404 by @ipjohnson in #475
- Send a thrown framework record as the body the contract declares by @ipjohnson in #476
- Bind a described binary request body to the raw bytes by @ipjohnson in #477
- Bind a Smithy error's header members and apply a service's errors by @ipjohnson in #478
- Replay a build task's warnings, prune stale generated files, and fix two Smithy notes by @ipjohnson in #479
- Pin Refitter 2.2.1 and Refit 16.3.0, make optional client parameters optional, and name the restore race by @ipjohnson in #480
- Send a [Shared] client's requests to one container on every construction path by @ipjohnson in #481
- Read test responses with the application's JSON settings, carry claims, stream socket bodies, and add Accepted by @ipjohnson in #482
- Carry content headers through the Lambda test host's client handler, and let a test set the remaining time by @ipjohnson in #485
- Publish the 401 for every guarded operation, the one scheme for a requirement naming none, and the 403's challenge by @ipjohnson in #486
- Send the health probes' body on a socket, answer a handler that threw after taking over its body, and let default-deny keep the probes and document public by @ipjohnson in #487
- Land the 0.41 trial fixes for #452 to #461, #465 to #467 and #419 by @ipjohnson in #506
- Add a mixed Lambda response mode that streams only event streams and NDJSON by @ipjohnson in #507
- Log Lambda functions in JSON, and run their startup services under the runtime's writer by @ipjohnson in #508
- Validate constraints reachable only through a nested model by @ipjohnson in #509
- Ship a JWT bearer principal source in its own package by @ipjohnson in #510
- Add Page and page tokens, and read Smithy's @paginated by @ipjohnson in #511
- Release 0.42.0-rc1000 by @ipjohnson in #512
Full Changelog: v0.41.0-rc1000...v0.42.0-rc1000