[Docs] [txt|pdf|xml|html] [Tracker] [WG] [Email] [Diff1] [Diff2] [Nits]

Versions: (draft-hartke-t2trg-ciri) 00 01 02 03

CoRE Working Group                                             K. Hartke
Internet-Draft                                                  Ericsson
Intended status: Standards Track                            9 March 2020
Expires: 10 September 2020


                    Constrained Resource Identifiers
                        draft-ietf-core-href-03

Abstract

   The Constrained Resource Identifier (CRI) is a complement to the
   Uniform Resource Identifier (URI) that serializes the URI components
   in Concise Binary Object Representation (CBOR) instead of a sequence
   of characters.  This simplifies parsing, comparison and reference
   resolution in environments with severe 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

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 10 September 2020.

Copyright Notice

   Copyright (c) 2020 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Simplified BSD License text
   as described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Simplified BSD License.

Table of Contents

   1.  Introduction
     1.1.  Notational Conventions
   2.  Constraints
   3.  Creation and Normalization
   4.  Comparison
   5.  CRI References
     5.1.  CBOR Serialization
     5.2.  Reference Resolution
   6.  Relationship between CRIs, URIs and IRIs
     6.1.  Converting CRIs to URIs
   7.  Security Considerations
   8.  IANA Considerations
   9.  References
     9.1.  Normative References
     9.2.  Informative References
   Appendix A.  Change Log
   Acknowledgements
   Author's Address

1.  Introduction

   The Uniform Resource Identifier (URI) [RFC3986] and its most common
   usage, the URI reference, are the Internet standard for linking to
   resources in hypertext formats such as HTML [W3C.REC-html52-20171214]
   and the HTTP "Link" header field [RFC8288].

   A URI reference is a sequence of characters chosen from the
   repertoire of US-ASCII characters.  The individual components of a
   URI reference are delimited by a number of reserved characters, which
   necessitates the use of an escape mechanism ("percent-encoding") when
   these reserved characters are used in a non-delimiting function.  The
   resolution of URI references involves parsing a character sequence
   into its components, combining those components with the components
   of a base URI, merging path components, removing dot-segments, and
   recomposing the result back into a character sequence.

   Overall, the proper handling of URI references is relatively
   intricate.  This can be a problem, especially in constrained
   environments [RFC7228] where nodes often have severe code size and
   memory size limitations.  As a result, many implementations in such
   environments support only an ad-hoc, informally-specified, bug-
   ridden, non-interoperable subset of half of RFC 3986.

   This document defines the Constrained Resource Identifier (CRI) by
   constraining URIs to a simplified subset and serializing their
   components in Concise Binary Object Representation (CBOR)
   [RFC7049bis] instead of a sequence of characters.  This allows
   typical operations on URI references such as parsing, comparison and
   reference resolution to be implemented (including all corner cases)
   in a comparatively small amount of code.

   As a result of simplification, however, CRIs are not capable of
   expressing all URIs permitted by the generic syntax of RFC 3986
   (hence the "constrained" in "Constrained Resource Identifier").  The
   supported subset includes all URIs of the Constrained Application
   Protocol (CoAP) [RFC7252], most URIs of the Hypertext Transfer
   Protocol (HTTP) [RFC7230], and other URIs that are similar.  The
   exact constraints are defined in Section 2.

1.1.  Notational Conventions

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in BCP
   14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

   Terms defined in this document appear in _cursive_ where they are
   introduced (rendered in plain text as the new term surrounded by
   underscores).

