Skip to content

Commit

Permalink
Warnings for header and cookie serialization (3.0.4)
Browse files Browse the repository at this point in the history
This makes serializing cookie paramters and most header parameters
with `schema` and `style` NOT RECOMMENDED.
It is not clear that any `schema`-based serialization for cookies
will produce a correct value (although the reason is sufficiently
obscure that many implementations might ignore it and produce
cookie-compliant output anyway).
With headers, there are numerous pitfalls and only the simplest
scenarios will work properly, although perhaps the warning
here could be reworded to emphasize the safe scenarios more clearly.

The details are relegated to an appendix, because truly, most
people will not want to know.  But recommending against syntactically
legal configurations really does need to be explained in the spec.

Also, don't use

- in: header
  name: Cookie

Because... yeah.
  • Loading branch information
handrews committed May 23, 2024
1 parent c069212 commit 9ba7454
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions versions/3.0.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,6 @@ There are four possible parameter locations specified by the `in` field:
* header - Custom headers that are expected as part of the request. Note that [RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case insensitive.
* cookie - Used to pass a specific cookie value to the API.


##### Fixed Fields

The rules for serialization of the parameter are specified in one of two ways.
Expand All @@ -1056,11 +1055,15 @@ Field Name | Type | Description
<a name="parameterDeprecated"></a> deprecated | `boolean` | Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is `false`.
<a name="parameterAllowEmptyValue"></a> allowEmptyValue | `boolean` | If `true`, clients MAY pass a zero-length string value in place of parameters that would otherwise be omitted entirely, which the server SHOULD interpret as the parameter being unused. Default value is `false`. If [`style`](#parameterStyle) is used, and if behavior is `n/a` (cannot be serialized), the value of `allowEmptyValue` SHALL be ignored. Interactions between this field and the parameter's [Schema Object](#schemaObject) are implementation-defined. This field is valid only for `query` parameters. Use of this property is NOT RECOMMENDED, and it is likely to be removed in a later revision.

Note that while `"Cookie"` as a `name` is not forbidden with `in: header`, the effect of defining a cookie parameter that way is undefined; use `in: cookie` instead.

###### Fixed Fields for use with `schema`

For simpler scenarios, a [`schema`](#parameterSchema) and [`style`](#parameterStyle) can describe the structure and syntax of the parameter.
When `example` or `examples` are provided in conjunction with the `schema` object, the example MUST follow the prescribed serialization strategy for the parameter.

Serializing with `schema` is NOT RECOMMENDED for `in: cookie` parameters, `in: header` paramters that use HTTP header parameters (name=value pairs following a `;`) in their values, or `in: header` parameters where values might have non-URL-safe characters; see [Appendix D](#serializingHeadersAndCookies) for details.

Field Name | Type | Description
---|:---:|---
<a name="parameterStyle"></a>style | `string` | Describes how the parameter value will be serialized depending on the type of the parameter value. Default values (based on value of `in`): for `query` - `form`; for `path` - `simple`; for `header` - `simple`; for `cookie` - `form`.
Expand All @@ -1070,14 +1073,16 @@ Field Name | Type | Description
<a name="parameterExample"></a>example | Any | Example of the parameter's potential value. The example SHOULD match the specified schema and encoding properties if present. The `example` field is mutually exclusive of the `examples` field. Furthermore, if referencing a `schema` that contains an example, the `example` value SHALL _override_ the example provided by the schema. To represent examples of media types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where necessary.
<a name="parameterExamples"></a>examples | Map[ `string`, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)] | Examples of the parameter's potential value. Each example SHOULD contain a value in the correct format as specified in the parameter encoding. The `examples` field is mutually exclusive of the `example` field. Furthermore, if referencing a `schema` that contains an example, the `examples` value SHALL _override_ the example provided by the schema.

###### Fixed Fields and considerations for use with `content`
###### Fixed Fields for use with `content`

For more complex scenarios, the [`content`](#parameterContent) property can define the media type and schema of the parameter, as well as give examples of its use.
Using `content` with a `text/plain` media type is RECOMMENDED for `in: header` and `in: cookie` parameters where the `schema` strategy is not appropriate.

Field Name | Type | Description
---|:---:|---
<a name="parameterContent"></a>content | Map[`string`, [Media Type Object](#mediaTypeObject)] | A map containing the representations for the parameter. The key is the media type and the value describes it. The map MUST only contain one entry.


##### Style Values

In order to support common ways of serializing simple parameters, a set of `style` values are defined.
Expand Down Expand Up @@ -3505,3 +3510,24 @@ Version | Date | Notes
1.2 | 2014-03-14 | Initial release of the formal document.
1.1 | 2012-08-22 | Release of Swagger 1.1
1.0 | 2011-08-10 | First release of the Swagger Specification

## <a name="serializingHeadersAndCookies"></a>Appendix D: Serializing Headers and Cookies

RFC6570's percent-encoding behavior is not always appropriate for `in: header` and `in: cookie` parameters.
In many cases, it is more appropriate to use `content` with a media type such as `text/plain` and require the application to assemble the correct string.

For both cookies ([RFC6265](https://www.rfc-editor.org/rfc/rfc6265)) and HTTP headers using the structured fields ([RFC8941](https://www.rfc-editor.org/rfc/rfc8941)) syntax, non-ASCII content is handled using base64 encoding (`format: byte`).
Note that the standard base64 encoding alphabet includes non-URL-safe characters that are percent-encoded by RFC6570 expansion; serializing values through both encodings is NOT RECOMMENDED.

Most HTTP headers predate the structured field syntax, and a comprehensive assessment of their syntax and encoding rules is well beyond the scope of this specification.
While [RFC8187](https://www.rfc-editor.org/rfc/rfc8187) recommends percent-encoding HTTP field (header or trailer) parameters, these parameters appear after a `;` character.
With `style: simple`, that delimiter would itself be percent-encoded, violating the general HTTP field syntax.

Using `style: form` with `in: cookie` is ambiguous for a single value, and incorrect for multiple values.
This is true whether the multiple values are the result of using `explode: true` or not.

This style is specified to be equivalent to RFC6570 form expansion which includes the `?` character (see Appendix C for more details), which is not part of the cookie syntax.
However, examples of this style in past versions of this specification have not included the `?` prefix, suggesting that the comparison is not exact.
Because implementations that rely on an RFC6570 implementation and those that perform custom serialization based on the style example will produce different results, it is implementation-defined as to which of the two results is correct.

For multiple values, `style: form` is always incorrect as name=value pairs in cookies are delimited by `; ` (a semicolon followed by a space character) rather than `&`.

0 comments on commit 9ba7454

Please sign in to comment.