asciidoctor-rfc 0.2.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +116 -6
  3. data/asciidoctor-rfc.gemspec +15 -1
  4. data/lib/asciidoctor/rfc/common/base.rb +74 -7
  5. data/lib/asciidoctor/rfc/common/front.rb +1 -1
  6. data/lib/asciidoctor/rfc/v2/base.rb +87 -38
  7. data/lib/asciidoctor/rfc/v2/blocks.rb +29 -2
  8. data/lib/asciidoctor/rfc/v2/converter.rb +0 -1
  9. data/lib/asciidoctor/rfc/v2/inline_anchor.rb +2 -8
  10. data/lib/asciidoctor/rfc/v2/lists.rb +7 -4
  11. data/lib/asciidoctor/rfc/v2/table.rb +1 -1
  12. data/lib/asciidoctor/rfc/v3/base.rb +41 -43
  13. data/lib/asciidoctor/rfc/v3/blocks.rb +29 -2
  14. data/lib/asciidoctor/rfc/v3/converter.rb +0 -2
  15. data/lib/asciidoctor/rfc/v3/inline_anchor.rb +2 -6
  16. data/lib/asciidoctor/rfc/version.rb +1 -1
  17. data/spec/asciidoctor/rfc/v2/comments_spec.rb +7 -3
  18. data/spec/asciidoctor/rfc/v2/date_spec.rb +23 -0
  19. data/spec/asciidoctor/rfc/v2/dlist_spec.rb +107 -9
  20. data/spec/asciidoctor/rfc/v2/image_spec.rb +17 -0
  21. data/spec/asciidoctor/rfc/v2/inline_formatting_spec.rb +12 -0
  22. data/spec/asciidoctor/rfc/v2/listing_spec.rb +22 -0
  23. data/spec/asciidoctor/rfc/v2/literal_spec.rb +22 -2
  24. data/spec/asciidoctor/rfc/v2/preamble_spec.rb +72 -0
  25. data/spec/asciidoctor/rfc/v2/references_spec.rb +3 -1
  26. data/spec/asciidoctor/rfc/v2/table_spec.rb +104 -4
  27. data/spec/asciidoctor/rfc/v2/text_spec.rb +89 -0
  28. data/spec/asciidoctor/rfc/v2/ulist_spec.rb +40 -0
  29. data/spec/asciidoctor/rfc/v3/dlist_spec.rb +103 -1
  30. data/spec/asciidoctor/rfc/v3/image_spec.rb +18 -0
  31. data/spec/asciidoctor/rfc/v3/listing_spec.rb +26 -0
  32. data/spec/asciidoctor/rfc/v3/literal_spec.rb +20 -1
  33. data/spec/asciidoctor/rfc/v3/preamble_spec.rb +150 -0
  34. data/spec/asciidoctor/rfc/v3/references_spec.rb +35 -34
  35. data/spec/asciidoctor/rfc/v3/series_info_spec.rb +39 -0
  36. data/spec/examples/README.adoc +162 -0
  37. data/spec/examples/davies-template-bare-06.adoc +3 -0
  38. data/spec/examples/draft-ietf-core-block-xx.mkd +935 -0
  39. data/spec/examples/draft-ietf-core-block-xx.mkd.adoc +1013 -0
  40. data/spec/examples/draft-ietf-core-block-xx.xml.orig +1251 -0
  41. data/spec/examples/example-v2.adoc +6 -2
  42. data/spec/examples/example-v3.adoc +5 -1
  43. data/spec/examples/hoffmanv2.xml.adoc +247 -0
  44. data/spec/examples/hoffmanv2.xml.orig +339 -0
  45. data/spec/examples/hoffmanv3.xml.orig +346 -0
  46. data/spec/examples/mib-doc-template-xml-06.adoc +5 -1
  47. data/spec/examples/rfc2100.md.adoc +2 -3
  48. data/spec/examples/rfc3514.md.adoc +3 -2
  49. data/spec/examples/rfc5841.md.adoc +1 -1
  50. data/spec/examples/rfc748.md.adoc +7 -6
  51. data/spec/examples/rfc7511.md.adoc +15 -15
  52. data/spec/examples/skel.mkd +32 -0
  53. data/spec/examples/skel.mkd.adoc +50 -0
  54. data/spec/examples/skel.xml.orig +105 -0
  55. data/spec/examples/stupid-s.mkd +569 -0
  56. data/spec/examples/stupid-s.mkd.adoc +771 -0
  57. data/spec/examples/stupid-s.xml.orig +880 -0
  58. data/spec/spec_helper.rb +1 -1
  59. metadata +32 -4
@@ -148,4 +148,43 @@ describe Asciidoctor::RFC::V3::Converter do
148
148
  </rfc>
149
149
  OUTPUT
150
150
  end
151
+ it "sets seriesInfo attributes for RFC with illegal intended status" do
152
+ expect(Asciidoctor.convert(<<~'INPUT', backend: :rfc3, header_footer: true)).to be_equivalent_to <<~'OUTPUT'
153
+ = Document title
154
+ Author
155
+ :doctype: internet-draft
156
+ :name: draft-xxx
157
+ :status: full-standard
158
+ :intended-series: illegal
159
+ :submission-type: IRTF
160
+
161
+ == Section 1
162
+ Text
163
+ INPUT
164
+ <?xml version="1.0" encoding="US-ASCII"?>
165
+ <!DOCTYPE rfc SYSTEM "rfc2629.dtd">
166
+ <?rfc strict="yes"?>
167
+ <?rfc toc="yes"?>
168
+ <?rfc tocdepth="4"?>
169
+ <?rfc symrefs=""?>
170
+ <?rfc sortrefs=""?>
171
+ <?rfc compact="yes"?>
172
+ <?rfc subcompact="no"?>
173
+ <rfc submissionType="IRTF" prepTime="2000-01-01T05:00:00Z" version="3">
174
+ <front>
175
+ <title>Document title</title>
176
+ <seriesInfo name="Internet-Draft" status="full-standard" stream="IRTF" value="draft-xxx"/>
177
+ <seriesInfo name="" status="illegal" value="draft-xxx"/>
178
+ <author fullname="Author"/>
179
+ <date day="1" month="January" year="2000"/>
180
+
181
+ </front><middle>
182
+ <section anchor="_section_1" numbered="false">
183
+ <name>Section 1</name>
184
+ <t>Text</t>
185
+ </section>
186
+ </middle>
187
+ </rfc>
188
+ OUTPUT
189
+ end
151
190
  end