2.  Constraints

   A Constrained Resource Identifier consists of the same five
   components as a URI: scheme, authority, path, query, and fragment.
   The components are subject to the following constraints:

   C1.   The scheme name can be any Unicode string (see Definition D80
         in [Unicode]) that matches the syntax defined in Section 3.1 of
         [RFC3986] and is lowercase (see Definition D139 in [Unicode]).

   C2.   An authority is always a host identified by an IP address or
         registered name, along with optional port information.  User
         information is not supported.

   C3.   An IP address can be either an IPv4 address or an IPv6 address.
         IPv6 scoped addressing zone identifiers and future versions of
         IP are not supported.

   C4.   A registered name can be any Unicode string that is lowercase
         and in Unicode Normalization Form C (NFC) (see Definition D120
         in [Unicode]).  (The syntax may be further restricted by the
         scheme.)

   C5.   A port is always an integer in the range from 0 to 65535.
         Empty ports or ports outside this range are not supported.

   C6.   The port is omitted if and only if the port would be the same
         as the scheme's default port (provided the scheme is defining
         such a default port) or the scheme is not using ports.

   C7.   A path consists of zero or more path segments.  A path must not
         consist of a single zero-length path segment, which is
         considered equivalent to a path of zero path segments.

   C8.   A path segment can be any Unicode string that is in NFC
         (including the zero-length string) with the exception of the
         special "." and ".." complete path segments.  No special
         constraints are placed on the first path segment.

   C9.   A query always consists of one or more query parameters.  A
         query parameter can be any Unicode string that is in NFC.  It
         is often in the form of a "key=value" pair.  When converting a
         CRI to a URI, query parameters are separated by an ampersand
         ("&") character.  (This matches the structure and encoding of
         the query in CoAP URIs.)

   C10.  A fragment identifier can be any Unicode string that is in NFC.

   C11.  The syntax of registered names, path segments, query
         parameters, and fragment identifiers may be further restricted
         and sub-structured by the scheme.  There is no support,
         however, for escaping sub-delimiters that are not intended to
         be used in a delimiting function.

   C12.  When converting a CRI to a URI, any character that is outside
         the allowed character range or a delimiter in the URI syntax is
         percent-encoded.  Percent-encoding always uses the UTF-8
         encoding form (see Definition D92 in [Unicode]) to convert the
         character to a sequence of one or more octets.

3.  Creation and Normalization

   Resource identifiers are generally created on the initial creation of
   a resource with a certain resource identifier, or the initial
   exposition of a resource under a particular resource identifier.

   A Constrained Resource Identifier SHOULD be created by the naming
   authority that governs the namespace of the resource identifier.  For
   example, for the resources of an HTTP origin server, that server is
   responsible for creating the CRIs for those resources.

   The creator MUST ensure that any CRI created satisfies the
   constraints defined in Section 2.  The creation of a CRI fails if the
   CRI cannot be validated to satisfy all of the constraints.

   If a creator creates a CRI from user input, it MAY apply the
   following (and only the following) normalizations to get the CRI more
   likely to validate: map the scheme name to lowercase (C1.); map the
   registered name to NFC (C4.); elide the port if it's the default port
   for the scheme (C6.); elide a single zero-length path segment (C7.);
   map path segments, query parameters and the fragment identifier to
   NFC (C8., C9., C10.).

   Once a CRI has been created, it can be used and transferred without
   further normalization.  All operations that operate on a CRI SHOULD
   rely on the assumption that the CRI is appropriately pre-normalized.
   (This does not contradict the requirement that when CRIs are
   transferred, recipients must operate on as-good-as untrusted input
   and fail gracefully in the face of malicious inputs.)

4.  Comparison

   One of the most common operations on CRIs is comparison: determining
   whether two CRIs are equivalent, without using the CRIs to access
   their respective resource(s).

   Determination of equivalence or difference of CRIs is based on simple
   component-wise comparison.  If two CRIs are identical component-by-
   component (using code-point-by-code-point comparison for components
   that are Unicode strings) then it is safe to conclude that they are
   equivalent.

   This comparison mechanism is designed to minimize false negatives
   while strictly avoiding false positives.  The constraints defined in
   Section 2 imply the most common forms of syntax- and scheme-based
   normalizations in URIs, but do not comprise protocol-based
   normalizations that require accessing the resources or detailed
   knowledge of the scheme's dereference algorithm.  False negatives can
   be caused by resource aliases and CRIs that do not fully satisfy the
   constraints.

   When CRIs are compared to select (or avoid) a network action, such as
   retrieval of a representation, fragment components (if any) should be
   excluded from the comparison.

5.  CRI References

   The most common usage of a Constrained Resource Identifier is to
   embed it in resource representations, e.g., to express a hyperlink
   between the represented resource and the resource identified by the
   CRI.

   This section defines the serialization of CRIs in Concise Binary
   Object Representation (CBOR) [RFC7049bis].  To reduce representation
   size, CRIs are not serialized directly.  Instead, CRIs are indirectly
   referenced through _CRI references_ that take advantage of
   hierarchical locality.  The CBOR serialization of CRI references is
   specified in Section 5.1.

   The only operation defined on a CRI reference is _reference
   resolution_: the act of transforming a CRI reference into a CRI.  An
   application MUST implement this operation by applying the algorithm
   specified in Section 5.2 or any algorithm that is functionally
   equivalent to it.

   The method of transforming a CRI into a CRI reference is unspecified;
   implementations are free to use any algorithm as long as reference
   resolution of the resulting CRI reference yields the original CRI.

   When testing for equivalence or difference, applications SHOULD NOT
   directly compare CRI references; the references should be resolved to
   their respective CRI before comparison.

