draft-ietf-core-href-01.txt   draft-ietf-core-href-02.txt 
CoRE Working Group K. Hartke CoRE Working Group K. Hartke
Internet-Draft Ericsson Internet-Draft Ericsson
Intended status: Standards Track November 4, 2019 Intended status: Standards Track 8 January 2020
Expires: May 7, 2020 Expires: 11 July 2020
Constrained Resource Identifiers Constrained Resource Identifiers
draft-ietf-core-href-01 draft-ietf-core-href-02
Abstract Abstract
Constrained Resource Identifiers (CoRIs) are an alternate Constrained Resource Identifiers (CoRIs) are an alternate
serialization of Uniform Resource Identifiers (URIs) that encodes the serialization of Uniform Resource Identifiers (URIs) that encodes the
URI components in Concise Binary Object Representation (CBOR) instead URI components in Concise Binary Object Representation (CBOR) instead
of a string of characters. This simplifies parsing, reference of a string of characters. This simplifies parsing, reference
resolution, and comparison of URIs in environments with severe resolution, and comparison of URIs in environments with severe
limitations on processing power, code size, and memory size. limitations on processing power, code size, and memory size.
Note to Readers
This note is to be removed before publishing as an RFC.
The issues list for this Internet-Draft can be found at
<https://github.com/core-wg/coral/labels/href>.
A reference implementation and a set of test vectors can be found at
<https://github.com/core-wg/coral/tree/master/binary/python>.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on May 7, 2020. This Internet-Draft will expire on 11 July 2020.
Copyright Notice Copyright Notice
Copyright (c) 2019 IETF Trust and the persons identified as the Copyright (c) 2020 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents (https://trustee.ietf.org/
(https://trustee.ietf.org/license-info) in effect on the date of license-info) in effect on the date of publication of this document.
publication of this document. Please review these documents Please review these documents carefully, as they describe your rights
carefully, as they describe your rights and restrictions with respect and restrictions with respect to this document. Code Components
to this document. Code Components extracted from this document must extracted from this document must include Simplified BSD License text
include Simplified BSD License text as described in Section 4.e of as described in Section 4.e of the Trust Legal Provisions and are
the Trust Legal Provisions and are provided without warranty as provided without warranty as described in the Simplified BSD License.
described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 1. Introduction
1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 1.1. Notational Conventions
2. Data Model . . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Data Model
2.1. Options . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1. Options
2.2. Option Sequences . . . . . . . . . . . . . . . . . . . . 4 2.2. Option Sequences
3. CBOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. CBOR
4. Python . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4. Python
4.1. Reference Resolution . . . . . . . . . . . . . . . . . . 9 4.1. Reference Resolution
4.2. URI Recomposition . . . . . . . . . . . . . . . . . . . . 10 4.2. URI Recomposition
4.3. CoAP Encoding . . . . . . . . . . . . . . . . . . . . . . 12 4.3. CoAP Encoding
5. Security Considerations . . . . . . . . . . . . . . . . . . . 14 5. Security Considerations
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 6. IANA Considerations
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 14 7. References
7.1. Normative References . . . . . . . . . . . . . . . . . . 14 7.1. Normative References
7.2. Informative References . . . . . . . . . . . . . . . . . 15 7.2. Informative References
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 15 Appendix A. Change Log
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 15 Acknowledgements
Author's Address
1. Introduction 1. Introduction
Uniform Resource Identifier (URI) references [RFC3986] are the Uniform Resource Identifier (URI) references [RFC3986] are the
standard way to link to resources in hypertext formats such as HTML standard way to link to resources in hypertext formats such as HTML
[W3C.REC-html52-20171214] or the HTTP "Link" header field [RFC8288]. [W3C.REC-html52-20171214] or the HTTP "Link" header field [RFC8288].
A URI reference is either a URI or a relative reference that must be A URI reference is either a URI or a relative reference that must be
resolved against a base URI. resolved against a base URI.
URI references are strings of characters chosen from the repertoire URI references are strings of characters chosen from the repertoire
skipping to change at page 3, line 49 skipping to change at line 151
Every option consists of an _option number_ identifying the type of Every option consists of an _option number_ identifying the type of
option (scheme, host name, path segment, etc.) and an _option value_. option (scheme, host name, path segment, etc.) and an _option value_.
2.1. Options 2.1. Options
The following types of options are defined: The following types of options are defined:
scheme scheme
Specifies the URI scheme. The option value can be any Unicode Specifies the URI scheme. The option value can be any Unicode
string matching the "scheme" rule described in Section 3.1 of RFC string matching the "scheme" rule described in Section 3.1 of RFC
3986 [RFC3986]. 3986 [RFC3986], excluding uppercase letters.
host.name host.name
Specifies the host of the URI authority as a registered name. The Specifies the host of the URI authority as a registered name. The
option value can be any Unicode string matching the specifications option value can be any Unicode string matching the specifications
of the URI scheme. of the URI scheme.
host.ip host.ip
Specifies the host of the URI authority as an IPv4 address or an Specifies the host of the URI authority as an IPv4 address or an
IPv6 address. The option value is a byte string with a length of IPv6 address. The option value is a byte string with a length of
either 4 or 16 bytes, respectively. either 4 or 16 bytes, respectively.
port port
Specifies the port number of the URI authority. The option value Specifies the port number of the URI authority. The option value
is an integer in the range from 0 to 65535. is an integer in the range from 0 to 65535.
path.type path.type
Specifies the type of the URI path for reference resolution. The Specifies the type of the URI path for reference resolution. The
option value is an integer in the range from 0 to 127, named as option value is an integer in the range from 0 to 127, named as
follows: follows:
0 - absolute-path 0 absolute-path
1 - append-relation 1 append-relation
2 - append-path 2 append-path
3 - relative-path 3 relative-path
4 - relative-path-1up 4 relative-path-1up
5 - relative-path-2up 5 relative-path-2up
6 - relative-path-3up 6 relative-path-3up
7 - relative-path-4up 7 relative-path-4up
... ...
127 relative-path-124up
path path
Specifies one segment of the URI path. The option value can be Specifies one segment of the URI path. The option value can be
any Unicode string with the exception of "." and "..". This any Unicode string with the exception of "." and "..". This
option can occur more than once. option can occur more than once.
query query
Specifies one argument of the URI query. The option value can be Specifies one argument of the URI query. The option value can be
any Unicode string. This option can occur more than once. any Unicode string. This option can occur more than once.
skipping to change at page 5, line 4 skipping to change at line 199
Specifies one argument of the URI query. The option value can be Specifies one argument of the URI query. The option value can be
any Unicode string. This option can occur more than once. any Unicode string. This option can occur more than once.
fragment fragment
Specifies the fragment identifier. The option value can be any Specifies the fragment identifier. The option value can be any
Unicode string. Unicode string.
No percent-encoding is performed in option values. No percent-encoding is performed in option values.
2.2. Option Sequences 2.2. Option Sequences
_ host.name _ _ host.name _
____ scheme __/ \___ port _ ____ scheme __/ \___ port _
\ \________/ \__ host.ip __/ / \ \ \________/ \__ host.ip __/ / \
\__________________________/ ________/ \__________________________/ ________/
\ / ________ _________ \ / ________ _________
\ / / \ / \ \ / / \ / \
\__________ path.type __\_\_ path _/__\_ query _/__ fragment __ \__________ path.type __\_\_ path _/__\_ query _/__ fragment __
\___________/ \________/ \_________/ \__________/ \___________/ \________/ \_________/ \__________/
Figure 1: Structure of a Well-Formed Sequence of Options Figure 1: Structure of a Well-Formed Sequence of Options
A sequence of options is considered _well-formed_ if: A sequence of options is considered _well-formed_ if:
o the sequence of options is empty or starts with a "scheme", * the sequence of options is empty or starts with a "scheme",
"host.name", "host.ip", "port", "path.type", "path", "query", or "host.name", "host.ip", "port", "path.type", "path", "query", or
"fragment" option; "fragment" option;
o any "scheme" option is followed by either a "host.name" or a * any "scheme" option is followed by either a "host.name" or a
"host.ip" option; "host.ip" option;
o any "host.name" option is followed by a "port" option; * any "host.name" option is followed by a "port" option;
o any "host.ip" option is followed by a "port" option; * any "host.ip" option is followed by a "port" option;
o any "port" option is followed by a "path", "query", or "fragment" * any "port" option is followed by a "path", "query", or "fragment"
option or is at the end of the sequence; option or is at the end of the sequence;
o any "path.type" option is followed by a "path", "query", or * any "path.type" option is followed by a "path", "query", or
"fragment" option or is at the end of the sequence; "fragment" option or is at the end of the sequence;
o any "path" option is followed by a "path", "query", or "fragment" * any "path" option is followed by a "path", "query", or "fragment"
option or is at the end of the sequence; option or is at the end of the sequence;
o any "query" option is followed by a "query" or "fragment" option * any "query" option is followed by a "query" or "fragment" option
or is at the end of the sequence; and or is at the end of the sequence; and
o any "fragment" option is at the end of the sequence. * any "fragment" option is at the end of the sequence.
A well-formed sequence of options is considered _absolute_ if the A well-formed sequence of options is considered _absolute_ if the
sequence of options starts with a "scheme" option. sequence of options starts with a "scheme" option.
A well-formed sequence of options is considered _relative_ if the A well-formed sequence of options is considered _relative_ if the
sequence of options is empty or starts with an option other than a sequence of options is empty or starts with an option other than a
"scheme" option. "scheme" option.
An absolute sequence of options is considered _normalized_ if the An absolute sequence of options is considered _normalized_ if the
result of resolving the sequence of options against any base is equal result of resolving the sequence of options against any base is equal
skipping to change at page 7, line 14 skipping to change at line 300
3. CBOR 3. CBOR
In Concise Binary Object Representation (CBOR) [RFC7049], a sequence In Concise Binary Object Representation (CBOR) [RFC7049], a sequence
of options is encoded as an array that contains the option numbers of options is encoded as an array that contains the option numbers
and option values in alternating order. and option values in alternating order.
The structure can be described in the Concise Data Definition The structure can be described in the Concise Data Definition
Language (CDDL) [RFC8610] as follows: Language (CDDL) [RFC8610] as follows:
CoRI = [?(scheme: 1, text .regexp "[A-Za-z][A-Za-z0-9+.-]*"), CoRI = [?(scheme: 1, text .regexp "[a-z][a-z0-9+.-]*"),
?(host.name: 2, text // ?(host.name: 2, text //
host.ip: 3, bytes .size 4 / bytes .size 16), host.ip: 3, bytes .size 4 / bytes .size 16),
?(port: 4, 0..65535), ?(port: 4, 0..65535),
?(path.type: 5, 0..127), ?(path.type: 5, 0..127),
*(path: 6, text), *(path: 6, text),
*(query: 7, text), *(query: 7, text),
?(fragment: 8, text)] ?(fragment: 8, text)]
Example: Examples:
[1, "coap", 3, h'20010DB8000000000000000000000001', 4, 5683, 6, [1, "coap",
".well-known", 6, "core"] 3, h'C6336401',
4, 5683,
6, ".well-known",
6, "core"]
[5, 0, 6, ".well-known", 6, "core", 7, "rt=temperature-c"] [5, 0,
6, ".well-known",
6, "core",
7, "rt=temperature-c"]
4. Python 4. Python
In Python, a sequence of options is encoded as a list of tuples, In Python, a sequence of options is encoded as a list of tuples,
where each tuple contains one option number and one option value. where each tuple contains one option number and one option value.
The following Python 3.6 code illustrates how to check a sequence of The following Python 3.6 code illustrates how to check a sequence of
options for being well-formed, absolute, and relative. options for being well-formed, absolute, and relative.
<CODE BEGINS> <CODE BEGINS>
import enum import enum
class Option(enum.IntEnum): class Option(enum.IntEnum):
_BEGIN = 0 _BEGIN = 0
SCHEME = 1 SCHEME = 1
HOST_NAME = 2 HOST_NAME = 2
HOST_IP = 3 HOST_IP = 3
PORT = 4 PORT = 4
PATH_TYPE = 5 PATH_TYPE = 5
PATH = 6 PATH = 6
skipping to change at page 8, line 44 skipping to change at line 384
return False return False
return True return True
def is_absolute(href): def is_absolute(href):
return is_well_formed(href) and \ return is_well_formed(href) and \
(len(href) != 0 and href[0][0] == Option.SCHEME) (len(href) != 0 and href[0][0] == Option.SCHEME)
def is_relative(href): def is_relative(href):
return is_well_formed(href) and \ return is_well_formed(href) and \
(len(href) == 0 or href[0][0] != Option.SCHEME) (len(href) == 0 or href[0][0] != Option.SCHEME)
<CODE ENDS>
<CODE ENDS>
Examples: Examples:
[(Option.SCHEME, "coap"), (Option.HOST_IP, b"\x20\x01\x0D\xB8\x00\ [(Option.SCHEME, 'coap'),
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), (Option.PORT, (Option.HOST_IP, b'\xC6\x33\x64\x01'),
5683), (Option.PATH, ".well-known"), (Option.PATH, "core")] (Option.PORT, 5683),
(Option.PATH, '.well-known'),
(Option.PATH, 'core')]
[(Option.PATH_TYPE, PathType.ABSOLUTE_PATH), (Option.PATH, ".well- [(Option.PATH_TYPE, PathType.ABSOLUTE_PATH),
known"), (Option.PATH, "core"), (Option.QUERY, "rt=temperature- (Option.PATH, '.well-known'),
c")] (Option.PATH, 'core'),
(Option.QUERY, 'rt=temperature-c')]
4.1. Reference Resolution 4.1. Reference Resolution
The following Python 3.6 code defines how to resolve a sequence of The following Python 3.6 code defines how to resolve a sequence of
options that might be relative to a given base. options that might be relative to a given base.
<CODE BEGINS> <CODE BEGINS>
def resolve(base, href, relation=0): def resolve(base, href, relation=0):
if not is_absolute(base) or not is_well_formed(href): if not is_absolute(base) or not is_well_formed(href):
return None return None
result = [] result = []
option = Option.FRAGMENT option = Option.FRAGMENT
if len(href) != 0: if len(href) != 0:
option = href[0][0] option = href[0][0]
if option == Option.HOST_IP: if option == Option.HOST_IP:
option = Option.HOST_NAME option = Option.HOST_NAME
elif option == Option.PATH_TYPE: elif option == Option.PATH_TYPE:
skipping to change at page 10, line 15 skipping to change at line 452
if option > Option.PATH: if option > Option.PATH:
if len(output) >= 2 and \ if len(output) >= 2 and \
output[-1] == (Option.PATH, '') and ( output[-1] == (Option.PATH, '') and (
output[-2][0] < Option.PATH_TYPE or ( output[-2][0] < Option.PATH_TYPE or (
output[-2][0] == Option.PATH_TYPE and output[-2][0] == Option.PATH_TYPE and
output[-2][1] == PathType.ABSOLUTE_PATH)): output[-2][1] == PathType.ABSOLUTE_PATH)):
del output[-1] del output[-1]
if option > Option.FRAGMENT: if option > Option.FRAGMENT:
return return
output.append((option, value)) output.append((option, value))
<CODE ENDS>
<CODE ENDS>
4.2. URI Recomposition 4.2. URI Recomposition
The following Python 3.6 code defines how to recompose a URI from an The following Python 3.6 code defines how to recompose a URI from an
absolute sequence of options. absolute sequence of options.
<CODE BEGINS> <CODE BEGINS>
def recompose(href): def recompose(href):
if not is_absolute(href): if not is_absolute(href):
return None return None
result = '' result = ''
no_path = True no_path = True
first_query = True first_query = True
for option, value in href: for option, value in href:
if option == Option.SCHEME: if option == Option.SCHEME:
result += value + ':' result += value + ':'
elif option == Option.HOST_NAME: elif option == Option.HOST_NAME:
skipping to change at page 12, line 19 skipping to change at line 550
def _is_alpha(c): def _is_alpha(c):
return c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \ return c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
'abcdefghijklmnopqrstuvwxyz' 'abcdefghijklmnopqrstuvwxyz'
def _is_digit(c): def _is_digit(c):
return c in '0123456789' return c in '0123456789'
def _is_sub_delim(c): def _is_sub_delim(c):
return c in '!$&\'()*+,;=' return c in '!$&\'()*+,;='
<CODE ENDS>
<CODE ENDS>
4.3. CoAP Encoding 4.3. CoAP Encoding
The following Python 3.6 code illustrates how to construct CoAP The following Python 3.6 code illustrates how to construct CoAP
options from an absolute sequence of options. For simplicity, the options from an absolute sequence of options. For simplicity, the
code does not omit CoAP options with their default value. code does not omit CoAP options with their default value.
<CODE BEGINS> <CODE BEGINS>
def coap(href, to_proxy=False): def coap(href, to_proxy=False):
if not is_absolute(href): if not is_absolute(href):
return None return None
result = b'' result = b''
previous = 0 previous = 0
for option, value in href: for option, value in href:
if option == Option.SCHEME: if option == Option.SCHEME:
pass pass
elif option == Option.HOST_NAME: elif option == Option.HOST_NAME:
opt = 3 # Uri-Host opt = 3 # Uri-Host
skipping to change at page 14, line 4 skipping to change at line 630
length -= 256 + 13 length -= 256 + 13
result += bytes([length >> 8, length & 255]) result += bytes([length >> 8, length & 255])
result += value result += value
return result return result
def _encode_coap_option_nibble(n): def _encode_coap_option_nibble(n):
if n < 13: if n < 13:
return n return n
elif n < 256 + 13: elif n < 256 + 13:
return 13 return 13
elif n < 65536 + 256 + 13: elif n < 65536 + 256 + 13:
return 14 return 14
<CODE ENDS>
<CODE ENDS>
5. Security Considerations 5. Security Considerations
Parsers must operate on input that is assumed to be untrusted. This Parsers must operate on input that is assumed to be untrusted. This
means that parsers MUST fail gracefully in the face of malicious means that parsers MUST fail gracefully in the face of malicious
inputs. Additionally, parsers MUST be prepared to deal with resource inputs. Additionally, parsers MUST be prepared to deal with resource
exhaustion (e.g., resulting from the allocation of big data items) or exhaustion (e.g., resulting from the allocation of big data items) or
exhaustion of the call stack (stack overflow). See Section 8 of RFC exhaustion of the call stack (stack overflow). See Section 8 of RFC
7049 [RFC7049] for security considerations relating to CBOR. 7049 [RFC7049] for security considerations relating to CBOR.
skipping to change at page 15, line 34 skipping to change at line 707
DOI 10.17487/RFC7252, June 2014, DOI 10.17487/RFC7252, June 2014,
<https://www.rfc-editor.org/info/rfc7252>. <https://www.rfc-editor.org/info/rfc7252>.
[RFC8288] Nottingham, M., "Web Linking", RFC 8288, [RFC8288] Nottingham, M., "Web Linking", RFC 8288,
DOI 10.17487/RFC8288, October 2017, DOI 10.17487/RFC8288, October 2017,
<https://www.rfc-editor.org/info/rfc8288>. <https://www.rfc-editor.org/info/rfc8288>.
[W3C.REC-html52-20171214] [W3C.REC-html52-20171214]
Faulkner, S., Eicholz, A., Leithead, T., Danilo, A., and Faulkner, S., Eicholz, A., Leithead, T., Danilo, A., and
S. Moon, "HTML 5.2", World Wide Web Consortium S. Moon, "HTML 5.2", World Wide Web Consortium
Recommendation REC-html52-20171214, December 2017, Recommendation REC-html52-20171214, 14 December 2017,
<https://www.w3.org/TR/2017/REC-html52-20171214>. <https://www.w3.org/TR/2017/REC-html52-20171214>.
Appendix A. Change Log
This section is to be removed before publishing as an RFC.
Changes from -01 to -02:
* Changed the syntax of schemes to exclude upper case characters.
* Minor editorial improvements.
Changes from -00 to -01:
* None.
Acknowledgements Acknowledgements
Thanks to Christian Amsuess, Ari Keranen, and Dave Thaler for helpful Thanks to Christian Amsuess, Ari Keranen, Jim Schaad, and Dave Thaler
comments and discussions that have shaped the document. for helpful comments and discussions that have shaped the document.
Author's Address Author's Address
Klaus Hartke Klaus Hartke
Ericsson Ericsson
Torshamnsgatan 23 Torshamnsgatan 23
Stockholm SE-16483 SE-16483 Stockholm
Sweden Sweden
Email: klaus.hartke@ericsson.com Email: klaus.hartke@ericsson.com
 End of changes. 40 change blocks. 
81 lines changed or deleted 107 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/