@@ -0,0 +1,162 @@
1
+ = Examples
2
+ The examples in this directory are found RFC XML documents in various markup schemes
3
+ (RFC XML source, MMark Markdown, Krmdown Markdown), with Asciidoc equivalents which
4
+ we have supplied. The RFC XML derived from these sources is compared with the RFC
5
+ XML derived from Asciidoc during Rspec: for v2 RFC XML, this is done using xml2rfc,
6
+ and comparing the resulting txt files.
7
+
8
+ Examples are taken from the following sources:
9
+
10
+ == RFC XML v1
11
+ https://tools.ietf.org/tools/templates/
12
+
13
+ * `davies-template-bare-06.xml.orig`
14
+ * `mib-doc-template-xml-06.xml.orig`
15
+
16
+ The equivalent asciidoc is
17
+
18
+ * `davies-template-bare-06.adoc`
19
+ * `mib-doc-template-xml-06.adoc`
20
+
21
+ As these are document templates in v1, they are not good exemplars of RFC XML usage.
22
+
23
+ The following discrepancies should be noted between xml2rfc output from the XML source,
24
+ and xml2rfc output from XML generated from our asciidoc should be noted:
25
+
26
+ `davies-template-bare-06.adoc`::
27
+ +
28
+ --
29
+ * Asciidoc does not support table preambles and postambles; the table preamble and postamble
30
+ text is unindented in the output, and the postamble follows the table caption.
31
+ --
32
+
33
+ `mib-doc-template-xml-06.adoc`::
34
+ +
35
+ --
36
+ * The asciidoc automatically tages hyperlinks; this is reflected in the RFC XML
37
+ output as `eref`, and in the xml2rfc output as angle brackets.
38
+ --
39
+
40
+ == RFC XML v2
41
+ https://www.ietf.org/archive/id/draft-hoffman-rfcexamples-04.txt
42
+
43
+ * `hoffmanv2.xml.orig`
44
+
45
+ The equivalent asciidoc is
46
+
47
+ * `hoffmanv2.xml.adoc`
48
+
49
+ The following discrepancies should be noted between xml2rfc output from the XML source,
50
+ and xml2rfc output from XML generated from our asciidoc should be noted:
51
+
52
+ `hoffmanv2.xml.adoc`::
53
+ +
54
+ --
55
+ * The source xml has set the `subcompact` document directive; the directive cannot be set
56
+ from Asciidoc.
57
+ * Table preambles and postambles are not supported in Asciidoc.
58
+ --
59
+
60
+ == MMark
61
+ https://github.com/miekg/mmark/tree/master/rfc
62
+
63
+ The RFC XML v2 documents (`*.md.2.xml`) and RFC XML v3 documents (`*.md.3.xml`)
64
+ have been generated from the MMark source (`*.md`) using the current version of MMark:
65
+
66
+ * `rfc1149.md`
67
+ * `rfc2100.md`
68
+ * `rfc3514.md`
69
+ * `rfc5841.md`
70
+ * `rfc748.md`
71
+ * `rfc7511.md`
72
+
73
+ The equivalent asciidoc is
74
+
75
+ * `rfc1149.md.adoc`
76
+ * `rfc2100.md.adoc`
77
+ * `rfc3514.md.adoc`
78
+ * `rfc5841.md.adoc`
79
+ * `rfc748.md.adoc`
80
+ * `rfc7511.md.adoc`
81
+
82
+ The following discrepancies should be noted between xml2rfc output from the XML source,
83
+ and xml2rfc output from XML generated from our asciidoc should be noted:
84
+
85
+ `rfc1149.md`:: No discrepancy
86
+
87
+ `rfc2100.md`::
88
+ +
89
+ --
90
+ * The MMark has tagged the doggerel in this RFC as `artwork`. We have chosen to use Asciidoc
91
+ `verse`, which in RFC XML 2 preserves linebreaks, but not the indentation of even-numbered
92
+ verses, or of the concluding stanza.
93
+ --
94
+
95
+ `rfc3514.adoc`::
96
+ +
97
+ --
98
+ * The MMark separates definition list terms from definitions, with a line break (`<vspace/>`).
99
+ This gem consistently inserts one blank line between definition list terms
100
+ and definitions (`<vspace blankLines="1"/>`).
101
+ --
102
+
103
+ `rfc5841.md`:: No discrepancy
104
+ `rfc748.md`:: No discrepancy
105
+
106
+ `rfc7511.md`::
107
+ +
108
+ --
109
+ * The MMark has specified an external reference to a specific section by giving the section
110
+ number in text: `Section 4.2 of RFC 2460 [@!RFC2460]`, rendered as
111
+ `Section 4.2 of RFC 2460 <xref target="RFC2460"/>`. The asciidoc takes advantage of
112
+ the `relref` construction of external section references, even though `relref` is a v3
113
+ RFC XML feature: `<<RFC2460,4.2 of>>`, which is rendered in v2 RFC XML as
114
+ `<xref target="RFC2460">Section 4.2 of [RFC2460]</xref>`.
115
+ --
116
+
117
+ == Kramdown
118
+ https://github.com/cabo/kramdown-rfc2629/tree/master/examples
119
+
120
+ The RFC XML v2 documents (`*.mkd.xml`)
121
+ have been generated from the Kramdown source (`*.mkd`) using the current version of Kramdown:
122
+
123
+ * `draft-ietf-core-block-xx.mkd`
124
+ * `skel.mkd`
125
+ * `stupid-s.mkd`
126
+
127
+ The equivalent asciidoc is
128
+
129
+ * `draft-ietf-core-block-xx.mkd.adoc`
130
+ * `skel.mkd.adoc`
131
+ * `stupid-s.mkd.adoc`
132
+
133
+ The following discrepancies should be noted between xml2rfc output from the XML source,
134
+ and xml2rfc output from XML generated from our asciidoc should be noted:
135
+
136
+ `draft-ietf-core-block-xx.mkd`::
137
+ +
138
+ --
139
+ * The Kramdown document references itself through an entity. The Asciidoc uses a
140
+ cross-reference, which takes up one more space for the same reference text.
141
+ * Asciidoc requires an extra space for a definition list term ending in a colon,
142
+ since the term delimiter itself involves colons:
143
+ `SZX: :: `
144
+ * Note that `**` needs to be escape in Asciidoc as `\\**`, in order not to be misinterpreted
145
+ as formatting. On occasionl, the escaping is ignored, and the exponentiation operator
146
+ has had to be entered as `&#42;&#42;`.
147
+ --
148
+
149
+ `skel.mkd`::
150
+ +
151
+ --
152
+ * Kramdown inserts a leading zero in day numbers; our gem does not.
153
+ --
154
+
155
+ `stupid-s.mkd`::
156
+ +
157
+ --
158
+ * Kramdown inserts a leading zero in day numbers; our gem does not.
159
+ * The asciidoc automatically tages hyperlinks; this is reflected in the RFC XML
160
+ output as `eref`, and in the xml2rfc output as angle brackets.
161
+ --
162
+
@@ -18,6 +18,9 @@ Elwyn Davies <elwynd@dial.pipex.com>
18
18
  :area: General
19
19
  :workgroup: Internet Engineering Task Force
20
20
  :keyword: template
21
+ :inline-definition-lists: true
22
+ :compact: yes
23
+ :subcompact: no
21
24
 
22
25
  [abstract]
23
26
  Insert an abstract: MANDATORY. This template is for creating an
