Thing-to-Thing Research Group                                  K. Hartke
Internet-Draft                                                  Ericsson
Intended status: Experimental                           October 22, 2018
Expires: April 25, 2019


           Constrained Internationalized Resource Identifiers
                       draft-hartke-t2trg-ciri-00

Abstract

   This document specifies Constrained Internationalized Resource
   Identifier References, a serialization of Internationalized Resource
   Identifier (IRI) references that encodes the IRI components as
   Concise Binary Object Representation (CBOR) data items rather than a
   string of characters.  This intends to simplify parsing, reference
   resolution, and comparison of IRIs in Constrained RESTful
   Environments (CoRE).

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 April 25, 2019.

Copyright Notice

   Copyright (c) 2018 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



Hartke                   Expires April 25, 2019                 [Page 1]


Internet-Draft              Constrained IRIs                October 2018


   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
     1.1.  Requirements Notation . . . . . . . . . . . . . . . . . .   3
   2.  Data Model  . . . . . . . . . . . . . . . . . . . . . . . . .   3
     2.1.  Options . . . . . . . . . . . . . . . . . . . . . . . . .   3
     2.2.  Option Sequences  . . . . . . . . . . . . . . . . . . . .   4
   3.  CBOR  . . . . . . . . . . . . . . . . . . . . . . . . . . . .   6
   4.  Python  . . . . . . . . . . . . . . . . . . . . . . . . . . .   6
     4.1.  Reference Resolution  . . . . . . . . . . . . . . . . . .   8
     4.2.  IRI Recomposition . . . . . . . . . . . . . . . . . . . .   9
     4.3.  CoAP Encoding . . . . . . . . . . . . . . . . . . . . . .  12
   5.  Security Considerations . . . . . . . . . . . . . . . . . . .  13
   6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  14
   7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  14
     7.1.  Normative References  . . . . . . . . . . . . . . . . . .  14
     7.2.  Informative References  . . . . . . . . . . . . . . . . .  14
   Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  15
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  15

1.  Introduction

   URI references [RFC3986] and, albeit less prevalently, IRI references
   [RFC3987] are the standard way to link to resources in hypertext
   formats like HTML [W3C.REC-html52-20171214] and the CoRE Link Format
   [RFC6690].  They encode the components of a resource reference either
   as an absolute URI/IRI or as a relative reference that must be
   resolved against a base URI/IRI to receive an absolute URI/IRI.

   URI and IRI references are strings of characters where the characters
   are chosen from a limited subset of the repertoires of US-ASCII and
   Unicode characters, respectively.  The individual components of a URI
   or IRI reference are delimited by a number of reserved characters,
   which necessitates the use of percent-encoding when these reserved
   characters are used in a non-delimiting function.  The resolution of
   references involves parsing URI/IRI references into their components,
   combining those components with the components of the base URI/IRI,
   merging paths, removing dot segments, and recomposing the result back
   into a character string.

   Altogether, the proper processing of URIs is quite complex.  This can
   be a problem particularly in constrained environments [RFC7228],
   where devices often have severe code size limitations.  As a result,
   many implementations in these environments choose to implement only




Hartke                   Expires April 25, 2019                 [Page 2]


Internet-Draft              Constrained IRIs                October 2018


   an ad-hoc, informally-specified, bug-ridden, non-interoperable subset
   of less than half of RFC 3986.

   This document specifies Constrained IRI References, a serialization
   format for IRI references that encodes the IRI components as Concise
   Binary Object Representation (CBOR) [RFC7049] data items rather than
   as a string of characters.  Assuming that a CBOR implementation is
   already present on a device, typical operations on Constrained IRI
   references such as parsing, reference resolution, and comparison can
   be implemented much more easily than with the original format.  A
   full implementation that covers all corner cases of the specification
   can be implemented in a relatively small amount of code.

   As a result of the simplification, Constrained IRI References are not
   capable of expressing all IRI references that are permitted by the
   syntax of RFC 3987.  The supported subset includes all Constrained
   Application Protocol (CoAP) URIs [RFC7252], most Hypertext Transfer
   Protocol (HTTP) URIs [RFC7230], and many other URIs and IRIs.

