Project: CloudEvents (App Definition and Development / Streaming & Messaging)
File: http-protocol-binding.md

The HTTP Protocol Binding for CloudEvents defines how events are mapped to HTTP 1.1 request and response messages. 1.1. 1.2. 1.3. 1.4. 1.5. 2.1. 2.2. 3.1. 3.2. 3.3. is a standardized and protocol-agnostic definition of the structure and metadata description of events. This specification defines how the elements defined in the CloudEvents specification are to be used in [HTTP 1.1][rfc7230] requests and response messages. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in . This specification does not prescribe rules constraining the use or handling of specific , and it also does not constrain the that is used for transferring or soliciting events. Events can be transferred with all standard or application-defined HTTP request methods that support payload body transfers. Events can be also be transferred in HTTP responses and with all HTTP status codes that permit payload body transfers. All examples herein that show HTTP methods, HTTP target URIs, and HTTP status codes are non-normative illustrations. This specification also applies equivalently to HTTP/2 (), which is compatible with HTTP 1.1 semantics. The CloudEvents specification defines three content modes for transferring events: structured, binary and batch. The HTTP protocol binding supports all three content modes. Every compliant implementation SHOULD support both structured and binary modes. In the binary content mode, the value of the event `data` is placed into the HTTP request, or response, body as-is, with the `datacontenttype` attribute value declaring its media type in the HTTP `Content-Type` header; all other event attributes are mapped to HTTP headers. In the structured content mode, event metadata attributes and event data are placed into the HTTP request or response body using an that supports . In the batched content mode, event metadata attributes and event data of multiple events are batched into a single HTTP request or response body using an that supports batching . Event formats, used with the structured content mode, define how an event is expressed in a particular data format. All implementations of this specification that support the structured content mode MUST support the non-batching [JSON event format][json-format], but MAY support any additional, including proprietary, formats. Event formats MAY additionally define how a batch of events is expressed. Those can be used with the batched content mode. This specification does not introduce any new security features for HTTP, or mandate specific existing features to be used. This specification applies identically to . This specification does not further define any of the core event attributes. This mapping is intentionally robust against changes, including the addition and removal of event attributes, and also accommodates vendor extensions to the event metadata. The `datacontenttype` attribute is assumed to contain a compliant media-type expression. `data` is assumed to contain opaque application data that is encoded as declared by the `datacontenttype` attribute. An application is free to hold the information in any in-memory representation of its choosing, but as the value is transposed into HTTP as defined in this specification, the assumption is that the `data` value is made available as a sequence of

For instance, if the declared `datacontenttype` is `application/json;charset=utf-8`, the expectation is that the `data` value is made available as encoded JSON text to HTTP. The event binding is identical for both HTTP request and response messages. The content mode is chosen by the sender of the event, which is either the requesting or the responding party. Gestures that might allow solicitation of events using a particular mode might be defined by an application, but are not defined here. The batched mode MUST NOT be used unless solicited, and the gesture SHOULD allow the receiver to choose the maximum size of a batch. The receiver of the event can distinguish between the three modes by inspecting the `Content-Type` header value. If the value is prefixed with the CloudEvents media type `application/cloudevents` (matched case-insensitively), indicating the use of a known , the receiver uses structured mode. If the value is prefixed with `application/cloudevents-batch`, the receiver uses the batched mode. Otherwise it defaults to binary mode. If a receiver detects the CloudEvents media type, but with an event format that it cannot handle, for instance `application/cloudevents+avro`, it MAY still treat the event as binary and forward it to another party as-is. When the `Content-Type` header value is not prefixed with the CloudEvents media type, knowing when the message ought to be parsed as a CloudEvent can be a challenge. While this specification can not mandate that senders do not include any of the CloudEvents HTTP headers when the message is not a CloudEvent, it would be reasonable for a receiver to assume that if the message has all of the mandatory CloudEvents attributes as HTTP headers then it's probably a CloudEvent. However, as with all CloudEvent messages, if it does not adhere to all of the normative language of this specification then it is not a valid CloudEvent. The binary content mode accommodates any shape of event data, and allows for efficient transfer and without transcoding effort. For the binary mode, the HTTP `Content-Type` header value corresponds to (MUST be populated from or written to) the CloudEvents `datacontenttype` attribute. Note that a `ce-datacontenttype` HTTP header MUST NOT also be present in the message. The byte-sequence is used as the HTTP message body. All other attributes, including extensions, MUST be individually mapped to and from distinct HTTP message header. CloudEvents extensions that define their own attributes MAY define a secondary mapping to HTTP headers for those attributes, especially if specific attributes need to align with HTTP features or with other specifications that have explicit HTTP header bindings. Note that these attributes MUST also still appear in the HTTP message as HTTP headers with the `ce-` prefix as noted in . Except where noted, all CloudEvents context attributes, including extensions, MUST be mapped to HTTP headers with the same name as the attribute name but prefixed with `ce-`. Examples: `time` maps to `ce-time` `id` maps to `ce-id` `specversion` maps to `ce-specversion` Note: per the specification, header names are case-insensitive. The value for each HTTP header is constructed from the respective attribute type's . Some CloudEvents metadata attributes can contain arbitrary UTF-8 string content, and per , HTTP headers MUST only use printable characters from the US-ASCII character set, and are terminated by a CRLF sequence with OPTIONAL whitespace around the header

