From 06476bcc454527b882ff91b3c2a6dad7d4f85255 Mon Sep 17 00:00:00 2001 From: Kevin Stich Date: Wed, 2 Oct 2024 14:52:33 -0700 Subject: [PATCH] Require an Accept header for RPCv2 requests --- .../protocols/smithy-rpc-v2.rst | 20 ++++-- .../model/rpcv2Cbor/cbor-lists.smithy | 21 ++++-- .../model/rpcv2Cbor/cbor-maps.smithy | 24 ++++--- .../model/rpcv2Cbor/cbor-structs.smithy | 65 +++++++++++++++---- .../model/rpcv2Cbor/defaults.smithy | 18 +++-- .../model/rpcv2Cbor/empty-input-output.smithy | 8 ++- 6 files changed, 114 insertions(+), 42 deletions(-) diff --git a/docs/source-2.0/additional-specs/protocols/smithy-rpc-v2.rst b/docs/source-2.0/additional-specs/protocols/smithy-rpc-v2.rst index f4abe4669bc..315589b401f 100644 --- a/docs/source-2.0/additional-specs/protocols/smithy-rpc-v2.rst +++ b/docs/source-2.0/additional-specs/protocols/smithy-rpc-v2.rst @@ -214,10 +214,16 @@ Buffered RPC requests for the ``rpcv2Cbor`` protocol SHOULD include a ``Content-Length`` header. Event streaming requests MUST NOT specify a content length (instead using ``Transfer-Encoding: chunked`` on HTTP/1.1). -Requests with event stream responses for the ``rpcv2Cbor`` protocol MUST -include an ``Accept`` header set to the value -``application/vnd.amazon.eventstream``. Other forms of content streaming MAY be -added in the future, utilizing different values for ``Accept``. +Requests for the ``rpcv2Cbor`` protocol MUST use the following behavior for +setting an ``Accept`` header: + +* For requests with event streaming responses: the value of the ``Accept`` + header MUST be ``application/vnd.amazon.eventstream``. +* For requests with all other response types: the value of the ``Accept`` + header MUST be ``application/cbor``. + +Other forms of content streaming MAY be added in the future, utilizing +different values for ``Accept``. In summary, the ``rpcv2Cbor`` protocol defines behavior for the following headers for requests: @@ -241,9 +247,9 @@ headers for requests: - The standard ``Content-Length`` header defined by :rfc:`9110#section-8.6`. For event streaming requests, this MUST NOT be set. * - ``Accept`` - - Conditional - - For requests with event streaming responses, this is - ``application/vnd.amazon.eventstream``. + - Required + - The value of ``application/cbor``. For requests with event streaming + responses, this is ``application/vnd.amazon.eventstream``. ~~~~~~~~~ diff --git a/smithy-protocol-tests/model/rpcv2Cbor/cbor-lists.smithy b/smithy-protocol-tests/model/rpcv2Cbor/cbor-lists.smithy index be0817cfccf..b7d99291fc1 100644 --- a/smithy-protocol-tests/model/rpcv2Cbor/cbor-lists.smithy +++ b/smithy-protocol-tests/model/rpcv2Cbor/cbor-lists.smithy @@ -45,7 +45,8 @@ apply RpcV2CborLists @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -116,7 +117,8 @@ apply RpcV2CborLists @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -136,7 +138,8 @@ apply RpcV2CborLists @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -155,7 +158,8 @@ apply RpcV2CborLists @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -175,7 +179,8 @@ apply RpcV2CborLists @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -343,7 +348,8 @@ structure StructureListMember { bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -364,7 +370,8 @@ structure StructureListMember { bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" diff --git a/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy b/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy index 0f4a5223d6e..6013433f089 100644 --- a/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy +++ b/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy @@ -29,7 +29,8 @@ apply RpcV2CborDenseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -55,7 +56,8 @@ apply RpcV2CborDenseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -79,7 +81,8 @@ apply RpcV2CborDenseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -222,7 +225,8 @@ apply RpcV2CborSparseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -248,7 +252,8 @@ apply RpcV2CborSparseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -278,7 +283,8 @@ apply RpcV2CborSparseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -300,7 +306,8 @@ apply RpcV2CborSparseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -323,7 +330,8 @@ apply RpcV2CborSparseMaps @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" diff --git a/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy b/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy index 7ea41d9cf4d..81ae0836043 100644 --- a/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy +++ b/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy @@ -13,7 +13,8 @@ use smithy.test#httpResponseTests documentation: "Serializes simple scalar properties", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -44,7 +45,8 @@ use smithy.test#httpResponseTests a key encoded using an indefinite length string.""", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -77,7 +79,8 @@ use smithy.test#httpResponseTests bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -97,7 +100,8 @@ use smithy.test#httpResponseTests bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -111,7 +115,8 @@ use smithy.test#httpResponseTests documentation: "Supports handling NaN float values.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -131,7 +136,8 @@ use smithy.test#httpResponseTests documentation: "Supports handling Infinity float values.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -151,7 +157,8 @@ use smithy.test#httpResponseTests documentation: "Supports handling Infinity float values.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -171,7 +178,8 @@ use smithy.test#httpResponseTests documentation: "The server should be capable of deserializing indefinite length text strings.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -191,7 +199,8 @@ use smithy.test#httpResponseTests documentation: "The server should be capable of deserializing indefinite length byte strings.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -211,7 +220,8 @@ use smithy.test#httpResponseTests documentation: "Supports upcasting from a smaller byte representation of the same data type.", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -238,7 +248,8 @@ use smithy.test#httpResponseTests generated against an older Smithy model.""", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" } requireHeaders: [ "Content-Length" @@ -260,6 +271,35 @@ use smithy.test#httpResponseTests blobValue: "foo" }, appliesTo: "server" + }, + { + id: "RpcV2CborServersShouldHandleNoAcceptHeader", + protocol: rpcv2Cbor, + documentation: "Servers should tolerate requests without an Accept header set.", + headers: { + "smithy-protocol": "rpc-v2-cbor", + "Content-Type": "application/cbor" + } + requireHeaders: [ + "Content-Length" + ], + method: "POST", + bodyMediaType: "application/cbor", + uri: "/service/RpcV2Protocol/operation/SimpleScalarProperties", + body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kD0AABsaW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==", + params: { + byteValue: 5, + doubleValue: 1.889, + falseBooleanValue: false, + floatValue: 7.625, + integerValue: 256, + longValue: 9873, + shortValue: 9898, + stringValue: "simple", + trueBooleanValue: true, + blobValue: "foo" + }, + appliesTo: "server" } ]) @httpResponseTests([ @@ -453,7 +493,8 @@ apply RecursiveShapes @httpRequestTests([ bodyMediaType: "application/cbor", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" diff --git a/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy b/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy index bf1e44834b4..f2d969bcafb 100644 --- a/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy +++ b/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy @@ -18,7 +18,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -40,7 +41,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -60,7 +62,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -105,7 +108,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -152,7 +156,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -174,7 +179,8 @@ apply OperationWithDefaults @httpRequestTests([ uri: "/service/RpcV2Protocol/operation/OperationWithDefaults", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" diff --git a/smithy-protocol-tests/model/rpcv2Cbor/empty-input-output.smithy b/smithy-protocol-tests/model/rpcv2Cbor/empty-input-output.smithy index c753e062df5..b2bb2161533 100644 --- a/smithy-protocol-tests/model/rpcv2Cbor/empty-input-output.smithy +++ b/smithy-protocol-tests/model/rpcv2Cbor/empty-input-output.smithy @@ -14,6 +14,7 @@ use smithy.test#httpResponseTests documentation: "Body is empty and no Content-Type header if no input", headers: { "smithy-protocol": "rpc-v2-cbor", + "Accept": "application/cbor" }, forbidHeaders: [ "Content-Type", @@ -108,7 +109,8 @@ operation NoInputOutput {} documentation: "When Input structure is empty we write CBOR equivalent of {}", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, requireHeaders: [ "Content-Length" @@ -127,6 +129,7 @@ operation NoInputOutput {} documentation: "When Input structure is empty the server should accept an empty body", headers: { "smithy-protocol": "rpc-v2-cbor", + "Accept": "application/cbor", "Content-Type": "application/cbor" }, method: "POST", @@ -192,7 +195,8 @@ operation EmptyInputOutput { documentation: "When input is empty we write CBOR equivalent of {}", headers: { "smithy-protocol": "rpc-v2-cbor", - "Content-Type": "application/cbor" + "Content-Type": "application/cbor", + "Accept": "application/cbor" }, forbidHeaders: [ "X-Amz-Target"