1.1.  Requirements Notation

   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.

2.  Data Model

   The data model for Constrained IRI References is very similar to the
   encoding of a request URI in CoAP messages [RFC7252]: The components
   of an IRI reference are encoded as a sequence of _options_. Each
   option consists of an _option number_ identifying the type of option
   (scheme, host name, etc.) and the _option value_.

2.1.  Options

   The following types of options are defined:

   scheme
      Specifies the IRI scheme.  Since IRI schemes have the same syntax
      as URI schemes, the option value MUST match the "scheme" rule
      defined in Section 3.1 of RFC 3986.

   host.name
      Specifies the host of the IRI authority as a registered name.

   host.ip



Hartke                   Expires April 25, 2019                 [Page 3]


Internet-Draft              Constrained IRIs                October 2018


      Specifies the host of the IRI authority as an IPv4 address
      (4 bytes) or an IPv6 address (16 bytes).

   port
      Specifies the port number.  The option value MUST be an unsigned
      integer in the range 0 to 65535 (inclusive).

   path.type
      Specifies the type of the IRI path for reference resolution.
      Possible values are 0 (absolute-path), 1 (append-path), 2
      (relative-path), and 3 (append-relation).

   path
      Specifies one segment of the IRI path.  This option can occur more
      than once.

   query
      Specifies one argument of the IRI query.  This option can occur
      more than once.

   fragment
      Specifies the fragment identifier.

   The value of a "host.name", "path", "query", and "fragment" option
   can be any Unicode string.  No percent-encoding is performed.

2.2.  Option Sequences

                  _ host.name _
   ____ scheme __/             \___ port _
    \ \________/ \__ host.ip __/ /        \
     \__________________________/ ________/
      \                          / ________    _________
       \                        / /        \  /         \
        \__________ path.type __\_\_ path _/__\_ query _/__ fragment __
                  \___________/   \________/  \_________/ \__________/

         Figure 1: Structure of a Well-Formed Sequence of Options

   A sequence of options is considered _well-formed_ if:

   o  the sequence of options is empty or starts with a "scheme",
      "host.name", "host.ip", "port", "path.type", "path", "query", or
      "fragment" option;

   o  any "scheme" option is followed by either a "host.name" or a
      "host.ip" option;




Hartke                   Expires April 25, 2019                 [Page 4]


Internet-Draft              Constrained IRIs                October 2018


   o  any "host.name" option is followed by a "port" option;

   o  any "host.ip" option is followed by a "port" option;

   o  any "port" option is followed by a "path", "query", or "fragment"
      option or is at the end of the sequence;

   o  any "path.type" option is followed by a "path", "query", or
      "fragment" option or is at the end of the sequence;

   o  any "path" option is followed by a "path", "query", or "fragment"
      option or is at the end of the sequence;

   o  any "query" option is followed by a "query" or "fragment" option
      or is at the end of the sequence; and

   o  any "fragment" option is at the end of the sequence.

   A well-formed sequence of options is considered _absolute_ if the
   sequence of options starts with a "scheme" option.

   A well-formed sequence of options is considered _relative_ if the
   sequence of options is empty or starts with an option other than the
   "scheme" option.

   An absolute sequence of options is considered _normalized_ if the
   result of resolving the sequence of options against any base IRI
   reference is equal to the input.  (It doesn't matter what base IRI it
   is resolved against, since it is already absolute.)

   The following operations can be performed on a sequence of options:

   resolve(href, base)
      Resolves a well-formed sequence of options `href` against an
      absolute sequence of options `base`. This operation MUST be
      performed by applying any algorithm that is functionally
      equivalent to the reference implementation in Section 4.1 of this
      document.

   recompose(href)
      Recomposes an IRI reference string from an absolute sequence of
      options `href`. This operation MUST be performed by applying any
      algorithm that is functionally equivalent to the reference
      implementation in Section 4.2 of this document.

      To reduce variability, it is RECOMMENDED to uppercase the letters
      in the hexadecimal notation when percent-encoding octets [RFC3986]