When encoding a CloudEvent as an HTTP message, string values represented as HTTP header values MUST be percent-encoded as described below. This is compatible with [RFC3986, section 2.1][rfc3986-section-2-1] but is more specific about what needs encoding. The resulting string SHOULD NOT be further encoded. (Rationale: quoted string escaping is unnecessary when every space and double-quote character is already percent-encoded.) When decoding an HTTP message into a CloudEvent, any HTTP header value MUST first be unescaped with respect to double-quoted strings, as described in . A single round of percent-decoding MUST then be performed as described below. HTTP headers for CloudEvent attribute values do not support parenthetical comments, so the initial unescaping only needs to handle double-quoted values, including processing backslash escapes within double-quoted values. Header values produced via the percent-encoding described here will never include double-quoted values, but they MUST be supported when receiving events, for compatibility with older versions of this specification which did not require double-quote and space characters to be percent-encoded. Percent encoding is performed by considering each Unicode character within the attribute's canonical string representation. Any character represented in memory as a [Unicode surrogate pair][surrogate-pair] MUST be treated as a single Unicode character. The following characters MUST be percent-encoded: Space (U+0020) Double-quote (U+0022) Percent (U+0025) Any characters outside the printable ASCII range of U+0021-U+007E inclusive Attribute values are already constrained to prohibit characters in the range U+0000-U+001F inclusive and U+007F-U+009F inclusive; however for simplicity and to account for potential future changes, it is RECOMMENDED that any HTTP header encoding implementation treats such characters as requiring percent-encoding. Space and double-quote are encoded to avoid requiring any further quoting. Percent is encoded to avoid ambiguity with percent-encoding itself. Steps to encode a Unicode character: Encode the character using UTF-8, to obtain a byte sequence. Encode each byte within the sequence as `%xy` where `x` is a hexadecimal representation of the most significant 4 bits of the byte, and `y` is a hexadecimal representation of the least significant 4 bits of the byte. Percent-encoding SHOULD be performed using upper-case for values A-F, but decoding MUST accept lower-case values. When performing percent-decoding (when decoding an HTTP message to a CloudEvent), values that have been unnecessarily percent-encoded MUST be accepted, but encoded byte sequences which are invalid in UTF-8 MUST be rejected. (For example, "%C0%A0" is an overlong encoding of U+0020, and MUST be rejected.) Example: a header value of "Euro &#x20AC; &#x1F600;" SHOULD be encoded as follows: The characters, 'E', 'u', 'r', 'o' do not require encoding Space, the Euro symbol, and the grinning face emoji require encoding. They are characters U+0020, U+20AC and U+1F600 respectively. The encoded HTTP header value is therefore "Euro%20%E2%82%AC%20%F0%9F%98%80" where "%20" is the encoded form of space, "%E2%82%AC" is the encoded form of the Euro symbol, and "%F0%9F%98%80" is the encoded form of the grinning face emoji. This example shows the binary mode mapping of an event with an HTTP POST request: ```text POST /someresource HTTP/1.1 Host: webhook.example.com ce-specversion: 1.0 ce-type: com.example.someevent ce-time: 2018-04-05T03:56:24Z ce-id: 1234-1234-1234 ce-source: /mycontext/subcontext .... further attributes ... Content-Type: application/json; charset=utf-8 Content-Length: nnnn { ... application data ... } ``` This example shows a response containing an event: ```text HTTP/1.1 200 OK ce-specversion: 1.0 ce-type:

