3. Examples
This section gives a number of short examples with message flows for a block-wise GET, and for a PUT or POST. These examples demonstrate the basic operation, the operation in the presence of retransmissions, and examples for the operation of the block size negotiation.
In all these examples, a Block option is shown in a decomposed way indicating the kind of Block option (1 or 2) followed by a colon, and then the block number (NUM), more bit (M), and block size exponent (2**(SZX+4)) separated by slashes. For example, a Block2 Option value of 33 would be shown as 2:2/0/32) and a Block1 Option value of 59 would be shown as 1:3/1/128. As in [RFC7252], "MID" is used as an abbreviation for "Message ID".3.1. Block2 Examples
The first example (Figure 2) shows a GET request that is split into three blocks. The server proposes a block size of 128, and the client agrees. The first two ACKs contain a payload of 128 bytes each, and the third ACK contains a payload between 1 and 128 bytes. CLIENT SERVER | | | CON [MID=1234], GET, /status ------> | | | | <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 | | | | CON [MID=1235], GET, /status, 2:1/0/128 ------> | | | | <------ ACK [MID=1235], 2.05 Content, 2:1/1/128 | | | | CON [MID=1236], GET, /status, 2:2/0/128 ------> | | | | <------ ACK [MID=1236], 2.05 Content, 2:2/0/128 | Figure 2: Simple Block-Wise GET
In the second example (Figure 3), the client anticipates the block- wise transfer (e.g., because of a size indication in the link-format description [RFC6690]) and sends a block size proposal. All ACK messages except for the last carry 64 bytes of payload; the last one carries between 1 and 64 bytes. CLIENT SERVER | | | CON [MID=1234], GET, /status, 2:0/0/64 ------> | | | | <------ ACK [MID=1234], 2.05 Content, 2:0/1/64 | | | | CON [MID=1235], GET, /status, 2:1/0/64 ------> | | | | <------ ACK [MID=1235], 2.05 Content, 2:1/1/64 | : : : ... : : : | CON [MID=1238], GET, /status, 2:4/0/64 ------> | | | | <------ ACK [MID=1238], 2.05 Content, 2:4/1/64 | | | | CON [MID=1239], GET, /status, 2:5/0/64 ------> | | | | <------ ACK [MID=1239], 2.05 Content, 2:5/0/64 | Figure 3: Block-Wise GET with Early Negotiation
In the third example (Figure 4), the client is surprised by the need for a block-wise transfer, and unhappy with the size chosen unilaterally by the server. As it did not send a size proposal initially, the negotiation only influences the size from the second message exchange onward. Since the client already obtained both the first and second 64-byte block in the first 128-byte exchange, it goes on requesting the third 64-byte block ("2/0/64"). None of this is (or needs to be) understood by the server, which simply responds to the requests as it best can. CLIENT SERVER | | | CON [MID=1234], GET, /status ------> | | | | <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 | | | | CON [MID=1235], GET, /status, 2:2/0/64 ------> | | | | <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 | | | | CON [MID=1236], GET, /status, 2:3/0/64 ------> | | | | <------ ACK [MID=1236], 2.05 Content, 2:3/1/64 | | | | CON [MID=1237], GET, /status, 2:4/0/64 ------> | | | | <------ ACK [MID=1237], 2.05 Content, 2:4/1/64 | | | | CON [MID=1238], GET, /status, 2:5/0/64 ------> | | | | <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 | Figure 4: Block-Wise GET with Late Negotiation In all these (and the following) cases, retransmissions are handled by the CoAP message exchange layer, so they don't influence the block operations (Figures 5 and 6).
CLIENT SERVER | | | CON [MID=1234], GET, /status ------> | | | | <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 | | | | CON [MID=1235], GE///////////////////////// | | | | (timeout) | | | | CON [MID=1235], GET, /status, 2:2/0/64 ------> | | | | <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 | : : : ... : : : | CON [MID=1238], GET, /status, 2:5/0/64 ------> | | | | <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 | Figure 5: Block-Wise GET with Late Negotiation and Lost CON CLIENT SERVER | | | CON [MID=1234], GET, /status ------> | | | | <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 | | | | CON [MID=1235], GET, /status, 2:2/0/64 ------> | | | | //////////////////////////////////tent, 2:2/1/64 | | | | (timeout) | | | | CON [MID=1235], GET, /status, 2:2/0/64 ------> | | | | <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 | : : : ... : : : | CON [MID=1238], GET, /status, 2:5/0/64 ------> | | | | <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 | Figure 6: Block-Wise GET with Late Negotiation and Lost ACK
3.2. Block1 Examples
The following examples demonstrate a PUT exchange; a POST exchange looks the same, with different requirements on atomicity/idempotence. Note that, similar to GET, the responses to the requests that have a more bit in the request Block1 Option are provisional and carry the response code 2.31 (Continue); only the final response tells the client that the PUT succeeded. CLIENT SERVER | | | CON [MID=1234], PUT, /options, 1:0/1/128 ------> | | | | <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 | | | | CON [MID=1235], PUT, /options, 1:1/1/128 ------> | | | | <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 | | | | CON [MID=1236], PUT, /options, 1:2/0/128 ------> | | | | <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128 | Figure 7: Simple Atomic Block-Wise PUT A stateless server that simply builds/updates the resource in place (statelessly) may indicate this by not setting the more bit in the response (Figure 8); in this case, the response codes are valid separately for each block being updated. This is of course only an acceptable behavior of the server if the potential inconsistency present during the run of the message exchange sequence does not lead to problems, e.g., because the resource being created or changed is not yet or not currently in use.
CLIENT SERVER | | | CON [MID=1234], PUT, /options, 1:0/1/128 ------> | | | | <------ ACK [MID=1234], 2.04 Changed, 1:0/0/128 | | | | CON [MID=1235], PUT, /options, 1:1/1/128 ------> | | | | <------ ACK [MID=1235], 2.04 Changed, 1:1/0/128 | | | | CON [MID=1236], PUT, /options, 1:2/0/128 ------> | | | | <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128 | Figure 8: Simple Stateless Block-Wise PUT Finally, a server receiving a block-wise PUT or POST may want to indicate a smaller block size preference (Figure 9). In this case, the client SHOULD continue with a smaller block size; if it does, it MUST adjust the block number to properly count in that smaller size. CLIENT SERVER | | | CON [MID=1234], PUT, /options, 1:0/1/128 ------> | | | | <------ ACK [MID=1234], 2.31 Continue, 1:0/1/32 | | | | CON [MID=1235], PUT, /options, 1:4/1/32 ------> | | | | <------ ACK [MID=1235], 2.31 Continue, 1:4/1/32 | | | | CON [MID=1236], PUT, /options, 1:5/1/32 ------> | | | | <------ ACK [MID=1235], 2.31 Continue, 1:5/1/32 | | | | CON [MID=1237], PUT, /options, 1:6/0/32 ------> | | | | <------ ACK [MID=1236], 2.04 Changed, 1:6/0/32 | Figure 9: Simple Atomic Block-Wise PUT with Negotiation
3.3. Combining Block1 and Block2
Block options may be used in both directions of a single exchange. The following example demonstrates a block-wise POST request, resulting in a separate block-wise response. CLIENT SERVER | | | CON [MID=1234], POST, /soap, 1:0/1/128 ------> | | | | <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 | | | | CON [MID=1235], POST, /soap, 1:1/1/128 ------> | | | | <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 | | | | CON [MID=1236], POST, /soap, 1:2/0/128 ------> | | | | <------ ACK [MID=1236], 2.04 Changed, 2:0/1/128, 1:2/0/128 | | | | CON [MID=1237], POST, /soap, 2:1/0/128 ------> | | (no payload for requests with Block2 with NUM != 0) | | (could also do late negotiation by requesting, | | e.g., 2:2/0/64) | | | | <------ ACK [MID=1237], 2.04 Changed, 2:1/1/128 | | | | CON [MID=1238], POST, /soap, 2:2/0/128 ------> | | | | <------ ACK [MID=1238], 2.04 Changed, 2:2/1/128 | | | | CON [MID=1239], POST, /soap, 2:3/0/128 ------> | | | | <------ ACK [MID=1239], 2.04 Changed, 2:3/0/128 | Figure 10: Atomic Block-Wise POST with Block-Wise Response
This model does provide for early negotiation input to the Block2 block-wise transfer, as shown below. CLIENT SERVER | | | CON [MID=1234], POST, /soap, 1:0/1/128 ------> | | | | <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 | | | | CON [MID=1235], POST, /soap, 1:1/1/128 ------> | | | | <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 | | | | CON [MID=1236], POST, /soap, 1:2/0/128, 2:0/0/64 ------> | | | | <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128, 2:0/1/64 | | | | CON [MID=1237], POST, /soap, 2:1/0/64 ------> | | (no payload for requests with Block2 with NUM != 0) | | | | <------ ACK [MID=1237], 2.04 Changed, 2:1/1/64 | | | | CON [MID=1238], POST, /soap, 2:2/0/64 ------> | | | | <------ ACK [MID=1238], 2.04 Changed, 2:2/1/64 | | | | CON [MID=1239], POST, /soap, 2:3/0/64 ------> | | | | <------ ACK [MID=1239], 2.04 Changed, 2:3/0/64 | Figure 11: Atomic Block-Wise POST with Block-Wise Response, Early Negotiation3.4. Combining Observe and Block2
In the following example, the server first sends a direct response (Observe sequence number 62350) to the initial GET request (the resulting block-wise transfer is as in Figure 4 and has therefore been left out). The second transfer is started by a 2.05 notification that contains just the first block (Observe sequence number 62354); the client then goes on to obtain the rest of the blocks.
CLIENT SERVER
| |
+----->| Header: GET 0x41011636
| GET | Token: 0xfb
| | Uri-Path: status-icon
| | Observe: (empty)
| |
|<-----+ Header: 2.05 0x61451636
| 2.05 | Token: 0xfb
| | Block2: 0/1/128
| | Observe: 62350
| | ETag: 6f00f38e
| | Payload: [128 bytes]
| |
| | (Usual GET transfer left out)
...
| | (Notification of first block)
| |
|<-----+ Header: 2.05 0x4145af9c
| 2.05 | Token: 0xfb
| | Block2: 0/1/128
| | Observe: 62354
| | ETag: 6f00f392
| | Payload: [128 bytes]
| |
+- - ->| Header: 0x6000af9c
| |
| | (Retrieval of remaining blocks)
| |
+----->| Header: GET 0x41011637
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 1/0/128
| |
|<-----+ Header: 2.05 0x61451637
| 2.05 | Token: 0xfc
| | Block2: 1/1/128
| | ETag: 6f00f392
| | Payload: [128 bytes]
| |
+----->| Header: GET 0x41011638
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 2/0/128
| |
|<-----+ Header: 2.05 0x61451638 | 2.05 | Token: 0xfc | | Block2: 2/0/128 | | ETag: 6f00f392 | | Payload: [53 bytes] Figure 12: Observe Sequence with Block-Wise Response (Note that the choice of token 0xfc in this example is arbitrary; tokens are just shown in this example to illustrate that the requests for additional blocks cannot make use of the token of the Observation relationship. As a general comment on tokens, there is no other mention of tokens in this document, as block-wise transfers handle tokens like any other CoAP exchange. As usual, the client is free to choose tokens for each exchange as it likes.) In the following example, the client also uses early negotiation to limit the block size to 64 bytes. CLIENT SERVER | | +----->| Header: GET 0x41011636 | GET | Token: 0xfb | | Uri-Path: status-icon | | Observe: (empty) | | Block2: 0/0/64 | | |<-----+ Header: 2.05 0x61451636 | 2.05 | Token: 0xfb | | Block2: 0/1/64 | | Observe: 62350 | | ETag: 6f00f38e | | Max-Age: 60 | | Payload: [64 bytes] | | | | (Usual GET transfer left out) ... | | (Notification of first block) | | |<-----+ Header: 2.05 0x4145af9c | 2.05 | Token: 0xfb | | Block2: 0/1/64 | | Observe: 62354 | | ETag: 6f00f392 | | Payload: [64 bytes] | |
+- - ->| Header: 0x6000af9c | | | | (Retrieval of remaining blocks) | | +----->| Header: GET 0x41011637 | GET | Token: 0xfc | | Uri-Path: status-icon | | Block2: 1/0/64 | | |<-----+ Header: 2.05 0x61451637 | 2.05 | Token: 0xfc | | Block2: 1/1/64 | | ETag: 6f00f392 | | Payload: [64 bytes] .... | | +----->| Header: GET 0x41011638 | GET | Token: 0xfc | | Uri-Path: status-icon | | Block2: 4/0/64 | | |<-----+ Header: 2.05 0x61451638 | 2.05 | Token: 0xfc | | Block2: 4/0/64 | | ETag: 6f00f392 | | Payload: [53 bytes] Figure 13: Observe Sequence with Early Negotiation4. The Size2 and Size1 Options
In many cases when transferring a large resource representation block by block, it is advantageous to know the total size early in the process. Some indication may be available from the maximum size estimate attribute "sz" provided in a resource description [RFC6690]. However, the size may vary dynamically, so a more up-to-date indication may be useful. This specification defines two CoAP options, Size1 for indicating the size of the representation transferred in requests, and Size2 for indicating the size of the representation transferred in responses. (Size1 has already been defined in Section 5.10.9 of [RFC7252] to provide "size information about the resource representation in a request"; however, that section only details the narrow case of indicating in 4.13 responses the maximum size of request payload that the server is able and willing to handle. The present specification provides details about its use as a request option as well.)
The Size2 Option may be used for two purposes: o In a request, to ask the server to provide a size estimate along with the usual response ("size request"). For this usage, the value MUST be set to 0. o In a response carrying a Block2 Option, to indicate the current estimate the server has of the total size of the resource representation, measured in bytes ("size indication"). Similarly, the Size1 Option may be used for two purposes: o In a request carrying a Block1 Option, to indicate the current estimate the client has of the total size of the resource representation, measured in bytes ("size indication"). o In a 4.13 response, to indicate the maximum size that would have been acceptable [RFC7252], measured in bytes. Apart from conveying/asking for size information, the Size options have no other effect on the processing of the request or response. If the client wants to minimize the size of the payload in the resulting response, it should add a Block2 Option to the request with a small block size (e.g., setting SZX=0). The Size options are "elective", i.e., a client MUST be prepared for the server to ignore the size estimate request. Either Size option MUST NOT occur more than once in a single message. +-----+---+---+---+---+-------+--------+--------+---------+ | No. | C | U | N | R | Name | Format | Length | Default | +-----+---+---+---+---+-------+--------+--------+---------+ | 60 | | | x | | Size1 | uint | 0-4 | (none) | | | | | | | | | | | | 28 | | | x | | Size2 | uint | 0-4 | (none) | +-----+---+---+---+---+-------+--------+--------+---------+ Table 2: Size Option Numbers Implementation Notes: o As a quality of implementation consideration, block-wise transfers for which the total size considerably exceeds the size of one block are expected to include size indications, whenever those can be provided without undue effort (preferably with the first block exchanged). If the size estimate does not change, the indication does not need to be repeated for every block.
o The end of a block-wise transfer is governed by the M bits in the Block options, _not_ by exhausting the size estimates exchanged. o As usual for an option of type uint, the value 0 is best expressed as an empty option (0 bytes). There is no default value for either Size option. o The Size options are neither critical nor unsafe, and are marked as No-Cache-Key.5. HTTP-Mapping Considerations
In this subsection, we give some brief examples of the influence that the Block options might have on intermediaries that map between CoAP and HTTP. For mapping CoAP requests to HTTP, the intermediary may want to map the sequence of block-wise transfers into a single HTTP transfer. For example, for a GET request, the intermediary could perform the HTTP request once the first block has been requested and could then fulfill all further block requests out of its cache. A constrained implementation may not be able to cache the entire object and may use a combination of TCP flow control and (in particular if timeouts occur) HTTP range requests to obtain the information necessary for the next block transfer at the right time. For PUT or POST requests, historically there was more variation in how HTTP servers might implement ranges; recently, [RFC7233] has defined that Range header fields received with a request method other than GET are not to be interpreted. So, in general, the CoAP-to-HTTP intermediary will have to try sending the payload of all the blocks of a block-wise transfer for these other methods within one HTTP request. If enough buffering is available, this request can be started when the last CoAP block is received. A constrained implementation may want to relieve its buffering by already starting to send the HTTP request at the time the first CoAP block is received; any HTTP 408 status code that indicates that the HTTP server became impatient with the resulting transfer can then be mapped into a CoAP 4.08 response code (similarly, 413 maps to 4.13). For mapping HTTP to CoAP, the intermediary may want to map a single HTTP transfer into a sequence of block-wise transfers. If the HTTP client is too slow delivering a request body on a PUT or POST, the CoAP server might time out and return a 4.08 response code, which in turn maps well to an HTTP 408 status code (again, 4.13 maps to 413). HTTP range requests received on the HTTP side may be served out of a cache and/or mapped to GET requests that request a sequence of blocks that cover the range.
(Note that, while the semantics of CoAP 4.08 and HTTP 408 differ, this difference is largely due to the different way the two protocols are mapped to transport. HTTP has an underlying TCP connection, which supplies connection state, so an HTTP 408 status code can immediately be used to indicate that a timeout occurred during transmitting a request through that active TCP connection. The CoAP 4.08 response code indicates one or more missing blocks, which may be due to timeouts or resource constraints; as there is no connection state, there is no way to deliver such a response immediately; instead, it is delivered on the next block transfer. Still, HTTP 408 is probably the best mapping back to HTTP, as the timeout is the most likely cause for a CoAP 4.08. Note that there is no way to distinguish a timeout from a missing block for a server without creating additional state, the need for which we want to avoid.)6. IANA Considerations
This document adds the following option numbers to the "CoAP Option Numbers" registry defined by [RFC7252]: +--------+--------+-----------+ | Number | Name | Reference | +--------+--------+-----------+ | 23 | Block2 | RFC 7959 | | | | | | 27 | Block1 | RFC 7959 | | | | | | 28 | Size2 | RFC 7959 | +--------+--------+-----------+ Table 3: CoAP Option Numbers This document adds the following response codes to the "CoAP Response Codes" registry defined by [RFC7252]: +------+---------------------------+-----------+ | Code | Description | Reference | +------+---------------------------+-----------+ | 2.31 | Continue | RFC 7959 | | | | | | 4.08 | Request Entity Incomplete | RFC 7959 | +------+---------------------------+-----------+ Table 4: CoAP Response Codes
7. Security Considerations
Providing access to blocks within a resource may lead to surprising vulnerabilities. Where requests are not implemented atomically, an attacker may be able to exploit a race condition or confuse a server by inducing it to use a partially updated resource representation. Partial transfers may also make certain problematic data invisible to Intrusion Detection Systems (IDSs); it is RECOMMENDED that an IDS that analyzes resource representations transferred by CoAP implement the Block options to gain access to entire resource representations. Still, approaches such as transferring even-numbered blocks on one path and odd-numbered blocks on another path, or even transferring blocks multiple times with different content and obtaining a different interpretation of temporal order at the IDS than at the server, may prevent an IDS from seeing the whole picture. These kinds of attacks are well understood from IP fragmentation and TCP segmentation; CoAP does not add fundamentally new considerations. Where access to a resource is only granted to clients making use of specific security associations, all blocks of that resource MUST be subject to the same security checks; it MUST NOT be possible for unprotected exchanges to influence blocks of an otherwise protected resource. As a related consideration, where object security is employed, PUT/POST should be implemented in the atomic fashion, unless the object security operation is performed on each access and the creation of unusable resources can be tolerated. Future end-to- end security mechanisms that may be added to CoAP itself may have related security considerations, this includes considerations about caching of blocks in clients and in proxies (see Sections 2.10 and 5 for different strategies in performing this caching); these security considerations will need to be described in the specifications of those mechanisms. A stateless server might be susceptible to an attack where the adversary sends a Block1 (e.g., PUT) block with a high block number: A naive implementation might exhaust its resources by creating a huge resource representation. Misleading size indications may be used by an attacker to induce buffer overflows in poor implementations, for which the usual considerations apply.7.1. Mitigating Resource Exhaustion Attacks
Certain block-wise requests may induce the server to create state, e.g., to create a snapshot for the block-wise GET of a fast-changing resource to enable consistent access to the same version of a resource for all blocks, or to create temporary resource
representations that are collected until pressed into service by a final PUT or POST with the more bit unset. All mechanisms that induce a server to create state that cannot simply be cleaned up create opportunities for denial-of-service attacks. Servers SHOULD avoid being subject to resource exhaustion based on state created by untrusted sources. But even if this is done, the mitigation may cause a denial-of-service to a legitimate request when it is drowned out by other state-creating requests. Wherever possible, servers should therefore minimize the opportunities to create state for untrusted sources, e.g., by using stateless approaches. Performing segmentation at the application layer is almost always better in this respect than at the transport layer or lower (IP fragmentation, adaptation-layer fragmentation), for instance, because there are application-layer semantics that can be used for mitigation or because lower layers provide security associations that can prevent attacks. However, it is less common to apply timeouts and keepalive mechanisms at the application layer than at lower layers. Servers MAY want to clean up accumulated state by timing it out (cf. response code 4.08), and clients SHOULD be prepared to run block-wise transfers in an expedient way to minimize the likelihood of running into such a timeout.7.2. Mitigating Amplification Attacks
[RFC7252] discusses the susceptibility of CoAP endpoints for use in amplification attacks. A CoAP server can reduce the amount of amplification it provides to an attacker by offering large resource representations only in relatively small blocks. With this, e.g., for a 1000-byte resource, a 10-byte request might result in an 80-byte response (with a 64-byte block) instead of a 1016-byte response, considerably reducing the amplification provided.8. References
8.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>. [RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, <http://www.rfc-editor.org/info/rfc7252>.
[RFC7641] Hartke, K., "Observing Resources in the Constrained Application Protocol (CoAP)", RFC 7641, DOI 10.17487/RFC7641, September 2015, <http://www.rfc-editor.org/info/rfc7641>.8.2. Informative References
[REST] Fielding, R., "Architectural Styles and the Design of Network-based Software Architectures", Ph.D. Dissertation, University of California, Irvine, 2000, <http://www.ics.uci.edu/~fielding/pubs/dissertation/ fielding_dissertation.pdf>. [RFC4919] Kushalnagar, N., Montenegro, G., and C. Schumacher, "IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs): Overview, Assumptions, Problem Statement, and Goals", RFC 4919, DOI 10.17487/RFC4919, August 2007, <http://www.rfc-editor.org/info/rfc4919>. [RFC4944] Montenegro, G., Kushalnagar, N., Hui, J., and D. Culler, "Transmission of IPv6 Packets over IEEE 802.15.4 Networks", RFC 4944, DOI 10.17487/RFC4944, September 2007, <http://www.rfc-editor.org/info/rfc4944>. [RFC6690] Shelby, Z., "Constrained RESTful Environments (CoRE) Link Format", RFC 6690, DOI 10.17487/RFC6690, August 2012, <http://www.rfc-editor.org/info/rfc6690>. [RFC7228] Bormann, C., Ersue, M., and A. Keranen, "Terminology for Constrained-Node Networks", RFC 7228, DOI 10.17487/RFC7228, May 2014, <http://www.rfc-editor.org/info/rfc7228>. [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014, <http://www.rfc-editor.org/info/rfc7230>. [RFC7233] Fielding, R., Ed., Lafon, Y., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Range Requests", RFC 7233, DOI 10.17487/RFC7233, June 2014, <http://www.rfc-editor.org/info/rfc7233>.
Acknowledgements
Much of the content of this document is the result of discussions with the [RFC7252] authors, and via many CoRE WG discussions. Charles Palmer provided extensive editorial comments to a previous draft version of this document, some of which have been covered in this document. Esko Dijk reviewed a more recent version, leading to a number of further editorial improvements, a solution to the 4.13 ambiguity problem, and the section about combining Block and multicast (Section 2.8). Markus Becker proposed getting rid of an ill-conceived default value for the Block2 and Block1 Options. Peter Bigot insisted on a more systematic coverage of the options and response code. Qin Wu provided a review for the IETF Operations directorate, and Goeran Selander commented on the security considerations. Kepeng Li, Linyi Tian, and Barry Leiba wrote up an early version of the Size option, which is described in this document. Klaus Hartke wrote some of the text describing the interaction of Block2 with Observe. Matthias Kovatsch provided a number of significant simplifications of the protocol. The IESG reviewers provided very useful comments. Spencer Dawkins even suggested new text. He and Mirja Kuehlewind insisted on more explicit information about the layering of block-wise transfers on top of the base protocol. Ben Campbell helped untangle some MUST/ SHOULD soup. Comments by Alexey Melnikov, as well as the Gen-ART review by Jouni Korhonen, resulted in further improvements to the text.
Authors' Addresses
Carsten Bormann Universitaet Bremen TZI Postfach 330440 Bremen D-28359 Germany Phone: +49-421-218-63921 Email: cabo@tzi.org Zach Shelby (editor) ARM 150 Rose Orchard San Jose, CA 95134 United States of America Phone: +1-408-203-9434 Email: zach.shelby@arm.com