Hartke                   Expires April 25, 2019                 [Page 5]


Internet-Draft              Constrained IRIs                October 2018


      and to follow the recommendations of Section 4 of RFC 5952 for the
      text representation of IPv6 addresses [RFC5952].

   decompose(iriref)
      Decomposes a IRI reference string into a sequence of options.
      This operation MUST be performed by applying any algorithm that
      returns a sequence of options such that `recompose(decompose(x))`
      is equivalent to `x`.

   coap(href)
      Constructs CoAP options from an absolute, normalized sequence of
      options.  This operation MUST be performed by recomposing the
      sequence of options to an IRI reference string as described above,
      mapping the IRI to a URI as specified in Section 3.1 of RFC 3987,
      and decomposing the URI into CoAP options as specified in
      Section 6.4 of RFC 7252.  A concise implementation is illustrated
      in Section 4.3 of this document.

3.  CBOR

   A sequence of options is serialized as an array in Concise Binary
   Object Representation (CBOR) [RFC7049] as follows.  The structure is
   presented in the Concise Data Definition Language (CDDL)
   [I-D.ietf-cbor-cddl].

      ciri = [?(scheme:    1, text .regexp "[A-Za-z][A-Za-z0-9+.-]*"),
              ?(host.name: 2, text //
                host.ip:   3, bytes .size 4 / bytes .size 16),
              ?(port:      4, uint .size 2),
              ?(path.type: 5, path-type),
              *(path:      6, text),
              *(query:     7, text),
              ?(fragment:  8, text)]

      path-type = &(absolute-path:   0,
                    append-path:     1,
                    relative-path:   2,
                    append-relation: 3)

4.  Python

   The following Python 3.6 code shows how to work with a sequence of
   options.

   <CODE BEGINS>

      import enum




Hartke                   Expires April 25, 2019                 [Page 6]


Internet-Draft              Constrained IRIs                October 2018


      class Option(enum.IntEnum):
        _BEGIN = 0
        SCHEME = 1
        HOST_NAME = 2
        HOST_IP = 3
        PORT = 4
        PATH_TYPE = 5
        PATH = 6
        QUERY = 7
        FRAGMENT = 8
        _END = 9

      class PathType(enum.IntEnum):
        ABSOLUTE_PATH = 0
        APPEND_PATH = 1
        RELATIVE_PATH = 2
        APPEND_RELATION = 3

      _TRANSITIONS = [(Option.SCHEME, Option.HOST_NAME, Option.HOST_IP,
          Option.PORT, Option.PATH_TYPE, Option.PATH, Option.QUERY,
          Option.FRAGMENT, Option._END),
        (Option.HOST_NAME, Option.HOST_IP),
        (Option.PORT,),
        (Option.PORT,),
        (Option.PATH, Option.QUERY, Option.FRAGMENT, Option._END),
        (Option.PATH, Option.QUERY, Option.FRAGMENT, Option._END),
        (Option.PATH, Option.QUERY, Option.FRAGMENT, Option._END),
        (Option.QUERY, Option.FRAGMENT, Option._END),
        (Option._END,)]

      def is_well_formed(href):
        previous = Option._BEGIN
        for option, _ in href:
          if option not in _TRANSITIONS[previous]:
            return False
          previous = option
        if Option._END not in _TRANSITIONS[previous]:
          return False
        return True

      def is_absolute(href):
        return is_well_formed(href) and \
          (len(href) != 0 and href[0][0] == Option.SCHEME)

      def is_relative(href):
        return is_well_formed(href) and \
          (len(href) == 0 or href[0][0] != Option.SCHEME)




Hartke                   Expires April 25, 2019                 [Page 7]


Internet-Draft              Constrained IRIs                October 2018


   <CODE ENDS>