ce-time: 2018-04-05T03:56:24Z ce-id: 1234-1234-1234 ce-source: /mycontext/subcontext .... further attributes ... Content-Type: application/json; charset=utf-8 Content-Length: nnnn { ... application data ... } ``` The structured content mode keeps event metadata and data together in the payload, allowing simple forwarding of the same event across multiple routing hops, and across multiple protocols. The header MUST be set to the media type of an . Example for the : ```text Content-Type: application/cloudevents+json; charset=UTF-8 ``` The chosen defines how all attributes, and `data`, are represented. The event metadata and data is then rendered in accordance with the event format specification and the resulting data becomes the HTTP message body. Implementations MAY include the same HTTP headers as defined for the . All CloudEvents metadata attributes MUST be mapped into the payload, even if they are also mapped into HTTP headers. This example shows a JSON event format encoded event, sent with a PUT request: ```text PUT /myresource HTTP/1.1 Host: webhook.example.com Content-Type: application/cloudevents+json; charset=utf-8 Content-Length: nnnn { "specversion" : "1.0", "type" : "com.example.someevent", ... further attributes omitted ... "data" : { ... application data ... } } ``` This example shows a JSON encoded event returned in a response: ```text HTTP/1.1 200 OK Content-Type: application/cloudevents+json; charset=utf-8 Content-Length: nnnn { "specversion" : "1.0", "type" : "com.example.someevent", ... further attributes omitted ... "data" : { ... application data ... } } ``` In the batched content mode several events are batched into a single HTTP request or response body. The chosen MUST define how a batch is represented, including a suitable media type. The header MUST be set to the media type of the batch mode for the . Example for the : ```text Content-Type: application/cloudevents-batch+json; charset=UTF-8 ``` The chosen defines how a batch of events and all event attributes, and `data`, are represented. The batch of events is then rendered in accordance with the event format specification and the resulting data becomes the HTTP message body. This example shows two batched CloudEvents, sent with a PUT request: ```text PUT /myresource HTTP/1.1 Host: webhook.example.com Content-Type: application/cloudevents-batch+json; charset=utf-8 Content-Length: nnnn [ { "specversion" : "1.0", "type" : "com.example.someevent", ... further attributes omitted ... "data" : { ... application data ... } }, { "specversion" : "1.0", "type" : "com.example.someotherevent", ... further attributes omitted ... "data" : { ... application data ... } } ] ``` This example shows two batched CloudEvents returned in a response: ```text HTTP/1.1 200 OK Content-Type: application/cloudevents-batch+json; charset=utf-8 Content-Length: nnnn [ { "specversion" : "1.0", "type" : "com.example.someevent", ... further attributes omitted ... "data" : { ... application data ... } }, { "specversion" : "1.0", "type" : "com.example.someotherevent", ... further attributes omitted ... "data" : { ... application data ... } } ] ``` Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types Key words for use in RFCs to Indicate Requirement Levels HTTP over TLS UTF-8, a transformation format of ISO 10646 Uniform Resource Identifier (URI): Generic Syntax The application/json Media Type for JavaScript Object Notation (JSON) The Base16, Base32, and Base64 Data Encodings Additional Media Type Structured Syntax Suffixes The JavaScript Object Notation (JSON) Data Interchange Format Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content Hypertext Transfer Protocol Version 2 (HTTP/2)