A proxy is a CoAP endpoint that can be tasked by CoAP clients to
perform requests on their behalf. This may be useful, for example,
when the request could otherwise not be made, or to service the
response from a cache in order to reduce response time and network
bandwidth or energy consumption.
In an overall architecture for a Constrained RESTful Environment,
proxies can serve quite different purposes. Proxies can be
explicitly selected by clients, a role that we term "forward-proxy".
Proxies can also be inserted to stand in for origin servers, a role
that we term "reverse-proxy". Orthogonal to this distinction, a
proxy can map from a CoAP request to a CoAP request (CoAP-to-CoAP
proxy) or translate from or to a different protocol ("cross-proxy").
Full definitions of these terms are provided in Section 1.2.
Notes: The terminology in this specification has been selected to be
culturally compatible with the terminology used in the wider web
application environments, without necessarily matching it in every
detail (which may not even be relevant to Constrained RESTful
Environments). Not too much semantics should be ascribed to the
components of the terms (such as "forward", "reverse", or
HTTP proxies, besides acting as HTTP proxies, often offer a
transport-protocol proxying function ("CONNECT") to enable end-to-
end transport layer security through the proxy. No such function
is defined for CoAP-to-CoAP proxies in this specification, as
forwarding of UDP packets is unlikely to be of much value in
Constrained RESTful Environments. See also Section 10.2.7 for the
When a client uses a proxy to make a request that will use a secure
URI scheme (e.g., "coaps" or "https"), the request towards the proxy
SHOULD be sent using DTLS except where equivalent lower-layer
security is used for the leg between the client and the proxy.
5.7.1. Proxy Operation
A proxy generally needs a way to determine potential request
parameters for a request it places to a destination, based on the
request it received from its client. This way is fully specified for
a forward-proxy but may depend on the specific configuration for a
reverse-proxy. In particular, the client of a reverse-proxy
generally does not indicate a locator for the destination,
necessitating some form of namespace translation in the reverse-
proxy. However, some aspects of the operation of proxies are common
to all its forms.
If a proxy does not employ a cache, then it simply forwards the
translated request to the determined destination. Otherwise, if it
does employ a cache but does not have a stored response that matches
the translated request and is considered fresh, then it needs to
refresh its cache according to Section 5.6. For options in the
request that the proxy recognizes, it knows whether the option is
intended to act as part of the key used in looking up the cached
value or not. For example, since requests for different Uri-Path
values address different resources, Uri-Path values are always part
of the Cache-Key, while, e.g., Token values are never part of the
Cache-Key. For options that the proxy does not recognize but that
are marked Safe-to-Forward in the option number, the option also
indicates whether it is to be included in the Cache-Key (NoCacheKey
is not all set) or not (NoCacheKey is all set). (Options that are
unrecognized and marked Unsafe lead to 4.02 Bad Option.)
If the request to the destination times out, then a 5.04 (Gateway
Timeout) response MUST be returned. If the request to the
destination returns a response that cannot be processed by the proxy
(e.g, due to unrecognized critical options or message format errors),
then a 5.02 (Bad Gateway) response MUST be returned. Otherwise, the
proxy returns the response to the client.
If a response is generated out of a cache, the generated (or implied)
Max-Age Option MUST NOT extend the max-age originally set by the
server, considering the time the resource representation spent in the
cache. For example, the Max-Age Option could be adjusted by the
proxy for each response using the formula:
proxy-max-age = original-max-age - cache-age
For example, if a request is made to a proxied resource that was
refreshed 20 seconds ago and had an original Max-Age of 60 seconds,
then that resource's proxied max-age is now 40 seconds. Considering
potential network delays on the way from the origin server, a proxy
should be conservative in the max-age values offered.
All options present in a proxy request MUST be processed at the
proxy. Unsafe options in a request that are not recognized by the
proxy MUST lead to a 4.02 (Bad Option) response being returned by the
proxy. A CoAP-to-CoAP proxy MUST forward to the origin server all
Safe-to-Forward options that it does not recognize. Similarly,
Unsafe options in a response that are not recognized by the CoAP-to-
CoAP proxy server MUST lead to a 5.02 (Bad Gateway) response. Again,
Safe-to-Forward options that are not recognized MUST be forwarded.
Additional considerations for cross-protocol proxying between CoAP
and HTTP are discussed in Section 10.
CoAP distinguishes between requests made (as if) to an origin server
and requests made through a forward-proxy. CoAP requests to a
forward-proxy are made as normal Confirmable or Non-confirmable
requests to the forward-proxy endpoint, but they specify the request
URI in a different way: The request URI in a proxy request is
specified as a string in the Proxy-Uri Option (see Section 5.10.2),
while the request URI in a request to an origin server is split into
the Uri-Host, Uri-Port, Uri-Path, and Uri-Query Options (see
Section 5.10.1). Alternatively, the URI in a proxy request can be
assembled from a Proxy-Scheme option and the split options mentioned.
When a proxy request is made to an endpoint and the endpoint is
unwilling or unable to act as proxy for the request URI, it MUST
return a 5.05 (Proxying Not Supported) response. If the authority
(host and port) is recognized as identifying the proxy endpoint
itself (see Section 5.10.2), then the request MUST be treated as a
local (non-proxied) request.
Unless a proxy is configured to forward the proxy request to another
proxy, it MUST translate the request as follows: the scheme of the
request URI defines the outgoing protocol and its details (e.g., CoAP
is used over UDP for the "coap" scheme and over DTLS for the "coaps"
scheme.) For a CoAP-to-CoAP proxy, the origin server's IP address
and port are determined by the authority component of the request
URI, and the request URI is decoded and split into the Uri-Host, Uri-
Port, Uri-Path and Uri-Query Options. This consumes the Proxy-Uri or
Proxy-Scheme option, which is therefore not forwarded to the origin
Reverse-proxies do not make use of the Proxy-Uri or Proxy-Scheme
options but need to determine the destination (next hop) of a request
from information in the request and information in their
configuration. For example, a reverse-proxy might offer various
resources as if they were its own resources, after having learned of
their existence through resource discovery. The reverse-proxy is
free to build a namespace for the URIs that identify these resources.
A reverse-proxy may also build a namespace that gives the client more
control over where the request goes, e.g., by embedding host
identifiers and port numbers into the URI path of the resources
In processing the response, a reverse-proxy has to be careful that
ETag option values from different sources are not mixed up on one
resource offered to its clients. In many cases, the ETag can be
forwarded unchanged. If the mapping from a resource offered by the
reverse-proxy to resources offered by its various origin servers is
not unique, the reverse-proxy may need to generate a new ETag, making
sure the semantics of this option are properly preserved.
5.8. Method Definitions
In this section, each method is defined along with its behavior. A
request with an unrecognized or unsupported Method Code MUST generate
a 4.05 (Method Not Allowed) piggybacked response.
The GET method retrieves a representation for the information that
currently corresponds to the resource identified by the request URI.
If the request includes an Accept Option, that indicates the
preferred content-format of a response. If the request includes an
ETag Option, the GET method requests that ETag be validated and that
the representation be transferred only if validation failed. Upon
success, a 2.05 (Content) or 2.03 (Valid) Response Code SHOULD be
present in the response.
The GET method is safe and idempotent.
The POST method requests that the representation enclosed in the
request be processed. The actual function performed by the POST
method 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.
If a resource has been created on the server, the response returned
by the server SHOULD have a 2.01 (Created) Response Code and SHOULD
include the URI of the new resource in a sequence of one or more
Location-Path and/or Location-Query Options (Section 5.10.7). If the
POST succeeds but does not result in a new resource being created on
the server, the response SHOULD have a 2.04 (Changed) Response Code.
If the POST succeeds and results in the target resource being
deleted, the response SHOULD have a 2.02 (Deleted) Response Code.
POST is neither safe nor idempotent.
The PUT method requests that the resource identified by the request
URI be updated or created with the enclosed representation. The
representation format is specified by the media type and content
coding given in the Content-Format Option, if provided.
If a resource exists at the request URI, the enclosed representation
SHOULD be considered a modified version of that resource, and a 2.04
(Changed) Response Code SHOULD be returned. If no resource exists,
then the server MAY create a new resource with that URI, resulting in
a 2.01 (Created) Response Code. If the resource could not be created
or modified, then an appropriate error Response Code SHOULD be sent.
Further restrictions to a PUT can be made by including the If-Match
(see Section 126.96.36.199) or If-None-Match (see Section 188.8.131.52)
options in the request.
PUT is not safe but is idempotent.
The DELETE method requests that the resource identified by the
request URI be deleted. A 2.02 (Deleted) Response Code SHOULD be
used on success or in case the resource did not exist before the
DELETE is not safe but is idempotent.
5.9. Response Code Definitions
Each Response Code is described below, including any options required
in the response. Where appropriate, some of the codes will be
specified in regards to related Response Codes in HTTP [RFC2616];
this does not mean that any such relationship modifies the HTTP
mapping specified in Section 10.
5.9.1. Success 2.xx
This class of Response Code indicates that the clients request was
successfully received, understood, and accepted.
184.108.40.206. 2.01 Created
Like HTTP 201 "Created", but only used in response to POST and PUT
requests. The payload returned with the response, if any, is a
representation of the action result.
If the response includes one or more Location-Path and/or Location-
Query Options, the values of these options specify the location at
which the resource was created. Otherwise, the resource was created
at the request URI. A cache receiving this response MUST mark any
stored response for the created resource as not fresh.
This response is not cacheable.
220.127.116.11. 2.02 Deleted
This Response Code is like HTTP 204 "No Content" but only used in
response to requests that cause the resource to cease being
available, such as DELETE and, in certain circumstances, POST. The
payload returned with the response, if any, is a representation of
the action result.
This response is not cacheable. However, a cache MUST mark any
stored response for the deleted resource as not fresh.
18.104.22.168. 2.03 Valid
This Response Code is related to HTTP 304 "Not Modified" but only
used to indicate that the response identified by the entity-tag
identified by the included ETag Option is valid. Accordingly, the
response MUST include an ETag Option and MUST NOT include a payload.
When a cache that recognizes and processes the ETag response option
receives a 2.03 (Valid) response, it MUST update the stored response
with the value of the Max-Age Option included in the response
(explicitly, or implicitly as a default value; see also
Section 5.6.2). For each type of Safe-to-Forward option present in
the response, the (possibly empty) set of options of this type that
are present in the stored response MUST be replaced with the set of
options of this type in the response received. (Unsafe options may
trigger similar option-specific processing as defined by the option.)
22.214.171.124. 2.04 Changed
This Response Code is like HTTP 204 "No Content" but only used in
response to POST and PUT requests. The payload returned with the
response, if any, is a representation of the action result.
This response is not cacheable. However, a cache MUST mark any
stored response for the changed resource as not fresh.
126.96.36.199. 2.05 Content
This Response Code is like HTTP 200 "OK" but only used in response to
The payload returned with the response is a representation of the
This response is cacheable: Caches can use the Max-Age Option to
determine freshness (see Section 5.6.1) and (if present) the ETag
Option for validation (see Section 5.6.2).
5.9.2. Client Error 4.xx
This class of Response Code is intended for cases in which the client
seems to have erred. These Response Codes are applicable to any
The server SHOULD include a diagnostic payload under the conditions
detailed in Section 5.5.2.
Responses of this class are cacheable: Caches can use the Max-Age
Option to determine freshness (see Section 5.6.1). They cannot be
188.8.131.52. 4.00 Bad Request
This Response Code is Like HTTP 400 "Bad Request".
184.108.40.206. 4.01 Unauthorized
The client is not authorized to perform the requested action. The
client SHOULD NOT repeat the request without first improving its
authentication status to the server. Which specific mechanism can be
used for this is outside this document's scope; see also Section 9.
220.127.116.11. 4.02 Bad Option
The request could not be understood by the server due to one or more
unrecognized or malformed options. The client SHOULD NOT repeat the
request without modification.
18.104.22.168. 4.03 Forbidden
This Response Code is like HTTP 403 "Forbidden".
22.214.171.124. 5.01 Not Implemented
This Response Code is like HTTP 501 "Not Implemented".
126.96.36.199. 5.02 Bad Gateway
This Response Code is like HTTP 502 "Bad Gateway".
188.8.131.52. 5.03 Service Unavailable
This Response Code is like HTTP 503 "Service Unavailable" but uses
the Max-Age Option in place of the "Retry-After" header field to
indicate the number of seconds after which to retry.
184.108.40.206. 5.04 Gateway Timeout
This Response Code is like HTTP 504 "Gateway Timeout".
220.127.116.11. 5.05 Proxying Not Supported
The server is unable or unwilling to act as a forward-proxy for the
URI specified in the Proxy-Uri Option or using Proxy-Scheme (see
5.10. Option Definitions
The individual CoAP options are summarized in Table 4 and explained
in the subsections of this section.
In this table, the C, U, and N columns indicate the properties
Critical, UnSafe, and NoCacheKey, respectively. Since NoCacheKey
only has a meaning for options that are Safe-to-Forward (not marked
Unsafe), the column is filled with a dash for UnSafe options.
| No. | C | U | N | R | Name | Format | Length | Default |
| 1 | x | | | x | If-Match | opaque | 0-8 | (none) |
| 3 | x | x | - | | Uri-Host | string | 1-255 | (see |
| | | | | | | | | below) |
| 4 | | | | x | ETag | opaque | 1-8 | (none) |
| 5 | x | | | | If-None-Match | empty | 0 | (none) |
| 7 | x | x | - | | Uri-Port | uint | 0-2 | (see |
| | | | | | | | | below) |
| 8 | | | | x | Location-Path | string | 0-255 | (none) |
| 11 | x | x | - | x | Uri-Path | string | 0-255 | (none) |
| 12 | | | | | Content-Format | uint | 0-2 | (none) |
| 14 | | x | - | | Max-Age | uint | 0-4 | 60 |
| 15 | x | x | - | x | Uri-Query | string | 0-255 | (none) |
| 17 | x | | | | Accept | uint | 0-2 | (none) |
| 20 | | | | x | Location-Query | string | 0-255 | (none) |
| 35 | x | x | - | | Proxy-Uri | string | 1-1034 | (none) |
| 39 | x | x | - | | Proxy-Scheme | string | 1-255 | (none) |
| 60 | | | x | | Size1 | uint | 0-4 | (none) |
C=Critical, U=Unsafe, N=NoCacheKey, R=Repeatable
Table 4: Options5.10.1. Uri-Host, Uri-Port, Uri-Path, and Uri-Query
The Uri-Host, Uri-Port, Uri-Path, and Uri-Query Options are used to
specify the target resource of a request to a CoAP origin server.
The options encode the different components of the request URI in a
way that no percent-encoding is visible in the option values and that
the full URI can be reconstructed at any involved endpoint. The
syntax of CoAP URIs is defined in Section 6.
The steps for parsing URIs into options is defined in Section 6.4.
These steps result in zero or more Uri-Host, Uri-Port, Uri-Path, and
Uri-Query Options being included in a request, where each option
holds the following values:
o the Uri-Host Option specifies the Internet host of the resource
o the Uri-Port Option specifies the transport-layer port number of
o each Uri-Path Option specifies one segment of the absolute path to
the resource, and
o each Uri-Query Option specifies one argument parameterizing the
Note: Fragments ([RFC3986], Section 3.5) are not part of the request
URI and thus will not be transmitted in a CoAP request.
The default value of the Uri-Host Option is the IP literal
representing the destination IP address of the request message.
Likewise, the default value of the Uri-Port Option is the destination
UDP port. The default values for the Uri-Host and Uri-Port Options
are sufficient for requests to most servers. Explicit Uri-Host and
Uri-Port Options are typically used when an endpoint hosts multiple
The Uri-Path and Uri-Query Option can contain any character sequence.
No percent-encoding is performed. The value of a Uri-Path Option
MUST NOT be "." or ".." (as the request URI must be resolved before
parsing it into options).
The steps for constructing the request URI from the options are
defined in Section 6.5. Note that an implementation does not
necessarily have to construct the URI; it can simply look up the
target resource by examining the individual options.
Examples can be found in Appendix B.
5.10.2. Proxy-Uri and Proxy-Scheme
The Proxy-Uri Option is used to make a request to a forward-proxy
(see Section 5.7). The forward-proxy is requested to forward the
request or service it from a valid cache and return the response.
The option value is an absolute-URI ([RFC3986], Section 4.3).
Note that the forward-proxy MAY forward the request on to another
proxy or directly to the server specified by the absolute-URI. In
order to avoid request loops, a proxy MUST be able to recognize all
of its server names, including any aliases, local variations, and the
numeric IP addresses.
An endpoint receiving a request with a Proxy-Uri Option that is
unable or unwilling to act as a forward-proxy for the request MUST
cause the return of a 5.05 (Proxying Not Supported) response.
The Proxy-Uri Option MUST take precedence over any of the Uri-Host,
Uri-Port, Uri-Path or Uri-Query options (each of which MUST NOT be
included in a request containing the Proxy-Uri Option).
As a special case to simplify many proxy clients, the absolute-URI
can be constructed from the Uri-* options. When a Proxy-Scheme
Option is present, the absolute-URI is constructed as follows: a CoAP
URI is constructed from the Uri-* options as defined in Section 6.5.
In the resulting URI, the initial scheme up to, but not including,
the following colon is then replaced by the content of the Proxy-
Scheme Option. Note that this case is only applicable if the
components of the desired URI other than the scheme component
actually can be expressed using Uri-* options; for example, to
represent a URI with a userinfo component in the authority, only
Proxy-Uri can be used.
The Content-Format Option indicates the representation format of the
message payload. The representation format is given as a numeric
Content-Format identifier that is defined in the "CoAP Content-
Formats" registry (Section 12.3). In the absence of the option, no
default value is assumed, i.e., the representation format of any
representation message payload is indeterminate (Section 5.5).
The CoAP Accept option can be used to indicate which Content-Format
is acceptable to the client. The representation format is given as a
numeric Content-Format identifier that is defined in the "CoAP
Content-Formats" registry (Section 12.3). If no Accept option is
given, the client does not express a preference (thus no default
value is assumed). The client prefers the representation returned by
the server to be in the Content-Format indicated. The server returns
the preferred Content-Format if available. If the preferred Content-
Format cannot be returned, then a 4.06 "Not Acceptable" MUST be sent
as a response, unless another error code takes precedence for this
The Max-Age Option indicates the maximum time a response may be
cached before it is considered not fresh (see Section 5.6.1).
The option value is an integer number of seconds between 0 and
2**32-1 inclusive (about 136.1 years). A default value of 60 seconds
is assumed in the absence of the option in a response.
The value is intended to be current at the time of transmission.
Servers that provide resources with strict tolerances on the value of
Max-Age SHOULD update the value before each retransmission. (See
also Section 5.7.1.)
An entity-tag is intended for use as a resource-local identifier for
differentiating between representations of the same resource that
vary over time. It is generated by the server providing the
resource, which may generate it in any number of ways including a
version, checksum, hash, or time. An endpoint receiving an entity-
tag MUST treat it as opaque and make no assumptions about its content
or structure. (Endpoints that generate an entity-tag are encouraged
to use the most compact representation possible, in particular in
regards to clients and intermediaries that may want to store multiple
18.104.22.168. ETag as a Response Option
The ETag Option in a response provides the current value (i.e., after
the request was processed) of the entity-tag for the "tagged
representation". If no Location-* options are present, the tagged
representation is the selected representation (Section 5.5.3) of the
target resource. If one or more Location-* options are present and
thus a location URI is indicated (Section 5.10.7), the tagged
representation is the representation that would be retrieved by a GET
request to the location URI.
An ETag response option can be included with any response for which
there is a tagged representation (e.g., it would not be meaningful in
a 4.04 or 4.00 response). The ETag Option MUST NOT occur more than
once in a response.
There is no default value for the ETag Option; if it is not present
in a response, the server makes no statement about the entity-tag for
the tagged representation.
22.214.171.124. ETag as a Request Option
In a GET request, an endpoint that has one or more representations
previously obtained from the resource, and has obtained ETag response
options with these, can specify an instance of the ETag Option for
one or more of these stored responses.
A server can issue a 2.03 Valid response (Section 126.96.36.199) in place
of a 2.05 Content response if one of the ETags given is the entity-
tag for the current representation, i.e., is valid; the 2.03 Valid
response then echoes this specific ETag in a response option.
In effect, a client can determine if any of the stored
representations is current (see Section 5.6.2) without needing to
transfer them again.
The ETag Option MAY occur zero, one, or multiple times in a request.
5.10.7. Location-Path and Location-Query
The Location-Path and Location-Query Options together indicate a
relative URI that consists either of an absolute path, a query
string, or both. A combination of these options is included in a
2.01 (Created) response to indicate the location of the resource
created as the result of a POST request (see Section 5.8.2). The
location is resolved relative to the request URI.
If a response with one or more Location-Path and/or Location-Query
Options passes through a cache that interprets these options and the
implied URI identifies one or more currently stored responses, those
entries MUST be marked as not fresh.
Each Location-Path Option specifies one segment of the absolute path
to the resource, and each Location-Query Option specifies one
argument parameterizing the resource. The Location-Path and
Location-Query Option can contain any character sequence. No
percent-encoding is performed. The value of a Location-Path Option
MUST NOT be "." or "..".
The steps for constructing the location URI from the options are
analogous to Section 6.5, except that the first five steps are
skipped and the result is a relative URI-reference, which is then
interpreted relative to the request URI. Note that the relative URI-
reference constructed this way always includes an absolute path
(e.g., leaving out Location-Path but supplying Location-Query means
the path component in the URI is "/").
The options that are used to compute the relative URI-reference are
collectively called Location-* options. Beyond Location-Path and
Location-Query, more Location-* options may be defined in the future
and have been reserved option numbers 128, 132, 136, and 140. If any
of these reserved option numbers occurs in addition to Location-Path
and/or Location-Query and are not supported, then a 4.02 (Bad Option)
error MUST be returned.
5.10.8. Conditional Request Options
Conditional request options enable a client to ask the server to
perform the request only if certain conditions specified by the
option are fulfilled.
For each of these options, if the condition given is not fulfilled,
then the server MUST NOT perform the requested method. Instead, the
server MUST respond with the 4.12 (Precondition Failed) Response
If the condition is fulfilled, the server performs the request method
as if the conditional request options were not present.
If the request would, without the conditional request options, result
in anything other than a 2.xx or 4.12 Response Code, then any
conditional request options MAY be ignored.
The If-Match Option MAY be used to make a request conditional on the
current existence or value of an ETag for one or more representations
of the target resource. If-Match is generally useful for resource
update requests, such as PUT requests, as a means for protecting
against accidental overwrites when multiple clients are acting in
parallel on the same resource (i.e., the "lost update" problem).
The value of an If-Match option is either an ETag or the empty
string. An If-Match option with an ETag matches a representation
with that exact ETag. An If-Match option with an empty value matches
any existing representation (i.e., it places the precondition on the
existence of any current representation for the target resource).
The If-Match Option can occur multiple times. If any of the options
match, then the condition is fulfilled.
If there is one or more If-Match Options, but none of the options
match, then the condition is not fulfilled.
The If-None-Match Option MAY be used to make a request conditional on
the nonexistence of the target resource. If-None-Match is useful for
resource creation requests, such as PUT requests, as a means for
protecting against accidental overwrites when multiple clients are
acting in parallel on the same resource. The If-None-Match Option
carries no value.
If the target resource does exist, then the condition is not
(It is not very useful to combine If-Match and If-None-Match options
in one request, because the condition will then never be fulfilled.)
5.10.9. Size1 Option
The Size1 option provides size information about the resource
representation in a request. The option value is an integer number
of bytes. Its main use is with block-wise transfers [BLOCK]. In the
present specification, it is used in 4.13 responses (Section 188.8.131.52)
to indicate the maximum size of request entity that the server is
able and willing to handle.
6. CoAP URIs
CoAP uses the "coap" and "coaps" URI schemes for identifying CoAP
resources and providing a means of locating the resource. Resources
are organized hierarchically and governed by a potential CoAP origin
server listening for CoAP requests ("coap") or DTLS-secured CoAP
requests ("coaps") on a given UDP port. The CoAP server is
identified via the generic syntax's authority component, which
includes a host component and optional UDP port number. The
remainder of the URI is considered to be identifying a resource that
can be operated on by the methods defined by the CoAP protocol. The
"coap" and "coaps" URI schemes can thus be compared to the "http" and
"https" URI schemes, respectively.
The syntax of the "coap" and "coaps" URI schemes is specified in this
section in Augmented Backus-Naur Form (ABNF) [RFC5234]. The
definitions of "host", "port", "path-abempty", "query", "segment",
"IP-literal", "IPv4address", and "reg-name" are adopted from
Implementation Note: Unfortunately, over time, the URI format has
acquired significant complexity. Implementers are encouraged to
examine [RFC3986] closely. For example, the ABNF for IPv6
addresses is more complicated than maybe expected. Also,
implementers should take care to perform the processing of
percent-decoding or percent-encoding exactly once on the way from
a URI to its decoded components or back. Percent-encoding is
crucial for data transparency but may lead to unusual results such
as a slash character in a path component.
6.1. coap URI Scheme
coap-URI = "coap:" "//" host [ ":" port ] path-abempty [ "?" query ]
If the host component is provided as an IP-literal or IPv4address,
then the CoAP server can be reached at that IP address. If host is a
registered name, then that name is considered an indirect identifier
and the endpoint might use a name resolution service, such as DNS, to
find the address of that host. The host MUST NOT be empty; if a URI
is received with a missing authority or an empty host, then it MUST
be considered invalid. The port subcomponent indicates the UDP port
at which the CoAP server is located. If it is empty or not given,
then the default port 5683 is assumed.
The path identifies a resource within the scope of the host and port.
It consists of a sequence of path segments separated by a slash
character (U+002F SOLIDUS "/").
The query serves to further parameterize the resource. It consists
of a sequence of arguments separated by an ampersand character
(U+0026 AMPERSAND "&"). An argument is often in the form of a
The "coap" URI scheme supports the path prefix "/.well-known/"
defined by [RFC5785] for "well-known locations" in the namespace of a
host. This enables discovery of policy or other information about a
host ("site-wide metadata"), such as hosted resources (see
Application designers are encouraged to make use of short but
descriptive URIs. As the environments that CoAP is used in are
usually constrained for bandwidth and energy, the trade-off between
these two qualities should lean towards the shortness, without
6.2. coaps URI Scheme
coaps-URI = "coaps:" "//" host [ ":" port ] path-abempty
[ "?" query ]
All of the requirements listed above for the "coap" scheme are also
requirements for the "coaps" scheme, except that a default UDP port
of 5684 is assumed if the port subcomponent is empty or not given,
and the UDP datagrams MUST be secured through the use of DTLS as
described in Section 9.1.
Considerations for caching of responses to "coaps" identified
requests are discussed in Section 11.2.
Resources made available via the "coaps" scheme have no shared
identity with the "coap" scheme even if their resource identifiers
indicate the same authority (the same host listening to the same UDP
port). They are distinct namespaces and are considered to be
distinct origin servers.
6.3. Normalization and Comparison Rules
Since the "coap" and "coaps" schemes conform to the URI generic
syntax, such URIs are normalized and compared according to the
algorithm defined in [RFC3986], Section 6, using the defaults
described above for each scheme.
If the port is equal to the default port for a scheme, the normal
form is to elide the port subcomponent. Likewise, an empty path
component is equivalent to an absolute path of "/", so the normal
form is to provide a path of "/" instead. The scheme and host are
case insensitive and normally provided in lowercase; IP-literals are
in recommended form [RFC5952]; all other components are compared in a
case-sensitive manner. Characters other than those in the "reserved"
set are equivalent to their percent-encoded bytes (see [RFC3986],
Section 2.1): the normal form is to not encode them.
For example, the following three URIs are equivalent and cause the
same options and option values to appear in the CoAP messages:
6.4. Decomposing URIs into Options
The steps to parse a request's options from a string |url| are as
follows. These steps either result in zero or more of the Uri-Host,
Uri-Port, Uri-Path, and Uri-Query Options being included in the
request or they fail.
1. If the |url| string is not an absolute URI ([RFC3986]), then fail
2. Resolve the |url| string using the process of reference
resolution defined by [RFC3986]. At this stage, the URL is in
ASCII encoding [RFC0020], even though the decoded components will
be interpreted in UTF-8 [RFC3629] after steps 5, 8, and 9.
NOTE: It doesn't matter what it is resolved relative to, since we
already know it is an absolute URL at this point.
3. If |url| does not have a <scheme> component whose value, when
converted to ASCII lowercase, is "coap" or "coaps", then fail
4. If |url| has a <fragment> component, then fail this algorithm.
5. If the <host> component of |url| does not represent the request's
destination IP address as an IP-literal or IPv4address, include a
Uri-Host Option and let that option's value be the value of the
<host> component of |url|, converted to ASCII lowercase, and then
convert all percent-encodings ("%" followed by two hexadecimal
digits) to the corresponding characters.
NOTE: In the usual case where the request's destination IP
address is derived from the host part, this ensures that a Uri-
Host Option is only used for a <host> component of the form reg-
6. If |url| has a <port> component, then let |port| be that
component's value interpreted as a decimal integer; otherwise,
let |port| be the default port for the scheme.
7. If |port| does not equal the request's destination UDP port,
include a Uri-Port Option and let that option's value be |port|.
8. If the value of the <path> component of |url| is empty or
consists of a single slash character (U+002F SOLIDUS "/"), then
move to the next step.
Otherwise, for each segment in the <path> component, include a
Uri-Path Option and let that option's value be the segment (not
including the delimiting slash characters) after converting each
percent-encoding ("%" followed by two hexadecimal digits) to the
9. If |url| has a <query> component, then, for each argument in the
<query> component, include a Uri-Query Option and let that
option's value be the argument (not including the question mark
and the delimiting ampersand characters) after converting each
percent-encoding to the corresponding byte.
Note that these rules completely resolve any percent-encoding.
6.5. Composing URIs from Options
The steps to construct a URI from a request's options are as follows.
These steps either result in a URI or they fail. In these steps,
percent-encoding a character means replacing each of its
(UTF-8-encoded) bytes by a "%" character followed by two hexadecimal
digits representing the byte, where the digits A-F are in uppercase
(as defined in Section 2.1 of [RFC3986]; to reduce variability, the
hexadecimal notation for percent-encoding in CoAP URIs MUST use
uppercase letters). The definitions of "unreserved" and "sub-delims"
are adopted from [RFC3986].
1. If the request is secured using DTLS, let |url| be the string
"coaps://". Otherwise, let |url| be the string "coap://".
2. If the request includes a Uri-Host Option, let |host| be that
option's value, where any non-ASCII characters are replaced by
their corresponding percent-encoding. If |host| is not a valid
reg-name or IP-literal or IPv4address, fail the algorithm. If
the request does not include a Uri-Host Option, let |host| be
the IP-literal (making use of the conventions of [RFC5952]) or
IPv4address representing the request's destination IP address.
3. Append |host| to |url|.
4. If the request includes a Uri-Port Option, let |port| be that
option's value. Otherwise, let |port| be the request's
destination UDP port.
5. If |port| is not the default port for the scheme, then append a
single U+003A COLON character (:) followed by the decimal
representation of |port| to |url|.
6. Let |resource name| be the empty string. For each Uri-Path
Option in the request, append a single character U+002F SOLIDUS
(/) followed by the option's value to |resource name|, after
converting any character that is not either in the "unreserved"
set, in the "sub-delims" set, a U+003A COLON (:) character, or a
U+0040 COMMERCIAL AT (@) character to its percent-encoded form.
7. If |resource name| is the empty string, set it to a single
character U+002F SOLIDUS (/).
8. For each Uri-Query Option in the request, append a single
character U+003F QUESTION MARK (?) (first option) or U+0026
AMPERSAND (&) (subsequent options) followed by the option's
value to |resource name|, after converting any character that is
not either in the "unreserved" set, in the "sub-delims" set
(except U+0026 AMPERSAND (&)), a U+003A COLON (:), a U+0040
COMMERCIAL AT (@), a U+002F SOLIDUS (/), or a U+003F QUESTION
MARK (?) character to its percent-encoded form.
9. Append |resource name| to |url|.
10. Return |url|.
Note that these steps have been designed to lead to a URI in normal
form (see Section 6.3).