4.1.  Reference Resolution

   The following Python 3.6 code defines how to resolve a sequence of
   options that might be relative to a given base IRI.

   <CODE BEGINS>

      def resolve(base, href, relation=0):
        if not is_absolute(base) or not is_well_formed(href):
          return None
        result = []
        type = PathType.RELATIVE_PATH
        option = href[0][0] if href else Option._END
        if option == Option.HOST_IP:
          option = Option.HOST_NAME
        elif option == Option.PATH_TYPE:
          type = href[0][1]
          href = href[1:]
          option = Option.PATH
        if option != Option.PATH or type == PathType.ABSOLUTE_PATH:
          _copy_until(base, result, option)
        else:
          _copy_until(base, result, Option.QUERY)
          if type == PathType.APPEND_RELATION:
            _append_and_normalize(result, Option.PATH, str(relation))
          elif type == PathType.RELATIVE_PATH:
            _remove_last_path_segment(result)
        _copy_until(href, result, Option._END)
        _append_and_normalize(result, Option._END, None)
        return result

      def _copy_until(input, output, end):
        for option, value in input:
          if option >= end:
            break
          _append_and_normalize(output, option, value)

      def _append_and_normalize(output, option, value):
        if option == Option.PATH:
          if value == '.':
            return
          if value == '..':
            _remove_last_path_segment(output)
            return
        elif option > Option.PATH:
          if len(output) >= 2 and \



Hartke                   Expires April 25, 2019                 [Page 8]


Internet-Draft              Constrained IRIs                October 2018


              output[-1] == (Option.PATH, '') and (
              output[-2][0] < Option.PATH_TYPE or (
              output[-2][0] == Option.PATH_TYPE and
              output[-2][1] == PathType.ABSOLUTE_PATH)):
            _remove_last_path_segment(output)
          if option > Option.FRAGMENT:
            return
        output.append((option, value))

      def _remove_last_path_segment(output):
        if len(output) >= 1 and output[-1][0] == Option.PATH:
          del output[-1]

   <CODE ENDS>

4.2.  IRI Recomposition

   The following Python 3.6 code defines how to recompose an IRI from a
   sequence of options that encodes an absolute IRI reference.

   <CODE BEGINS>

      def recompose(href):
        if not is_absolute(href):
          return None
        result = ''
        no_path = True
        first_query = True
        for option, value in href:
          if option == Option.SCHEME:
            result += value + ':'
          elif option == Option.HOST_NAME:
            result += '//' + _encode_ireg_name(value)
          elif option == Option.HOST_IP:
            result += '//' + _encode_ip_address(value)
          elif option == Option.PORT:
            result += ':' + str(value)
          elif option == Option.PATH:
            result += '/' + _encode_path_segment(value)
            no_path = False
          elif option == Option.QUERY:
            if no_path:
              result += '/'
              no_path = False
            result += '?' if first_query else '&'
            result += _encode_query_argument(value)
            first_query = False
          elif option == Option.FRAGMENT:



Hartke                   Expires April 25, 2019                 [Page 9]


Internet-Draft              Constrained IRIs                October 2018


            if no_path:
              result += '/'
              no_path = False
            result += '#' + _encode_fragment(value)
        if no_path:
          result += '/'
          no_path = False
        return result

      def _encode_ireg_name(s):
        return ''.join(c if _is_ireg_name_char(c)
                         else _encode_pct(c) for c in s)

      def _encode_ip_address(b):
        if len(b) == 4:
          return '.'.join(str(c) for c in b)
        elif len(b) == 16:
          return '[' + ... + ']'  # see RFC 5952

      def _encode_path_segment(s):
        return ''.join(c if _is_isegment_char(c)
                         else _encode_pct(c) for c in s)

      def _encode_query_argument(s):
        return ''.join(c if _is_iquery_char(c) and c != '&'
                         else _encode_pct(c) for c in s)

      def _encode_fragment(s):
        return ''.join(c if _is_ifragment_char(c)
                         else _encode_pct(c) for c in s)

      def _encode_pct(s):
        return ''.join('%{0:0>2X}'.format(c) for c in s.encode('utf-8'))

      def _is_ireg_name_char(c):
        return _is_iunreserved(c) or _is_sub_delim(c)

      def _is_isegment_char(c):
        return _is_ipchar(c)

      def _is_iquery_char(c):
        return _is_ipchar(c) or _is_iprivate(c) or c == '/' or c == '?'

      def _is_ifragment_char(c):
        return _is_ipchar(c) or c == '/' or c == '?'

      def _is_ipchar(c):
        return _is_iunreserved(c) or _is_sub_delim(c) or \