5.1.  CBOR Serialization

   A CRI reference is encoded as a CBOR array [RFC7049bis] that contains
   a sequence of zero or more options.  Each option consists of an
   option number followed by an option value, holding one component or
   sub-component of the CRI reference.  To reduce size, both option
   numbers and option values are immediate elements of the CBOR array
   and appear in alternating order.

   Not all possible sequences of options denote a well-formed CRI
   reference.  The structure can be described in the Concise Data
   Definition Language (CDDL) [RFC8610] as follows:

      CRI-Reference = [
        (?scheme, ?((host.name // host.ip), ?port) // path.type),
        *path,
        *query,
        ?fragment
      ]

      scheme    = (0, text .regexp "[a-z][a-z0-9+.-]*")
      host.name = (1, text)
      host.ip   = (2, bytes .size 4 / bytes .size 16)
      port      = (3, 0..65535)
      path.type = (4, 0..127)
      path      = (5, text)
      query     = (6, text)
      fragment  = (7, text)

   The options correspond to the (sub-)components of a CRI, as described
   in Section 2, with the addition of the "path.type" option.  The
   "path.type" option can be used to express path prefixes like "/",
   "./", "../", "../../", etc.  The exact semantics of the option values
   are defined by Section 5.2.  A sequence of options that is empty or
   starts with a "path" option is equivalent the same sequence prefixed
   by a "path.type" option with value 2.

   Examples:

      [0, "coap",
       2, h'C6336401',
       3, 61616,
       5, ".well-known",
       5, "core"]

      [4, 0,
       5, ".well-known",
       5, "core",
       6, "rt=temperature-c"]

   A CRI reference is considered _absolute_ if the sequence of options
   starts with a "scheme" option.

   A CRI reference is considered _relative_ if the sequence of options
   is empty or starts with an option other than a "scheme" option.

5.2.  Reference Resolution

   The term "relative" implies that a "base CRI" exists against which
   the relative reference is applied.  Aside from fragment-only
   references, relative references are only usable when a base CRI is
   known.

   The following steps define the process of resolving any CRI reference
   against a base CRI so that the result is a CRI in the form of an
   absolute CRI reference:

   1.  Establish the base CRI of the CRI reference and express it in the
       form of an absolute CRI reference.  The base CRI can be
       established in a number of ways; see Section 5.1 of [RFC3986].

   2.  Determine the values of two variables, T and E, depending on the
       first option of the CRI reference to be resolved, according to
       Table 1.

    +---------------------+------------------+------------------------+
    | First Option Number | T                | E                      |
    +=====================+==================+========================+
    | 0 (scheme)          | 0                | 0                      |
    +---------------------+------------------+------------------------+
    | 1 (host.name)       | 0                | 1                      |
    +---------------------+------------------+------------------------+
    | 2 (host.ip)         | 0                | 1                      |
    +---------------------+------------------+------------------------+
    | 3 (port)            | (invalid sequence of options)             |
    +---------------------+------------------+------------------------+
    | 4 (path.type)       | option value - 1 | if T < 0 then 5 else 6 |
    +---------------------+------------------+------------------------+
    | 5 (path)            | 1                | 6                      |
    +---------------------+------------------+------------------------+
    | 6 (query)           | 0                | 6                      |
    +---------------------+------------------+------------------------+
    | 7 (fragment)        | 0                | 7                      |
    +---------------------+------------------+------------------------+
    | none/empty sequence | 0                | 7                      |
    +---------------------+------------------+------------------------+

                  Table 1: Values of the Variables T and E

   3.  Initialize a buffer with all the options from the base CRI where
       the option number is less than the value of E.

   4.  If the value of T is greater than 0, remove the last T-many
       "path" options from the end of the buffer (up to the number of
       "path" options in the buffer).

   5.  Append all the options from the CRI reference to the buffer,
       except for any "path.type" option.

   6.  If the buffer contains a single "path" option and the value of
       that option is the zero-length string, remove that option from
       the buffer.

   7.  Return the sequence of options in the buffer.

6.  Relationship between CRIs, URIs and IRIs

   CRIs are meant to replace both Uniform Resource Identifiers (URIs)
   [RFC3986] and Internationalized Resource Identifiers (IRIs) [RFC3987]
   in constrained environments [RFC7228].  Applications in these
   environments may never need to use URIs and IRIs directly, especially
   when the resource identifier is used simply for identification
   purposes or when the CRI can be directly converted into a CoAP
   request.

   However, it may be necessary in other environments to determine the
   associated URI or IRI of a CRI, and vice versa.  Applications can
   perform these conversions as follows:

   CRI to URI
      A CRI is converted to a URI as specified in Section 6.1.

   URI to CRI
      The method of converting a URI to a CRI is unspecified;
      implementations are free to use any algorithm as long as
      converting the resulting CRI back to a URI yields an equivalent
      URI.

   CRI to IRI
      A CRI can be converted to an IRI by first converting it to a URI,
      and then converting the URI to an IRI as described in Section 3.2
      of [RFC3987].

   IRI to CRI
      An IRI can be converted to a CRI by first converting it to a URI
      as described in Section 3.1 of [RFC3987], and then converting the
      URI to a CRI.

   Everything in this section also applies to CRI references, URI
   references and IRI references.

6.1.  Converting CRIs to URIs

   Applications MUST convert a CRI reference to a URI reference by
   determining the components of the URI reference according to the
   following steps and then recomposing the components to a URI
   reference string as specified in Section 5.3 of [RFC3986].

   scheme
      If the CRI reference contains a "scheme" option, the scheme
      component of the URI reference consists of the value of that
      option.  Otherwise, the scheme component is undefined.

   authority
      If the CRI reference contains a "host.name" or "host.ip" option,
      the authority component consists of the host subcomponent,
      optionally followed by a colon (":") character and the port
      subcomponent.  Otherwise, the authority component is undefined.

      The host subcomponent consists of the value of the "host.name" or
      "host.ip" option.

      Any character in the value of a "host.name" option that is not in
      the set of unreserved characters (Section 2.3 of [RFC3986]) or
      "sub-delims" (Section 2.2 of [RFC3986]) MUST be percent-encoded.

      The value of a "host.ip" option MUST be represented as a string
      that matches the "IPv4address" or "IP-literal" rule (Section 3.2.2
      of [RFC3986]).

      If the CRI reference contains a "port" option, the port
      subcomponent consists of the value of that option in decimal
      notation.  Otherwise, the colon (":") character and the port
      subcomponent are both omitted.

   path
      If the CRI reference is an empty sequence of options or starts
      with a "port" option, a "path" option, or a "path.type" option
      where the value is not 0, the conversion fails.

      If the CRI reference contains a "host.name" option, a "host.ip"
      option or a "path.type" option where the value is not 0, the path
      component of the URI reference is prefixed by a slash ("/")
      character.  Otherwise, the path component is prefixed by the empty
      string.

      If the CRI reference contains one or more "path" options, the
      prefix is followed by the value of each option, separated by a
      slash ("/") character.

      Any character in the value of a "path" option that is not in the
      set of unreserved characters or "sub-delims" or a colon (":") or
      commercial at ("@") character MUST be percent-encoded.

      If the authority component is defined and the path component does
      not match the "path-abempty" rule (Section 3.3 of [RFC3986]), the
      conversion fails.

      If the authority component is undefined and the scheme component
      is defined and the path component does not match the "path-
      absolute", "path-rootless" or "path-empty" rule (Section 3.3 of
      [RFC3986]), the conversion fails.

      If the authority component is undefined and the scheme component
      is undefined and the path component does not match the "path-
      absolute", "path-noscheme" or "path-empty" rule (Section 3.3 of
      [RFC3986]), the conversion fails.

   query
      If the CRI reference contains one or more "query" options, the
      query component of the URI reference consists of the value of each
      option, separated by an ampersand ("&") character.  Otherwise, the
      query component is undefined.

      Any character in the value of a "query" option that is not in the
      set of unreserved characters or "sub-delims" or a colon (":"),
      commercial at ("@"), slash ("/") or question mark ("?") character
      MUST be percent-encoded.  Additionally, any ampersand character
      ("&") in the option value MUST be percent-encoded.

   fragment
      If the CRI reference contains a fragment option, the fragment
      component of the URI reference consists of the value of that
      option.  Otherwise, the fragment component is undefined.

      Any character in the value of a "fragment" option that is not in
      the set of unreserved characters or "sub-delims" or a colon (":"),
      commercial at ("@"), slash ("/") or question mark ("?") character
      MUST be percent-encoded.

7.  Security Considerations

   Parsers of CRI references must operate on input that is assumed to be
   untrusted.  This means that parsers MUST fail gracefully in the face
   of malicious inputs.  Additionally, parsers MUST be prepared to deal
   with resource exhaustion (e.g., resulting from the allocation of big
   data items) or exhaustion of the call stack (stack overflow).  See
   Section 10 of [RFC7049bis] for additional security considerations
   relating to CBOR.

   The security considerations discussed in Section 7 of [RFC3986] and
   Section 8 of [RFC3987] for URIs and IRIs also apply to CRIs.

8.  IANA Considerations

   This document has no IANA actions.

9.  References

9.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,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
              Resource Identifier (URI): Generic Syntax", STD 66,
              RFC 3986, DOI 10.17487/RFC3986, January 2005,
              <https://www.rfc-editor.org/info/rfc3986>.

   [RFC3987]  Duerst, M. and M. Suignard, "Internationalized Resource
              Identifiers (IRIs)", RFC 3987, DOI 10.17487/RFC3987,
              January 2005, <https://www.rfc-editor.org/info/rfc3987>.

   [RFC7049bis]
              Bormann, C. and P. Hoffman, "Concise Binary Object
              Representation (CBOR)", Work in Progress, Internet-Draft,
              draft-ietf-cbor-7049bis-13, 8 March 2020,
              <https://tools.ietf.org/html/draft-ietf-cbor-7049bis-13>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

   [RFC8610]  Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
              Definition Language (CDDL): A Notational Convention to
              Express Concise Binary Object Representation (CBOR) and
              JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
              June 2019, <https://www.rfc-editor.org/info/rfc8610>.

   [Unicode]  The Unicode Consortium, "The Unicode Standard, Version
              12.1.0", ISBN 978-1-936213-25-2, May 2019,
              <http://www.unicode.org/versions/Unicode12.1.0/>.

9.2.  Informative References

   [RFC7228]  Bormann, C., Ersue, M., and A. Keranen, "Terminology for
              Constrained-Node Networks", RFC 7228,
              DOI 10.17487/RFC7228, May 2014,
              <https://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,
              <https://www.rfc-editor.org/info/rfc7230>.

   [RFC7252]  Shelby, Z., Hartke, K., and C. Bormann, "The Constrained
              Application Protocol (CoAP)", RFC 7252,
              DOI 10.17487/RFC7252, June 2014,
              <https://www.rfc-editor.org/info/rfc7252>.

   [RFC8288]  Nottingham, M., "Web Linking", RFC 8288,
              DOI 10.17487/RFC8288, October 2017,
              <https://www.rfc-editor.org/info/rfc8288>.

   [W3C.REC-html52-20171214]
              Faulkner, S., Eicholz, A., Leithead, T., Danilo, A., and
              S. Moon, "HTML 5.2", World Wide Web Consortium
              Recommendation REC-html52-20171214, 14 December 2017,
              <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 -02 to -03:

   *  Expanded the set of supported schemes (#3).

   *  Specified creation, normalization and comparison (#9).

   *  Clarified the default value of the "path.type" option (#33).

   *  Removed the "append-relation" path type (#41).

   *  Renumbered the remaining path types.

   *  Renumbered the option numbers.

   *  Restructured the document.

   *  Minor editorial improvements.

   Changes from -01 to -02:

   *  Changed the syntax of schemes to exclude upper case characters
      (#13).

   *  Minor editorial improvements (#34 #37).

   Changes from -00 to -01:

   *  None.

Acknowledgements

   Thanks to Christian Amsuess, Carsten Bormann, Ari Keranen, Jim Schaad
   and Dave Thaler for helpful comments and discussions that have shaped
   the document.

Author's Address

   Klaus Hartke
   Ericsson
   Torshamnsgatan 23
   SE-16483 Stockholm
   Sweden

   Email: klaus.hartke@ericsson.com


Html markup produced by rfcmarkup 1.129d, available from https://tools.ietf.org/tools/rfcmarkup/