@@ -0,0 +1,935 @@
1
+ ---
2
+ title: Blockwise transfers in CoAP
3
+ # abbrev: CoAP-Block
4
+ docname: draft-ietf-core-block-05
5
+ date: 2012-01-13
6
+ # date: 2012-01
7
+ # date: 2012
8
+
9
+ # stand_alone: true
10
+
11
+ ipr: trust200902
12
+ area: Applications
13
+ wg: CoRE Working Group
14
+ kw: Internet-Draft
15
+ cat: std
16
+
17
+ coding: us-ascii
18
+ pi: # can use array (if all yes) or hash here
19
+ # - toc
20
+ # - sortrefs
21
+ # - symrefs
22
+ toc: yes
23
+ sortrefs: # defaults to yes
24
+ symrefs: yes
25
+
26
+ author:
27
+ -
28
+ ins: C. Bormann
29
+ name: Carsten Bormann
30
+ org: Universitaet Bremen TZI
31
+ # abbrev: TZI
32
+ # street:
33
+ # - Postfach 330440
34
+ # - Bibliothekstr. 1
35
+ street: Postfach 330440
36
+ city: Bremen
37
+ code: D-28359
38
+ country: Germany
39
+ phone: +49-421-218-63921
40
+ facsimile: +49-421-218-7000
41
+ email: cabo@tzi.org
42
+ -
43
+ ins: Z. Shelby
44
+ name: Zach Shelby
45
+ org: Sensinode
46
+ role: editor
47
+ street: Kidekuja 2
48
+ city: Vuokatti
49
+ code: 88600
50
+ country: Finland
51
+ phone: "+358407796297"
52
+ email: zach@sensinode.com
53
+
54
+ normative:
55
+ # - rfc2119
56
+ # - rfc2616
57
+ # - I-D.ietf-core-coap
58
+ RFC2119:
59
+ RFC2616:
60
+ I-D.ietf-core-coap:
61
+
62
+ informative:
63
+ REST:
64
+ title: Architectural Styles and the Design of Network-based Software Architectures
65
+ author:
66
+ # -
67
+ ins: R. Fielding
68
+ name: Roy Fielding
69
+ org: University of California, Irvine
70
+ date: 2000
71
+
72
+ entity:
73
+ SELF: "[RFCXXXX]"
74
+
75
+ # --- note_IESG_Note
76
+ #
77
+ # bla bla bla
78
+
79
+ --- abstract
80
+
81
+
82
+ CoAP is a RESTful transfer protocol for constrained nodes and networks.
83
+ Basic CoAP messages work well for the small payloads we expect
84
+ from temperature sensors, light switches, and similar
85
+ building-automation devices.
86
+ Occasionally, however, applications will need to transfer
87
+ larger payloads --- for instance, for firmware updates. With
88
+ HTTP, TCP does the grunt work of slicing large payloads up
89
+ into multiple packets and ensuring that they all arrive and
90
+ are handled in the right order.
91
+
92
+ CoAP is based on datagram transports such as UDP or DTLS,
93
+ which limits the maximum size of resource representations that
94
+ can be transferred without too much fragmentation.
95
+ Although UDP supports larger payloads through IP
96
+ fragmentation, it is limited to 64 KiB and, more importantly,
97
+ doesn't really work well for constrained applications and
98
+ networks.
99
+
100
+ Instead of relying on IP fragmentation, this specification
101
+ extends basic CoAP with a pair of "Block" options, for
102
+ transferring multiple blocks of information from a resource
103
+ representation in multiple request-response pairs. In many
104
+ important cases, the Block options enable a server to be truly
105
+ stateless: the server can handle each block transfer
106
+ separately, with no need for a connection setup or other
107
+ server-side memory of previous block transfers.
108
+
109
+ In summary, the Block options provide a minimal way to
110
+ transfer larger representations in a block-wise fashion.
111
+
112
+
113
+ --- middle
114
+
115
+ Introduction {#problems}
116
+ ============
117
+
118
+ The CoRE WG is tasked with standardizing an
119
+ Application Protocol for Constrained Networks/Nodes, CoAP.
120
+ This protocol is intended to provide RESTful {{REST}} services not
121
+ unlike HTTP {{RFC2616}},
122
+ while reducing the complexity of implementation as well as the size of
123
+ packets exchanged in order to make these services useful in a highly
124
+ constrained network of themselves highly constrained nodes.
125
+
126
+ This objective requires restraint in a number of sometimes conflicting ways:
127
+
128
+ - reducing implementation complexity in order to minimize code size,
129
+ - reducing message sizes in order to minimize the number of fragments
130
+ needed for each message (in turn to maximize the probability of
131
+ delivery of the message), the amount of transmission power needed
132
+ and the loading of the limited-bandwidth channel,
133
+ - reducing requirements on the environment such as stable storage,
134
+ good sources of randomness or user interaction capabilities.
135
+
136
+ CoAP is based on datagram transports such as UDP, which limit the
137
+ maximum size of resource representations that can be transferred
138
+ without creating unreasonable levels of IP fragmentation. In
139
+ addition, not all resource representations will fit into a single link
140
+ layer packet of a constrained network, which may cause adaptation
141
+ layer fragmentation even if IP layer fragmentation is not required.
142
+ Using fragmentation (either at the adaptation layer or at the IP
143
+ layer) to enable the transport of larger representations is possible
144
+ up to the maximum size of the underlying datagram protocol (such as
145
+ UDP), but the fragmentation/reassembly process loads the lower layers
146
+ with conversation state that is better managed in the application
147
+ layer.
148
+
149
+ This specification defines a pair of CoAP options to enable *block-wise* access to
150
+ resource representations.
151
+ The Block options provide a minimal way to transfer larger
152
+ resource representations in a block-wise fashion.
153
+ The overriding objective is to avoid
154
+ creating conversation state at the server for block-wise GET requests.
155
+ (It is impossible to fully avoid creating conversation state for
156
+ POST/PUT, if the creation/replacement of resources is to be atomic;
157
+ where that property is not needed, there is no need to create server
158
+ conversation state in this case, either.)
159
+
160
+
161
+ In summary, this specification adds a pair of Block options to CoAP that
162
+ can be used for block-wise transfers. Benefits of using these options
163
+ include:
164
+
165
+ * Transfers larger than can be accommodated in constrained-network
166
+ link-layer packets can be performed in smaller blocks.
167
+ * No hard-to-manage conversation state is created at the adaptation
168
+ layer or IP layer for fragmentation.
169
+ * The transfer of each block is acknowledged, enabling retransmission
170
+ if required.
171
+ * Both sides have a say in the block size that actually will be used.
172
+ * The resulting exchanges are easy to understand using packet
173
+ analyzer tools and thus quite accessible to debugging.
174
+ * If needed, the Block options can also be used as is to provide random
175
+ access to power-of-two sized blocks within a resource representation.
176
+
177
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
178
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
179
+ document are to be interpreted as described in RFC 2119, BCP 14
180
+ {{RFC2119}} and indicate requirement levels for compliant CoAP
181
+ implementations.
182
+
183
+ In this document, the term "byte" is used in its now customary sense
184
+ as a synonym for "octet".
185
+
186
+ Where bit arithmetic is explained, this document uses the notation
187
+ familiar from the programming language C, except that the operator "\*\*"
188
+ stands for exponentiation.
189
+
190
+ Block-wise transfers
191
+ ====================
192
+
193
+ As discussed in the introduction, there are good reasons to limit the
194
+ size datagrams in constrained networks:
195
+
196
+ * by the maximum datagram size (~ 64 KiB for UDP)
197
+ * by the desire to avoid IP fragmentation (MTU of 1280 for IPv6)
198
+ * by the desire to avoid adaptation layer fragmentation (60--80 bytes
199
+ for 6LoWPAN)
200
+
201
+ When a resource representation is larger than can be comfortably
202
+ transferred in the payload of a single CoAP datagram, a Block option
203
+ can be used to indicate a block-wise transfer. As payloads can be
204
+ sent both with requests and with responses, this specification
205
+ provides two separate options for each direction of payload transfer.
206
+
207
+ In the following, the term "payload" will be used for the actual
208
+ content of a single CoAP message, i.e. a single block being
209
+ transferred, while the term "body" will be used for the entire
210
+ resource representation that is being transferred in a block-wise
211
+ fashion.
212
+
213
+ In most cases, all blocks being transferred for a body will be of the
214
+ same size. The block size is not fixed by the protocol. To keep the
215
+ implementation as simple as possible, the Block options support only a
216
+ small range of power-of-two block sizes, from 2\*\*4 (16) to 2\*\*10
217
+ (1024) bytes. As bodies often will not evenly divide into the
218
+ power-of-two block size chosen, the size need not be reached in the
219
+ final block; still this size will be given as the block size even for
220
+ the final block.
221
+
222
+ The Block Options {#block-option}
223
+ ----------------
224
+
225
+ | Type | C/E | Name | Format | Length | Default |
226
+ |------:+----------+--------+--------+--------+---------------|
227
+ | 19 | Critical | Block1 | uint | 1-3 B | 0 (see below) |
228
+ | 17 | Critical | Block2 | uint | 1-3 B | 0 (see below) |
229
+ {: #block-option-numbers title="Block Option Numbers"}
230
+
231
+ Both Block1 and Block2 options can be present both in request and
232
+ response messages. In either case, the Block1 Option pertains to the
233
+ request payload, and the Block2 Option pertains to the response payload.
234
+
235
+ Hence, for the methods defined in {{I-D.ietf-core-coap}}, Block1 is
236
+ useful with the payload-bearing POST and PUT requests and their
237
+ responses. Block2 is useful with GET, POST, and PUT requests and
238
+ their payload-bearing responses (2.01, 2.02, 2.04, 2.05 --- see
239
+ section "Payload" of {{I-D.ietf-core-coap}}).
240
+
241
+ (As a memory aid: Block_1_ pertains to the payload of the _1st_ part
242
+ of the request-response exchange, i.e. the request, and Block_2_
243
+ pertains to the payload of the _2nd_ part of the request-response
244
+ exchange, i.e. the response.)
245
+
246
+ Where Block1 is present in a request or Block2 in a response (i.e., in
247
+ that message to the payload of which it pertains) it indicates a
248
+ block-wise transfer and describes how this block-wise payload forms
249
+ part of the entire body being transferred ("descriptive usage").
250
+ Where it is present in the opposite direction, it provides additional
251
+ control on how that payload will be formed or was processed ("control usage").
252
+
253
+ Implementation of either Block option is intended to be optional.
254
+ However, when it is present in a CoAP message, it MUST be processed
255
+ (or the message rejected);
256
+ therefore it is identified as a critical option.
257
+
258
+ Three items of information may need to be transferred in a Block
259
+ option:
260
+
261
+ * The size of the block (SZX);
262
+ * whether more blocks are following (M);
263
+ * the relative number of the block (NUM) within a sequence of blocks
264
+ with the given size.
265
+
266
+ The value of the option is a 1-, 2- or 3-byte integer which encodes
267
+ these three fields, see {{block}}.
268
+
269
+ 0
270
+ 0 1 2 3 4 5 6 7
271
+ +-+-+-+-+-+-+-+-+
272
+ | NUM |M| SZX |
273
+ +-+-+-+-+-+-+-+-+
274
+
275
+ 0 1
276
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
277
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
278
+ | NUM |M| SZX |
279
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
280
+
281
+ 0 1 2
282
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
283
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
284
+ | NUM |M| SZX |
285
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
286
+ {: #block title="Block option value"}
287
+
288
+
289
+ The block size is encoded as a three-bit unsigned integer (0 for 2\*\*4 to 6
290
+ for 2\*\*10 bytes), which we call the `SZX` (size exponent); the
291
+ actual block size is then `2**(SZX + 4)`. SZX is transferred in the
292
+ three least significant bits of the option value (i.e., `val & 7`
293
+ where `val` is the value of the option).
294
+
295
+ The fourth least significant bit, the M or "more" bit (`val & 8`),
296
+ indicates whether more blocks are following or the current block-wise
297
+ transfer is the last block being transferred.
298
+
299
+ The option value divided by sixteen (the NUM field) is the sequence
300
+ number of the block currently being transferred, starting from
301
+ zero. The current transfer is therefore about the `size` bytes
302
+ starting at byte `NUM << (SZX + 4)`. (Note that, as an implementation
303
+ convenience, `(val & ~0xF) << (val & 7)`, i.e. the option value with
304
+ the last 4 bits masked out, shifted to the left by the value of SZX,
305
+ gives the byte position of the block.)
306
+
307
+ The default value of both the Block1 and the Block2 Option is zero,
308
+ indicating that the current block is the first and only block of the
309
+ transfer (block number 0, M bit not set); however, there is no
310
+ explicit size implied by this default value.
311
+
312
+ More specifically, within the option value of a Block1 or Block2
313
+ Option, the meaning of the option fields is defined as follows:
314
+
315
+ NUM:
316
+ : Block Number. The block number is a variable-size (4, 12, or 20 bit)
317
+ unsigned integer (uint, see Appendix A of {{I-D.ietf-core-coap}})
318
+ indicating the block number being requested or provided. Block
319
+ number 0 indicates the first block of a body.
320
+
321
+ M:
322
+ : More Flag (not last block). For descriptive usage, this flag, if
323
+ unset, indicates that the payload in this message is the last block
324
+ in the body; when set it indicates that there are one or more
325
+ additional blocks available. When a Block2 Option is used in a
326
+ request to retrieve a specific block number ("control usage"), the M
327
+ bit MUST be sent as zero and ignored on reception. (In a Block1
328
+ Option in a response, the M flag is used to indicate atomicity, see
329
+ below.)
330
+
331
+ SZX:
332
+ : Block Size. The block size is a three-bit unsigned integer indicating the size of a block to
333
+ the power of two. Thus block size = 2\*\*(SZX + 4). The allowed
334
+ values of SZX are 0 to 6, i.e., the minimum block size is 2\*\*(0+4) = 16
335
+ and the maximum is 2\*\*(6+4) = 1024.
336
+ The value 7 for SZX (which would indicate a block size of 2048) is
337
+ reserved, i.e. MUST NOT be sent and MUST lead to a 4.00 Bad Request
338
+ response code upon reception in a request.
339
+
340
+ The Block options are used in one of three roles:
341
+
342
+ - In descriptive usage, i.e. a Block2 Option in a response (e.g., a
343
+ 2.05 response for GET), or a Block1 Option in a request (e.g., PUT
344
+ or POST):
345
+ - The NUM field in the option value describes what block number is
346
+ contained in the payload of this message.
347
+ - The M bit indicates whether further
348
+ blocks are required to complete the transfer of that body.
349
+ - The block size given by SZX MUST match the size of the payload in
350
+ bytes, if the M bit is set. (The block size given is irrelevant if
351
+ M is unset). For Block2, if the request suggested a larger value
352
+ of SZX, the next request MUST move SZX down to the size given
353
+ here. (The effect is that, if the server uses the smaller of its
354
+ preferred block size and the one requested, all blocks for a body
355
+ use the same block size.)
356
+
357
+ - A Block2 Option in control usage in a request (e.g., GET):
358
+ - The NUM field in the Block2 Option gives the block number of the
359
+ payload that is being requested to be returned in the response.
360
+ - In this case, the M bit has no function and MUST be set to zero.
361
+ - The block size given (SZX) suggests a block size (in the case of
362
+ block number 0) or repeats the block size of previous blocks
363
+ received (in the case of block numbers other than 0).
364
+
365
+ - A Block1 Option in control usage in a response (e.g., a 2.xx
366
+ response for a PUT or POST request):
367
+ - The NUM field of the Block1 Option indicates what block number is
368
+ being acknowledged.
369
+ - If the M bit was set in the request, the server can choose whether
370
+ to act on each block separately, with no memory, or whether to
371
+ handle the request for the entire body atomically, or any mix of
372
+ the two. If the M bit is also set in the response, it indicates
373
+ that this response does not carry the final response code to the
374
+ request, i.e. the server collects further blocks and plans to
375
+ implement the request atomically (e.g., acts only upon reception
376
+ of the last block of payload). Conversely, if the M bit is unset
377
+ even though it was set in the request, it indicates the block-wise
378
+ request was enacted now specifically for this block, and the
379
+ response carries the final response to this request (and to any
380
+ previous ones with the M bit set in the response's Block1 Option
381
+ in this sequence of block-wise transfers); the client is still
382
+ expected to continue sending further blocks, the request method
383
+ for which may or may not also be enacted per-block.
384
+ - Finally, the SZX block size given in a control Block1 Option
385
+ indicates the largest block size preferred by the server for
386
+ transfers toward the resource that is the same or smaller than the
387
+ one used in the initial exchange; the client SHOULD use this block
388
+ size or a smaller one in all further requests in the transfer
389
+ sequence, even if that means changing the block size (and possibly
390
+ scaling the block number accordingly) from now on.
391
+
392
+ Using the Block Options {#block-usage}
393
+ -----------------------
394
+
395
+ Using one or both Block options, a single REST operation can be split
396
+ into multiple CoAP message exchanges. As specified in
397
+ {{I-D.ietf-core-coap}}, each of these message exchanges uses their own
398
+ CoAP Message ID.
399
+
400
+ When a request is answered with a response carrying a Block2 Option with
401
+ the M bit set, the requester may retrieve additional blocks of the
402
+ resource representation by sending further
403
+ requests with the same options and a Block2 Option giving the block
404
+ number and block size desired. In a request, the client MUST set the M bit of a Block2 Option
405
+ to zero and the server MUST ignore it on reception.
406
+
407
+ To influence the block size used in a response, the
408
+ requester also uses the Block2 Option, giving the desired size, a block
409
+ number of zero and an M bit of zero. A server MUST use the block
410
+ size indicated or a smaller size. Any further block-wise requests for
411
+ blocks beyond the first one MUST indicate the same block size that was
412
+ used by the server in the
413
+ response for the first request that gave a desired size using a Block2
414
+ Option.
415
+
416
+ Once the Block2 Option is used by the requester, all requests in a
417
+ single block-wise transfer
418
+ MUST ultimately use the same size, except that there may not be enough
419
+ content to fill the last block (the one returned with the M bit not
420
+ set).
421
+ (Note that the client may start using the Block2 Option in a second
422
+ request after a first request without a Block2 Option resulted in a
423
+ Block option in the response.)
424
+ The server SHOULD use the block
425
+ size indicated in the request option or a smaller size, but the
426
+ requester MUST take note of the actual block size used in the response
427
+ it receives
428
+ to its initial request and proceed to use it in subsequent requests. The
429
+ server behavior MUST ensure that this client behavior results in the
430
+ same block size for all responses in a sequence (except for the last
431
+ one with the M bit not set, and possibly the first one if the initial
432
+ request did not contain a Block2 Option).
433
+
434
+ Block-wise transfers can be used to GET resources the representations
435
+ of which are entirely static (not changing over time at all, such as
436
+ in a schema describing a device), or for dynamically changing
437
+ resources. In the latter case, the Block2 Option SHOULD be used in
438
+ conjunction with the ETag Option, to ensure that the blocks being
439
+ reassembled are from the same version of the representation: The
440
+ server SHOULD include an ETag option in each response. If an ETag
441
+ option is available, the client's reassembler, when reassembling the
442
+ representation from the blocks being exchanged, MUST compare ETag
443
+ Options. If the ETag Options do not match in a GET transfer, the
444
+ requester has the option of attempting to retrieve fresh values for
445
+ the blocks it retrieved first. To minimize the resulting
446
+ inefficiency, the server MAY cache the current value of a
447
+ representation for an ongoing sequence of requests. The client MAY
448
+ facilitate identifying the sequence by using the Token Option with a
449
+ non-default value. Note well that this specification makes no
450
+ requirement for the server to establish any state; however, servers
451
+ that offer quickly changing resources may thereby make it impossible
452
+ for a client to ever retrieve a consistent set of blocks.
453
+
454
+ In a request with a request payload (e.g., PUT or POST), the Block1
455
+ Option refers to the payload in the request (descriptive usage).
456
+
457
+ In response to a request with a payload (e.g., a PUT or POST
458
+ transfer), the block size given in the Block1 Option indicates the
459
+ block size preference of the server for this resource (control usage).
460
+ Obviously, at this point the first block has already been transferred
461
+ by the client without benefit of this knowledge. Still, the client
462
+ SHOULD heed the preference and, for all further blocks, use the block
463
+ size preferred by the server or a smaller one. Note that any
464
+ reduction in the block size may mean that the second request starts
465
+ with a block number larger than one, as the first request already
466
+ transferred multiple blocks as counted in the smaller size.
467
+
468
+ To counter the effects of adaptation layer fragmentation on packet
469
+ delivery probability, a client may want to give up retransmitting a
470
+ request with a relatively large payload even before MAX_RETRANSMIT has
471
+ been reached, and try restating the request as a block-wise transfer
472
+ with a smaller payload. Note that this new attempt is then a new
473
+ message-layer transaction and requires a new Message ID.
474
+ (Because of the uncertainty whether the request or the acknowledgement
475
+ was lost, this strategy is useful mostly for idempotent requests.)
476
+
477
+ In a blockwise transfer of a request payload (e.g., a PUT or POST) that is intended to be implemented in an
478
+ atomic fashion at the server, the actual creation/replacement takes
479
+ place at the time the final block, i.e. a block with the M bit unset
480
+ in the Block1 Option, is received. If not
481
+ all previous blocks are available at the server at this time, the
482
+ transfer fails and error code 4.08 (Request Entity Incomplete) MUST be returned. The error
483
+ code 4.13 (Request Entity Too Large) can be returned at any time by a server that does not
484
+ currently have the resources to store blocks for a block-wise request payload transfer that it would intend to implement in an atomic fashion.
485
+
486
+ If multiple concurrently proceeding block-wise request payload
487
+ transfer (e.g., PUT or POST) operations
488
+ are possible, the requester SHOULD use the Token Option to clearly separate the different sequences.
489
+ In this case, when reassembling the representation from the blocks
490
+ being exchanged to enable atomic processing, the reassembler MUST
491
+ compare any Token Options present (and, as usual, taking an absent Token Option
492
+ to default to the empty Token).
493
+ If atomic processing is not desired, there is no need to process the
494
+ Token Option (but it is still returned in the response as usual).
495
+
496
+ Examples
497
+ ========
498
+
499
+ This section gives a number of short examples with message flows for a
500
+ block-wise GET, and for a PUT or POST.
501
+ These examples demonstrate the basic operation, the operation in the
502
+ presence of retransmissions, and examples for the operation of the
503
+ block size negotiation.
504
+
505
+ In all these examples, a Block option is shown in a decomposed way
506
+ separating the kind of Block option (1 or 2), block number (NUM), more bit (M), and block size exponent
507
+ (2\*\*(SZX+4)) by slashes. E.g., a Block2 Option value of 33 would be shown as
508
+ 2/2/0/32), or a Block1 Option value of 59 would be shown as 1/3/1/128.
509
+
510
+ The first example ({{simple-get}}) shows a GET request that is split
511
+ into three blocks.
512
+ The server proposes a block size of 128, and the client agrees.
513
+ The first two ACKs contain 128 bytes of payload each, and third ACK
514
+ contains between 1 and 128 bytes.
515
+
516
+ ~~~~~~~~~~~
517
+ CLIENT SERVER
518
+ | |
519
+ | CON [MID=1234], GET, /status ------> |
520
+ | |
521
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
522
+ | |
523
+ | CON [MID=1235], GET, /status, 2/1/0/128 ------> |
524
+ | |
525
+ | <------ ACK [MID=1235], 2.05 Content, 2/1/1/128 |
526
+ | |
527
+ | CON [MID=1236], GET, /status, 2/2/0/128 ------> |
528
+ | |
529
+ | <------ ACK [MID=1236], 2.05 Content, 2/2/0/128 |
530
+ ~~~~~~~~~~~
531
+ {: #simple-get title="Simple blockwise GET"}
532
+
533
+
534
+ In the second example ({{early-get}}), the client anticipates the blockwise transfer
535
+ (e.g., because of a size indication in the link-format description)
536
+ and sends a size proposal. All ACK messages except for the last carry
537
+ 64 bytes of payload; the last one carries between 1 and 64 bytes.
538
+
539
+
540
+ ~~~~~~~~~~~
541
+ CLIENT SERVER
542
+ | |
543
+ | CON [MID=1234], GET, /status, 2/0/0/64 ------> |
544
+ | |
545
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/64 |
546
+ | |
547
+ | CON [MID=1235], GET, /status, 2/1/0/64 ------> |
548
+ | |
549
+ | <------ ACK [MID=1235], 2.05 Content, 2/1/1/64 |
550
+ : :
551
+ : ... :
552
+ : :
553
+ | CON [MID=1238], GET, /status, 2/4/0/64 ------> |
554
+ | |
555
+ | <------ ACK [MID=1238], 2.05 Content, 2/4/1/64 |
556
+ | |
557
+ | CON [MID=1239], GET, /status, 2/5/0/64 ------> |
558
+ | |
559
+ | <------ ACK [MID=1239], 2.05 Content, 2/5/0/64 |
560
+ ~~~~~~~~~~~
561
+ {: #early-get title="Blockwise GET with early negotiation" }
562
+
563
+ In the third example ({{late-get}}), the client is surprised by the
564
+ need for a blockwise transfer, and unhappy with the size chosen
565
+ unilaterally by the server. As it did not send a size proposal
566
+ initially, the negotiation only influences the size from the second
567
+ message exchange onward. Since the client already obtained both the first and
568
+ second 64-byte block in the first 128-byte exchange, it goes on
569
+ requesting the third 64-byte block ("2/0/64"). None of this is (or
570
+ needs to be) understood by the server, which simply responds to the
571
+ requests as it best can.
572
+
573
+
574
+ ~~~~~~~~~~~
575
+ CLIENT SERVER
576
+ | |
577
+ | CON [MID=1234], GET, /status ------> |
578
+ | |
579
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
580
+ | |
581
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
582
+ | |
583
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
584
+ | |
585
+ | CON [MID=1236], GET, /status, 2/3/0/64 ------> |
586
+ | |
587
+ | <------ ACK [MID=1236], 2.05 Content, 2/3/1/64 |
588
+ | |
589
+ | CON [MID=1237], GET, /status, 2/4/0/64 ------> |
590
+ | |
591
+ | <------ ACK [MID=1237], 2.05 Content, 2/4/1/64 |
592
+ | |
593
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
594
+ | |
595
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
596
+ ~~~~~~~~~~~
597
+ {: #late-get title="Blockwise GET with late negotiation" }
598
+
599
+ In all these (and the following) cases, retransmissions are handled by
600
+ the CoAP message exchange layer, so they don't influence the block
601
+ operations ({{late-get-lost-con}}, {{late-get-lost-ack}}).
602
+
603
+
604
+ ~~~~~~~~~~~
605
+ CLIENT SERVER
606
+ | |
607
+ | CON [MID=1234], GET, /status ------> |
608
+ | |
609
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
610
+ | |
611
+ | CON [MID=1235], GE///////////////////////// |
612
+ | |
613
+ | (timeout) |
614
+ | |
615
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
616
+ | |
617
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
618
+ : :
619
+ : ... :
620
+ : :
621
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
622
+ | |
623
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
624
+ ~~~~~~~~~~~
625
+ {: #late-get-lost-con title="Blockwise GET with late negotiation and
626
+ lost CON" }
627
+
628
+
629
+ ~~~~~~~~~~~
630
+ CLIENT SERVER
631
+ | |
632
+ | CON [MID=1234], GET, /status ------> |
633
+ | |
634
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
635
+ | |
636
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
637
+ | |
638
+ | //////////////////////////////////tent, 2/2/1/64 |
639
+ | |
640
+ | (timeout) |
641
+ | |
642
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
643
+ | |
644
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
645
+ : :
646
+ : ... :
647
+ : :
648
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
649
+ | |
650
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
651
+ ~~~~~~~~~~~
652
+ {: #late-get-lost-ack title="Blockwise GET with late negotiation and
653
+ lost ACK" }
654
+
655
+ The following examples demonstrate a PUT exchange; a POST exchange
656
+ looks the same, with different requirements on atomicity/idempotence.
657
+ To ensure that the blocks relate to the same version of the resource
658
+ representation carried in the request, the client in
659
+ {{simple-put-atomic}} sets the Token to
660
+ "v17" in all requests. Note that, as with the GET, the responses to
661
+ the requests that have a more bit in the request Block2 Option are
662
+ provisional; only the final response tells the client that the PUT
663
+ succeeded.
664
+
665
+
666
+ ~~~~~~~~~~~
667
+ CLIENT SERVER
668
+ | |
669
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
670
+ | |
671
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/1/128 |
672
+ | |
673
+ | CON [MID=1235], PUT, /options, v17, 1/1/1/128 ------> |
674
+ | |
675
+ | <------ ACK [MID=1235], 2.04 Changed, 1/1/1/128 |
676
+ | |
677
+ | CON [MID=1236], PUT, /options, v17, 1/2/0/128 ------> |
678
+ | |
679
+ | <------ ACK [MID=1236], 2.04 Changed, 1/2/0/128 |
680
+ ~~~~~~~~~~~
681
+ {: #simple-put-atomic title="Simple atomic blockwise PUT" }
682
+
683
+ A stateless server that simply builds/updates the resource in place
684
+ (statelessly) may indicate this by not setting the more bit in the
685
+ response ({{simple-put-stateless}}); in this case, the response codes are valid separately for
686
+ each block being updated. This is of course only an acceptable
687
+ behavior of the server if the potential inconsistency present during
688
+ the run of the message exchange sequence does not lead to problems,
689
+ e.g. because the resource being created or changed is not yet or not currently in
690
+ use.
691
+
692
+
693
+ ~~~~~~~~~~~
694
+ CLIENT SERVER
695
+ | |
696
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
697
+ | |
698
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/0/128 |
699
+ | |
700
+ | CON [MID=1235], PUT, /options, v17, 1/1/1/128 ------> |
701
+ | |
702
+ | <------ ACK [MID=1235], 2.04 Changed, 1/1/0/128 |
703
+ | |
704
+ | CON [MID=1236], PUT, /options, v17, 1/2/0/128 ------> |
705
+ | |
706
+ | <------ ACK [MID=1236], 2.04 Changed, 1/2/0/128 |
707
+ ~~~~~~~~~~~
708
+ {: #simple-put-stateless title="Simple stateless blockwise PUT" }
709
+
710
+ Finally, a server receiving a blockwise PUT or POST may want to indicate a
711
+ smaller block size preference ({{simple-put-atomic-nego}}).
712
+ In this case, the client SHOULD continue with a smaller block size; if
713
+ it does, it MUST adjust the block number to properly count in that smaller size.
714
+
715
+
716
+
717
+ ~~~~~~~~~~~
718
+ CLIENT SERVER
719
+ | |
720
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
721
+ | |
722
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/1/32 |
723
+ | |
724
+ | CON [MID=1235], PUT, /options, v17, 1/4/1/32 ------> |
725
+ | |
726
+ | <------ ACK [MID=1235], 2.04 Changed, 1/4/1/32 |
727
+ | |
728
+ | CON [MID=1236], PUT, /options, v17, 1/5/1/32 ------> |
729
+ | |
730
+ | <------ ACK [MID=1235], 2.04 Changed, 1/5/1/32 |
731
+ | |
732
+ | CON [MID=1237], PUT, /options, v17, 1/6/0/32 ------> |
733
+ | |
734
+ | <------ ACK [MID=1236], 2.04 Changed, 1/6/0/32 |
735
+ ~~~~~~~~~~~
736
+ {: #simple-put-atomic-nego title="Simple atomic blockwise PUT with
737
+ negotiation" }
738
+
739
+
740
+ HTTP Mapping Considerations {#http-mapping}
741
+ ===========================
742
+
743
+
744
+ In this subsection, we give some brief examples for the influence the
745
+ Block options might have on intermediaries that map between CoAP and
746
+ HTTP.
747
+
748
+ For mapping CoAP requests to HTTP, the intermediary may want to map
749
+ the sequence of block-wise transfers into a single HTTP transfer.
750
+ E.g., for a GET request, the intermediary could perform the HTTP
751
+ request once the first block has been requested and could then fulfill
752
+ all further block requests out of its cache.
753
+ A constrained implementation may not be able to cache the entire
754
+ object and may use a combination of TCP flow control and (in
755
+ particular if timeouts occur) HTTP range requests to obtain the
756
+ information necessary for the next block transfer at the right time.
757
+
758
+ For PUT or POST requests, there is more variation in how HTTP servers
759
+ might implement ranges. Some WebDAV servers do, but in general the
760
+ CoAP-to-HTTP intermediary will have to try sending the payload of all
761
+ the blocks of a block-wise transfer within one HTTP request. If
762
+ enough buffering is available, this request can be started when the
763
+ last CoAP block is received. A constrained implementation may want to
764
+ relieve its buffering by already starting to send the HTTP request at
765
+ the time the first CoAP block is received; any HTTP 408 status code
766
+ that indicates that the HTTP server became impatient with the
767
+ resulting transfer can then be mapped into a CoAP 4.08 response code
768
+ (similarly, 413 maps to 4.13).
769
+
770
+ For mapping HTTP to CoAP, the intermediary may want to map a single
771
+ HTTP transfer into a sequence of block-wise transfers.
772
+ If the HTTP client is too slow delivering a request body on a PUT or
773
+ POST, the CoAP server might time out and return a 4.08
774
+ response code, which in turn maps well to an HTTP 408 status code
775
+ (again, 4.13 maps to 413).
776
+ HTTP range requests received on the HTTP side may be served out of a
777
+ cache and/or mapped to GET
778
+ requests that request a sequence of blocks overlapping the range.
779
+
780
+ (Note that, while the semantics of CoAP 4.08 and HTTP 408 differ, this
781
+ difference is largely due to the different way the two protocols are
782
+ mapped to transport. HTTP has an underlying TCP connection, which
783
+ supplies connection state, so a HTTP 408 status code can immediately
784
+ be used to indicate that a timeout occurred during transmitting a
785
+ request through that active TCP connection.
786
+ The CoAP 4.08 response code indicates one or more missing blocks,
787
+ which may be due to timeouts or resource constraints; as there is no
788
+ connection state, there is no way to deliver such a response
789
+ immediately; instead, it is delivered on the next block transfer.
790
+ Still, HTTP 408 is probably the best mapping back to HTTP, as the
791
+ timeout is the most likely cause for a CoAP 4.08.
792
+ Note that there is no way to distinguish a timeout from a missing
793
+ block for a server without creating additional state, the need for
794
+ which we want to avoid.)
795
+
796
+
797
+ IANA Considerations
798
+ ===================
799
+
800
+ This draft adds the following option numbers to the CoAP Option
801
+ Numbers registry of
802
+ {{I-D.ietf-core-coap}}:
803
+
804
+ | Number | Name | Reference |
805
+ |-------:+--------+----------- |
806
+ | 17 | Block2 | {{&SELF}} |
807
+ | 19 | Block1 | {{&SELF}} |
808
+ {: #tab-option-registry title="CoAP Option Numbers"}
809
+
810
+
811
+ This draft adds the following response code to the CoAP Response Codes registry of
812
+ {{I-D.ietf-core-coap}}:
813
+
814
+ | Code | Description | Reference |
815
+ |-----:+--------------------------------+----------- |
816
+ | 136 | 4.08 Request Entity Incomplete | {{&SELF}} |
817
+ {: #tab-response-code-registry title="CoAP Response Codes"}
818
+
819
+
820
+ Security Considerations
821
+ =======================
822
+
823
+ Providing access to blocks within a resource may lead to
824
+ surprising vulnerabilities.
825
+ Where requests are not implemented atomically, an attacker may be able
826
+ to exploit a race condition or confuse a server by inducing it to use
827
+ a partially updated resource representation.
828
+ Partial transfers may also make certain problematic data invisible to
829
+ intrusion detection systems; it is RECOMMENDED that an intrusion
830
+ detection system (IDS) that analyzes resource representations transferred by
831
+ CoAP implement the Block options to gain access to entire resource representations.
832
+ Still, approaches such as transferring even-numbered blocks on one path and odd-numbered
833
+ blocks on another path, or even transferring blocks multiple times
834
+ with different content and
835
+ obtaining a different interpretation of temporal order at the IDS than
836
+ at the server, may prevent an IDS from seeing the whole picture.
837
+ These kinds of attacks are well understood from IP fragmentation and
838
+ TCP segmentation; CoAP does not add fundamentally new considerations.
839
+
840
+ Where access to a resource is only granted to clients making use of a specific security
841
+ association, all blocks of that resource MUST be subject to the same
842
+ security checks; it MUST NOT be possible for unprotected exchanges to
843
+ influence blocks of an otherwise protected resource.
844
+ As a related consideration, where object security is employed,
845
+ PUT/POST should be implemented in the atomic fashion, unless the
846
+ object security operation is performed on each access and the
847
+ creation of unusable resources can be tolerated.
848
+
849
+ Mitigating Resource Exhaustion Attacks {#mitigating-exhaustion-attacks}
850
+ --------------------------------------
851
+
852
+ Certain blockwise requests may induce the server to create state, e.g. to
853
+ create a snapshot for the blockwise GET of a fast-changing resource
854
+ to enable consistent access to the same
855
+ version of a resource for all blocks, or to create temporary
856
+ resource representations that are collected until pressed into
857
+ service by a final PUT or POST with the more bit unset.
858
+ All mechanisms that induce a server to create state that cannot simply
859
+ be cleaned up create opportunities for denial-of-service attacks.
860
+ Servers SHOULD avoid being subject to resource exhaustion based on state
861
+ created by untrusted sources.
862
+ But even if this is done, the mitigation may cause a denial-of-service
863
+ to a legitimate request when it is drowned out by other state-creating
864
+ requests.
865
+ Wherever possible, servers should therefore minimize the opportunities
866
+ to create state for untrusted sources, e.g. by using stateless approaches.
867
+
868
+ Performing segmentation at the application layer is almost always
869
+ better in this respect than at the transport layer or lower (IP fragmentation,
870
+ adaptation layer fragmentation), e.g. because there is application
871
+ layer semantics that can be used for mitigation or because lower
872
+ layers provide security associations that can prevent attacks.
873
+ However, it is less common to apply timeouts and keepalive mechanisms
874
+ at the application layer than at lower layers. Servers MAY want to
875
+ clean up accumulated state by timing it out (cf. response code 4.08), and
876
+ clients SHOULD be prepared to run blockwise transfers in an expedient
877
+ way to minimize the likelihood of running into such a timeout.
878
+
879
+ Mitigating Amplification Attacks {#mitigating-amplification-attacks}
880
+ --------------------------------
881
+
882
+ {{I-D.ietf-core-coap}} discusses the susceptibility of
883
+ CoAP end-points for use in amplification attacks.
884
+
885
+ A CoAP server can reduce the amount of amplification it provides to an
886
+ attacker by offering large resource representations only in relatively
887
+ small blocks. With this, e.g., for a 1000 byte resource, a 10-byte request might
888
+ result in an 80-byte response (with a 64-byte block) instead of a
889
+ 1016-byte response, considerably reducing the amplification provided.
890
+
891
+
892
+ Acknowledgements
893
+ ================
894
+
895
+ Much of the content of this draft is the result of
896
+ discussions with the {{I-D.ietf-core-coap}} authors, and via many CoRE
897
+ WG discussions. Tokens were suggested by Gilman Tolle and refined by
898
+ Klaus Hartke.
899
+
900
+ Charles Palmer provided extensive editorial comments to a previous
901
+ version of this draft, some of which the authors hope to have covered
902
+ in this version.
903
+
904
+
905
+
906
+ --- back
907
+
908
+ Historical Note {#compat}
909
+ ===============
910
+
911
+ (This appendix to be deleted by the RFC editor.)
912
+
913
+ An earlier version of this draft used a single option:
914
+
915
+ | Type | C/E | Name | Format | Length | Default |
916
+ |-----:+----------+-------+--------+--------+--------------- |
917
+ | 13 | Critical | Block | uint | 1-3 B | 0 (see below) |
918
+
919
+
920
+ Note that this option number has since been reallocated in
921
+ {{I-D.ietf-core-coap}}; no backwards compatibility is provided after
922
+ July 1st, 2011.
923
+
924
+ --- fluff
925
+
926
+ <!-- LocalWords: CoAP datagram CoRE WG RESTful IP ETag reassembler
927
+ -->
928
+ <!-- LocalWords: blockwise idempotence statelessly keepalive SZX
929
+ -->
930
+ <!-- LocalWords: acknowledgement retransmissions ACKs ACK untrusted
931
+ -->
932
+ <!-- LocalWords: acknowledgements interoperability retransmission
933
+ -->
934
+ <!-- LocalWords: BCP atomicity NUM WebDAV IANA
935
+ -->