Hartke                   Expires April 25, 2019                [Page 10]


Internet-Draft              Constrained IRIs                October 2018


               c == ':' or c == '@'

      def _is_iunreserved(c):
        return _is_alpha(c) or _is_digit(c) or \
               c == '-' or c == '.' or c == '_' or c == '~' or \
               _is_ucschar(c)

      def _is_alpha(c):
        return c >= 'A' and c <= 'Z' or c >= 'a' and c <= 'z'

      def _is_digit(c):
        return c >= '0' and c <= '9'

      def _is_sub_delim(c):
        return c == '!' or c == '$' or c == '&' or c == '\'' or \
               c == '(' or c == ')' or c == '*' or c == '+' or \
               c == ',' or c == ';' or c == '='

      def _is_ucschar(c):
        return c >= '\U000000A0' and c <= '\U0000D7FF' or \
               c >= '\U0000F900' and c <= '\U0000FDCF' or \
               c >= '\U0000FDF0' and c <= '\U0000FFEF' or \
               c >= '\U00010000' and c <= '\U0001FFFD' or \
               c >= '\U00020000' and c <= '\U0002FFFD' or \
               c >= '\U00030000' and c <= '\U0003FFFD' or \
               c >= '\U00040000' and c <= '\U0004FFFD' or \
               c >= '\U00050000' and c <= '\U0005FFFD' or \
               c >= '\U00060000' and c <= '\U0006FFFD' or \
               c >= '\U00070000' and c <= '\U0007FFFD' or \
               c >= '\U00080000' and c <= '\U0008FFFD' or \
               c >= '\U00090000' and c <= '\U0009FFFD' or \
               c >= '\U000A0000' and c <= '\U000AFFFD' or \
               c >= '\U000B0000' and c <= '\U000BFFFD' or \
               c >= '\U000C0000' and c <= '\U000CFFFD' or \
               c >= '\U000D0000' and c <= '\U000DFFFD' or \
               c >= '\U000E1000' and c <= '\U000EFFFD'

      def _is_iprivate(c):
        return c >= '\U0000E000' and c <= '\U0000F8FF' or \
               c >= '\U000F0000' and c <= '\U000FFFFD' or \
               c >= '\U00100000' and c <= '\U0010FFFD'

   <CODE ENDS>








Hartke                   Expires April 25, 2019                [Page 11]


Internet-Draft              Constrained IRIs                October 2018


