5. Request/Response Semantics
CoAP operates under a similar request/response model as HTTP: a CoAP endpoint in the role of a "client" sends one or more CoAP requests to a "server", which services the requests by sending CoAP responses. Unlike HTTP, requests and responses are not sent over a previously established connection but are exchanged asynchronously over CoAP messages.5.1. Requests
A CoAP request consists of the method to be applied to the resource, the identifier of the resource, a payload and Internet media type (if any), and optional metadata about the request. CoAP supports the basic methods of GET, POST, PUT, and DELETE, which are easily mapped to HTTP. They have the same properties of safe (only retrieval) and idempotent (you can invoke it multiple times with the same effects) as HTTP (see Section 9.1 of [RFC2616]). The GET method is safe; therefore, it MUST NOT take any other action on a resource other than retrieval. The GET, PUT, and DELETE methods MUST be performed in such a way that they are idempotent. POST is not idempotent, because its effect is determined by the origin server and dependent on the target resource; it usually results in a new resource being created or the target resource being updated. A request is initiated by setting the Code field in the CoAP header of a Confirmable or a Non-confirmable message to a Method Code and including request information. The methods used in requests are described in detail in Section 5.8.5.2. Responses
After receiving and interpreting a request, a server responds with a CoAP response that is matched to the request by means of a client- generated token (Section 5.3); note that this is different from the Message ID that matches a Confirmable message to its Acknowledgement. A response is identified by the Code field in the CoAP header being set to a Response Code. Similar to the HTTP Status Code, the CoAP Response Code indicates the result of the attempt to understand and satisfy the request. These codes are fully defined in Section 5.9. The Response Code numbers to be set in the Code field of the CoAP header are maintained in the CoAP Response Code Registry (Section 12.1.2).
0 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ |class| detail | +-+-+-+-+-+-+-+-+ Figure 9: Structure of a Response Code The upper three bits of the 8-bit Response Code number define the class of response. The lower five bits do not have any categorization role; they give additional detail to the overall class (Figure 9). As a human-readable notation for specifications and protocol diagnostics, CoAP code numbers including the Response Code are documented in the format "c.dd", where "c" is the class in decimal, and "dd" is the detail as a two-digit decimal. For example, "Forbidden" is written as 4.03 -- indicating an 8-bit code value of hexadecimal 0x83 (4*0x20+3) or decimal 131 (4*32+3). There are 3 classes of Response Codes: 2 - Success: The request was successfully received, understood, and accepted. 4 - Client Error: The request contains bad syntax or cannot be fulfilled. 5 - Server Error: The server failed to fulfill an apparently valid request. The Response Codes are designed to be extensible: Response Codes in the Client Error or Server Error class that are unrecognized by an endpoint are treated as being equivalent to the generic Response Code of that class (4.00 and 5.00, respectively). However, there is no generic Response Code indicating success, so a Response Code in the Success class that is unrecognized by an endpoint can only be used to determine that the request was successful without any further details. The possible Response Codes are described in detail in Section 5.9. Responses can be sent in multiple ways, which are defined in the following subsections.
5.2.1. Piggybacked
In the most basic case, the response is carried directly in the Acknowledgement message that acknowledges the request (which requires that the request was carried in a Confirmable message). This is called a "Piggybacked Response". The response is returned in the Acknowledgement message, independent of whether the response indicates success or failure. In effect, the response is piggybacked on the Acknowledgement message, and no separate message is required to return the response. Implementation Note: The protocol leaves the decision whether to piggyback a response or not (i.e., send a separate response) to the server. The client MUST be prepared to receive either. On the quality-of-implementation level, there is a strong expectation that servers will implement code to piggyback whenever possible -- saving resources in the network and both at the client and at the server.5.2.2. Separate
It may not be possible to return a piggybacked response in all cases. For example, a server might need longer to obtain the representation of the resource requested than it can wait to send back the Acknowledgement message, without risking the client repeatedly retransmitting the request message (see also the discussion of PROCESSING_DELAY in Section 4.8.2). The response to a request carried in a Non-confirmable message is always sent separately (as there is no Acknowledgement message). One way to implement this in a server is to initiate the attempt to obtain the resource representation and, while that is in progress, time out an acknowledgement timer. A server may also immediately send an acknowledgement if it knows in advance that there will be no piggybacked response. In both cases, the acknowledgement effectively is a promise that the request will be acted upon later. When the server finally has obtained the resource representation, it sends the response. When it is desired that this message is not lost, it is sent as a Confirmable message from the server to the client and answered by the client with an Acknowledgement, echoing the new Message ID chosen by the server. (It may also be sent as a Non-confirmable message; see Section 5.2.3.) When the server chooses to use a separate response, it sends the Acknowledgement to the Confirmable request as an Empty message. Once the server sends back an Empty Acknowledgement, it MUST NOT send back
the response in another Acknowledgement, even if the client retransmits another identical request. If a retransmitted request is received (perhaps because the original Acknowledgement was delayed), another Empty Acknowledgement is sent, and any response MUST be sent as a separate response. If the server then sends a Confirmable response, the client's Acknowledgement to that response MUST also be an Empty message (one that carries neither a request nor a response). The server MUST stop retransmitting its response on any matching Acknowledgement (silently ignoring any Response Code or payload) or Reset message. Implementation Notes: Note that, as the underlying datagram transport may not be sequence-preserving, the Confirmable message carrying the response may actually arrive before or after the Acknowledgement message for the request; for the purposes of terminating the retransmission sequence, this also serves as an acknowledgement. Note also that, while the CoAP protocol itself does not make any specific demands here, there is an expectation that the response will come within a time frame that is reasonable from an application point of view. As there is no underlying transport protocol that could be instructed to run a keep-alive mechanism, the requester may want to set up a timeout that is unrelated to CoAP's retransmission timers in case the server is destroyed or otherwise unable to send the response.5.2.3. Non-confirmable
If the request message is Non-confirmable, then the response SHOULD be returned in a Non-confirmable message as well. However, an endpoint MUST be prepared to receive a Non-confirmable response (preceded or followed by an Empty Acknowledgement message) in reply to a Confirmable request, or a Confirmable response in reply to a Non-confirmable request.5.3. Request/Response Matching
Regardless of how a response is sent, it is matched to the request by means of a token that is included by the client in the request, along with additional address information of the corresponding endpoint.5.3.1. Token
The Token is used to match a response with a request. The token value is a sequence of 0 to 8 bytes. (Note that every message carries a token, even if it is of zero length.) Every request carries a client-generated token that the server MUST echo (without modification) in any resulting response.
A token is intended for use as a client-local identifier for differentiating between concurrent requests (see Section 5.3); it could have been called a "request ID". The client SHOULD generate tokens in such a way that tokens currently in use for a given source/destination endpoint pair are unique. (Note that a client implementation can use the same token for any request if it uses a different endpoint each time, e.g., a different source port number.) An empty token value is appropriate e.g., when no other tokens are in use to a destination, or when requests are made serially per destination and receive piggybacked responses. There are, however, multiple possible implementation strategies to fulfill this. A client sending a request without using Transport Layer Security (Section 9) SHOULD use a nontrivial, randomized token to guard against spoofing of responses (Section 11.4). This protective use of tokens is the reason they are allowed to be up to 8 bytes in size. The actual size of the random component to be used for the Token depends on the security requirements of the client and the level of threat posed by spoofing of responses. A client that is connected to the general Internet SHOULD use at least 32 bits of randomness, keeping in mind that not being directly connected to the Internet is not necessarily sufficient protection against spoofing. (Note that the Message ID adds little in protection as it is usually sequentially assigned, i.e., guessable, and can be circumvented by spoofing a separate response.) Clients that want to optimize the Token length may further want to detect the level of ongoing attacks (e.g., by tallying recent Token mismatches in incoming messages) and adjust the Token length upwards appropriately. [RFC4086] discusses randomness requirements for security. An endpoint receiving a token it did not generate MUST treat the token as opaque and make no assumptions about its content or structure.5.3.2. Request/Response Matching Rules
The exact rules for matching a response to a request are as follows: 1. The source endpoint of the response MUST be the same as the destination endpoint of the original request. 2. In a piggybacked response, the Message ID of the Confirmable request and the Acknowledgement MUST match, and the tokens of the response and original request MUST match. In a separate response, just the tokens of the response and original request MUST match.
In case a message carrying a response is unexpected (the client is not waiting for a response from the identified endpoint, at the endpoint addressed, and/or with the given token), the response is rejected (Sections 4.2 and 4.3). Implementation Note: A client that receives a response in a CON message may want to clean up the message state right after sending the ACK. If that ACK is lost and the server retransmits the CON, the client may no longer have any state to which to correlate this response, making the retransmission an unexpected message; the client will likely send a Reset message so it does not receive any more retransmissions. This behavior is normal and not an indication of an error. (Clients that are not aggressively optimized in their state memory usage will still have message state that will identify the second CON as a retransmission. Clients that actually expect more messages from the server [OBSERVE] will have to keep state in any case.)5.4. Options
Both requests and responses may include a list of one or more options. For example, the URI in a request is transported in several options, and metadata that would be carried in an HTTP header in HTTP is supplied as options as well. CoAP defines a single set of options that are used in both requests and responses: o Content-Format o ETag o Location-Path o Location-Query o Max-Age o Proxy-Uri o Proxy-Scheme o Uri-Host o Uri-Path o Uri-Port
o Uri-Query o Accept o If-Match o If-None-Match o Size1 The semantics of these options along with their properties are defined in detail in Section 5.10. Not all options are defined for use with all methods and Response Codes. The possible options for methods and Response Codes are defined in Sections 5.8 and 5.9, respectively. In case an option is not defined for a Method or Response Code, it MUST NOT be included by a sender and MUST be treated like an unrecognized option by a recipient.5.4.1. Critical/Elective
Options fall into one of two classes: "critical" or "elective". The difference between these is how an option unrecognized by an endpoint is handled: o Upon reception, unrecognized options of class "elective" MUST be silently ignored. o Unrecognized options of class "critical" that occur in a Confirmable request MUST cause the return of a 4.02 (Bad Option) response. This response SHOULD include a diagnostic payload describing the unrecognized option(s) (see Section 5.5.2). o Unrecognized options of class "critical" that occur in a Confirmable response, or piggybacked in an Acknowledgement, MUST cause the response to be rejected (Section 4.2). o Unrecognized options of class "critical" that occur in a Non- confirmable message MUST cause the message to be rejected (Section 4.3). Note that, whether critical or elective, an option is never "mandatory" (it is always optional): these rules are defined in order to enable implementations to stop processing options they do not understand or implement.
Critical/elective rules apply to non-proxying endpoints. A proxy processes options based on Unsafe/Safe-to-Forward classes as defined in Section 5.7.5.4.2. Proxy Unsafe or Safe-to-Forward and NoCacheKey
In addition to an option being marked as critical or elective, options are also classified based on how a proxy is to deal with the option if it does not recognize it. For this purpose, an option can either be considered Unsafe to forward (UnSafe is set) or Safe-to- Forward (UnSafe is clear). In addition, for an option that is marked Safe-to-Forward, the option number indicates whether or not it is intended to be part of the Cache-Key (Section 5.6) in a request. If some of the NoCacheKey bits are 0, it is; if all NoCacheKey bits are 1, it is not (see Section 5.4.6). Note: The Cache-Key indication is relevant only for proxies that do not implement the given option as a request option and instead rely on the Unsafe/Safe-to-Forward indication only. For example, for ETag, actually using the request option as a part of the Cache-Key is grossly inefficient, but it is the best thing one can do if ETag is not implemented by a proxy, as the response is going to differ based on the presence of the request option. A more useful proxy that does implement the ETag request option is not using ETag as a part of the Cache-Key. NoCacheKey is indicated in three bits so that only one out of eight codepoints is qualified as NoCacheKey, leaving seven out of eight codepoints for what appears to be the more likely case. Proxy behavior with regard to these classes is defined in Section 5.7.5.4.3. Length
Option values are defined to have a specific length, often in the form of an upper and lower bound. If the length of an option value in a request is outside the defined range, that option MUST be treated like an unrecognized option (see Section 5.4.1).5.4.4. Default Values
Options may be defined to have a default value. If the value of an option is intended to be this default value, the option SHOULD NOT be included in the message. If the option is not present, the default value MUST be assumed.
Where a critical option has a default value, this is chosen in such a way that the absence of the option in a message can be processed properly both by implementations unaware of the critical option and by implementations that interpret this absence as the presence of the default value for the option.5.4.5. Repeatable Options
The definition of some options specifies that those options are repeatable. An option that is repeatable MAY be included one or more times in a message. An option that is not repeatable MUST NOT be included more than once in a message. If a message includes an option with more occurrences than the option is defined for, each supernumerary option occurrence that appears subsequently in the message MUST be treated like an unrecognized option (see Section 5.4.1).5.4.6. Option Numbers
An Option is identified by an option number, which also provides some additional semantics information, e.g., odd numbers indicate a critical option, while even numbers indicate an elective option. Note that this is not just a convention, it is a feature of the protocol: Whether an option is elective or critical is entirely determined by whether its option number is even or odd. More generally speaking, an Option number is constructed with a bit mask to indicate if an option is Critical or Elective, Unsafe or Safe-to-Forward, and, in the case of Safe-to-Forward, to provide a Cache-Key indication as shown by the following figure. In the following text, the bit mask is expressed as a single byte that is applied to the least significant byte of the option number in unsigned integer representation. When bit 7 (the least significant bit) is 1, an option is Critical (and likewise Elective when 0). When bit 6 is 1, an option is Unsafe (and likewise Safe-to-Forward when 0). When bit 6 is 0, i.e., the option is not Unsafe, it is not a Cache-Key (NoCacheKey) if and only if bits 3-5 are all set to 1; all other bit combinations mean that it indeed is a Cache-Key. These classes of options are explained in the next sections. 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | | NoCacheKey| U | C | +---+---+---+---+---+---+---+---+ Figure 10: Option Number Mask (Least Significant Byte)
An endpoint may use an equivalent of the C code in Figure 11 to derive the characteristics of an option number "onum". Critical = (onum & 1); UnSafe = (onum & 2); NoCacheKey = ((onum & 0x1e) == 0x1c); Figure 11: Determining Characteristics from an Option Number The option numbers for the options defined in this document are listed in the "CoAP Option Numbers" registry (Section 12.2).5.5. Payloads and Representations
Both requests and responses may include a payload, depending on the Method or Response Code, respectively. If a Method or Response Code is not defined to have a payload, then a sender MUST NOT include one, and a recipient MUST ignore it.5.5.1. Representation
The payload of requests or of responses indicating success is typically a representation of a resource ("resource representation") or the result of the requested action ("action result"). Its format is specified by the Internet media type and content coding given by the Content-Format Option. In the absence of this option, no default value is assumed, and the format will need to be inferred by the application (e.g., from the application context). Payload "sniffing" SHOULD only be attempted if no content type is given. Implementation Note: On a quality-of-implementation level, there is a strong expectation that a Content-Format indication will be provided with resource representations whenever possible. This is not a "SHOULD" level requirement solely because it is not a protocol requirement, and it also would be difficult to outline exactly in what cases this expectation can be violated. For responses indicating a client or server error, the payload is considered a representation of the result of the requested action only if a Content-Format Option is given. In the absence of this option, the payload is a Diagnostic Payload (Section 5.5.2).
5.5.2. Diagnostic Payload
If no Content-Format option is given, the payload of responses indicating a client or server error is a brief human-readable diagnostic message, explaining the error situation. This diagnostic message MUST be encoded using UTF-8 [RFC3629], more specifically using Net-Unicode form [RFC5198]. The message is similar to the Reason-Phrase on an HTTP status line. It is not intended for end users but for software engineers that during debugging need to interpret it in the context of the present, English-language specification; therefore, no mechanism for language tagging is needed or provided. In contrast to what is usual in HTTP, the payload SHOULD be empty if there is no additional information beyond the Response Code.5.5.3. Selected Representation
Not all responses carry a payload that provides a representation of the resource addressed by the request. It is, however, sometimes useful to be able to refer to such a representation in relation to a response, independent of whether it actually was enclosed. We use the term "selected representation" to refer to the current representation of a target resource that would have been selected in a successful response if the corresponding request had used the method GET and excluded any conditional request options (Section 5.10.8). Certain response options provide metadata about the selected representation, which might differ from the representation included in the message for responses to some state-changing methods. Of the response options defined in this specification, only the ETag response option (Section 5.10.6) is defined as metadata about the selected representation.5.5.4. Content Negotiation
A server may be able to supply a representation for a resource in one of multiple representation formats. Without further information from the client, it will provide the representation in the format it prefers. By using the Accept Option (Section 5.10.4) in a request, the client can indicate which content-format it prefers to receive.
5.6. Caching
CoAP endpoints MAY cache responses in order to reduce the response time and network bandwidth consumption on future, equivalent requests. The goal of caching in CoAP is to reuse a prior response message to satisfy a current request. In some cases, a stored response can be reused without the need for a network request, reducing latency and network round-trips; a "freshness" mechanism is used for this purpose (see Section 5.6.1). Even when a new request is required, it is often possible to reuse the payload of a prior response to satisfy the request, thereby reducing network bandwidth usage; a "validation" mechanism is used for this purpose (see Section 5.6.2). Unlike HTTP, the cacheability of CoAP responses does not depend on the request method, but it depends on the Response Code. The cacheability of each Response Code is defined along the Response Code definitions in Section 5.9. Response Codes that indicate success and are unrecognized by an endpoint MUST NOT be cached. For a presented request, a CoAP endpoint MUST NOT use a stored response, unless: o the presented request method and that used to obtain the stored response match, o all options match between those in the presented request and those of the request used to obtain the stored response (which includes the request URI), except that there is no need for a match of any request options marked as NoCacheKey (Section 5.4) or recognized by the Cache and fully interpreted with respect to its specified cache behavior (such as the ETag request option described in Section 5.10.6; see also Section 5.4.2), and o the stored response is either fresh or successfully validated as defined below. The set of request options that is used for matching the cache entry is also collectively referred to as the "Cache-Key". For URI schemes other than coap and coaps, matching of those options that constitute the request URI may be performed under rules specific to the URI scheme.
5.6.1. Freshness Model
When a response is "fresh" in the cache, it can be used to satisfy subsequent requests without contacting the origin server, thereby improving efficiency. The mechanism for determining freshness is for an origin server to provide an explicit expiration time in the future, using the Max-Age Option (see Section 5.10.5). The Max-Age Option indicates that the response is to be considered not fresh after its age is greater than the specified number of seconds. The Max-Age Option defaults to a value of 60. Thus, if it is not present in a cacheable response, then the response is considered not fresh after its age is greater than 60 seconds. If an origin server wishes to prevent caching, it MUST explicitly include a Max-Age Option with a value of zero seconds. If a client has a fresh stored response and makes a new request matching the request for that stored response, the new response invalidates the old response.5.6.2. Validation Model
When an endpoint has one or more stored responses for a GET request, but cannot use any of them (e.g., because they are not fresh), it can use the ETag Option (Section 5.10.6) in the GET request to give the origin server an opportunity both to select a stored response to be used, and to update its freshness. This process is known as "validating" or "revalidating" the stored response. When sending such a request, the endpoint SHOULD add an ETag Option specifying the entity-tag of each stored response that is applicable. A 2.03 (Valid) response indicates the stored response identified by the entity-tag given in the response's ETag Option can be reused after updating it as described in Section 5.9.1.3. Any other Response Code indicates that none of the stored responses nominated in the request is suitable. Instead, the response SHOULD be used to satisfy the request and MAY replace the stored response.