4.3.  CoAP Encoding

   The following Python 3.6 code shows how to construct CoAP options
   from an absolute sequence of options.  For simplicity, the code does
   not omit CoAP options with their default value in a CoAP request.

   <CODE BEGINS>

      def coap(href, to_proxy=False):
        if not is_absolute(href):
          return None
        result = b''
        previous = 0
        for option, value in href:
          if option == Option.SCHEME:
            pass
          elif option == Option.HOST_NAME:
            opt = 3  # Uri-Host
            val = value.encode('utf-8')
            result += _encode_coap_option(opt - previous, val)
            previous = opt
          elif option == Option.HOST_IP:
            opt = 3  # Uri-Host
            if len(value) == 4:
              val = '.'.join(str(c) for c in value).encode('utf-8')
            elif len(value) == 16:
              val = b'[' + ... + b']'  # see RFC 5952
            result += _encode_coap_option(opt - previous, val)
            previous = opt
          elif option == Option.PORT:
            opt = 7  # Uri-Port
            val = value.to_bytes((value.bit_length() + 7) // 8, 'big')
            result += _encode_coap_option(opt - previous, val)
            previous = opt
          elif option == Option.PATH:
            opt = 11  # Uri-Path
            val = value.encode('utf-8')
            result += _encode_coap_option(opt - previous, val)
            previous = opt
          elif option == Option.QUERY:
            opt = 15  # Uri-Query
            val = value.encode('utf-8')
            result += _encode_coap_option(opt - previous, val)
            previous = opt
          elif option == Option.FRAGMENT:
            pass
        if to_proxy:
          (option, value) = href[0]



Hartke                   Expires April 25, 2019                [Page 12]


Internet-Draft              Constrained IRIs                October 2018


          opt = 39  # Proxy-Scheme
          val = value.encode('utf-8')
          result += _encode_coap_option(opt - previous, val)
          previous = opt
        return result

      def _encode_coap_option(delta, value):
        length = len(value)
        delta_nibble = _encode_coap_option_nibble(delta)
        length_nibble = _encode_coap_option_nibble(length)
        result = bytes([delta_nibble << 4 | length_nibble])
        if delta_nibble == 13:
          delta -= 13
          result += bytes([delta])
        elif delta_nibble == 14:
          delta -= 256 + 13
          result += bytes([delta >> 8, delta & 255])
        if length_nibble == 13:
          length -= 13
          result += bytes([length])
        elif length_nibble == 14:
          length -= 256 + 13
          result += bytes([length >> 8, length & 255])
        result += value
        return result

      def _encode_coap_option_nibble(n):
        if n < 13:
          return n
        elif n < 256 + 13:
          return 13
        elif n < 65536 + 256 + 13:
          return 14

   <CODE ENDS>

5.  Security Considerations

   Parsers of Constrained IRI 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 8 of RFC 7049 [RFC7049] for
   security considerations relating to parsing CBOR.






Hartke                   Expires April 25, 2019                [Page 13]


Internet-Draft              Constrained IRIs                October 2018


   The security considerations discussed in Section 7 of RFC 3986
   [RFC3986] and Section 8 of RFC 3987 [RFC3987] also apply to
   Constrained IRI References.

6.  IANA Considerations

   This document has no IANA actions.

7.  References

7.1.  Normative References

   [I-D.ietf-cbor-cddl]
              Birkholz, H., Vigano, C., and C. Bormann, "Concise data
              definition language (CDDL): a notational convention to
              express CBOR and JSON data structures", draft-ietf-cbor-
              cddl-05 (work in progress), August 2018.

   [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>.

   [RFC7049]  Bormann, C. and P. Hoffman, "Concise Binary Object
              Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049,
              October 2013, <https://www.rfc-editor.org/info/rfc7049>.

   [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>.

7.2.  Informative References

   [RFC5952]  Kawamura, S. and M. Kawashima, "A Recommendation for IPv6
              Address Text Representation", RFC 5952,
              DOI 10.17487/RFC5952, August 2010,
              <https://www.rfc-editor.org/info/rfc5952>.





Hartke                   Expires April 25, 2019                [Page 14]


Internet-Draft              Constrained IRIs                October 2018


   [RFC6690]  Shelby, Z., "Constrained RESTful Environments (CoRE) Link
              Format", RFC 6690, DOI 10.17487/RFC6690, August 2012,
              <https://www.rfc-editor.org/info/rfc6690>.

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

   [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, December 2017,
              <https://www.w3.org/TR/2017/REC-html52-20171214>.

Acknowledgements

   Thanks to Christian Amsuess and Ari Keranen for helpful comments and
   discussions that have shaped the document.

Author's Address

   Klaus Hartke
   Ericsson
   Torshamnsgatan 23
   Stockholm  SE-16483
   Sweden

   Email: klaus.hartke@ericsson.com












Hartke                   Expires April 25, 2019                [Page 15]