RFC 2141

URN Syntax

๐Ÿ“… published May 1997, from ietf

RFC 2141: URN Syntax ๐Ÿ’–

Part 1 of 2 ๐Ÿงš (Section 5 onward comes next)

Okay bestie, this is RFC 2141, called URN Syntax ๐ŸŽ€. It was written by R. Moats from AT&T and dated May 1997. It's a Standards Track document โœจ, so it specifies an Internet standards track protocol. The title block doesn't list anything it obsoletes or updates, so it's giving independent energy ๐Ÿ’….


Status of This Memo ๐Ÿ“œ

Okay so this one is an Internet standards track protocol ๐Ÿ”ฅ for the whole Internet community, and it's literally asking for discussion and suggestions for improvements ๐Ÿ’ฌ. If you want to know where it stands in standardization, check the current edition of "Internet Official Protocol Standards" (STD 1) ๐Ÿ‘‘. Distribution of this memo is unlimited ๐ŸŒˆ, so share away!

Abstract ๐Ÿฆ‹

Uniform Resource Names (URNs) are meant to be persistent, location-independent resource identifiers ๐Ÿ’–, which is honestly the dream. This doc sets forward the canonical syntax for URNs โœจ. It also covers both existing legacy and new namespaces, plus the requirements for URN presentation and transmission ๐Ÿ“ฎ. Last but not least, it talks about URN equivalence and how to figure it out ๐Ÿ”.

1. Introduction ๐ŸŒธ

So Uniform Resource Names (URNs) are meant to be persistent, location-independent resource identifiers, and they're designed to make it easy to map other namespaces (ones that share the properties of URNs) into URN-space ๐Ÿ—บ๏ธ. That means the URN syntax gives us a way to encode character data so it can ride along in existing protocols and get typed on most keyboards, etc. ๐Ÿ’…

2. Syntax ๐ŸŽ€

Every URN follows this syntax (phrases in quotes are REQUIRED ๐Ÿ”’):

                     <URN> ::= "urn:" <NID> ":" <NSS>

Here, <NID> is the Namespace Identifier and <NSS> is the Namespace Specific String ๐Ÿง . The leading "urn:" sequence is case-insensitive ๐Ÿ™ˆ. The Namespace ID decides the syntactic interpretation of the Namespace Specific String (as discussed in [1]) ๐Ÿ”Ž.

RFC 1630 [2] and RFC 1737 [3] each bring extra considerations for URN encoding, and those can limit the syntax ๐Ÿšง. On the flip side, supporting existing legacy naming systems actually broadens it ๐Ÿ“ˆ. So we talk about the acceptable syntax for the Namespace Identifier and the Namespace Specific String separately ๐Ÿ’•.

2.1. Namespace Identifier Syntax ๐Ÿ’œ

Here's the syntax for the Namespace Identifier. To (a) stay consistent with all potential resolution schemes and (b) not put any undue constraints on any potential resolution scheme, the syntax is:

<NID>         ::= <let-num> [ 1,31<let-num-hyp> ]

<let-num-hyp> ::= <upper> | <lower> | <number> | "-"

<let-num>     ::= <upper> | <lower> | <number>

<upper>       ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" |
                  "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" |
                  "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" |
                  "Y" | "Z"

<lower>       ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" |
                  "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" |
                  "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" |
                  "y" | "z"

<number>      ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
                  "8" | "9"

This is slightly more restrictive than what [4] says (which allows the characters "." and "+") ๐Ÿ™ƒ. Also, the Namespace Identifier is case insensitive, so "ISBN" and "isbn" refer to the same namespace ๐Ÿซถ.

To avoid mixing things up with the "urn:" identifier, the NID "urn" is reserved and MUST NOT be used ๐Ÿšซ.

2.2. Namespace Specific String Syntax ๐Ÿฆ„

As RFC 1737 requires, there is a single canonical representation of the NSS portion of a URN ๐Ÿ’Ž. Here's the format:

<NSS>         ::= 1*<URN chars>

<URN chars>   ::= <trans> | "%" <hex> <hex>

<trans>       ::= <upper> | <lower> | <number> | <other> | <reserved>

<hex>         ::= <number> | "A" | "B" | "C" | "D" | "E" | "F" |
                  "a" | "b" | "c" | "d" | "e" | "f"

<other>       ::= "(" | ")" | "+" | "," | "-" | "." |
                  ":" | "=" | "@" | ";" | "$" |
                  "_" | "!" | "*" | "'"

Depending on a namespace's rules, valid identifiers in that namespace might include characters that aren't in the URN character set above (<URN chars>) ๐Ÿค”. Those strings MUST be translated into canonical NSS format before you use them as protocol elements or pass them on to other applications ๐ŸŽฏ. Translation works by encoding each character outside the URN character set as a sequence of one to six octets using UTF-8 encoding [5], and then encoding each of those octets as "%" followed by two characters from the <hex> character set above. Those two characters give the hexadecimal representation of that octet ๐Ÿ”ข.

2.3. Reserved characters ๐Ÿ”

The last bit of the character set we haven't covered yet is the reserved character set, which holds back certain characters from normal use. Here's the set, and below I explain why each character is reserved ๐Ÿ™‹.

The reserved character set is:

<reserved>    ::= '%" | "/" | "?" | "#"

2.3.1. The "%" character ๐ŸŒท

"%" is reserved in the URN syntax because it introduces the escape sequence for an octet ๐ŸŽฌ. Literal use of the "%" character in a namespace must be encoded using "%25" in URNs for that namespace. The presence of a "%" character in an URN MUST be followed by two characters from the <hex> character set ๐Ÿ’ฏ.

Namespaces MAY designate one or more characters from the URN character set as having special meaning for that namespace ๐ŸŽจ. If the namespace also uses that character in a literal sense, the character used in a literal sense MUST be encoded with "%" followed by the hexadecimal representation of that octet ๐Ÿซ . Further, a character MUST NOT be "%"-encoded if the character is not a reserved character ๐Ÿ™…. Therefore, the process of registering a namespace identifier shall include publication of a definition of which characters have a special meaning to that namespace ๐Ÿ“.

2.3.2. The other reserved characters ๐ŸŒŸ

RFC 1630 [2] reserves the characters "/", "?", and "#" for particular purposes ๐Ÿง. The URN-WG hasn't yet debated the applicability and precise semantics of those purposes as applied to URNs, so these characters are RESERVED for future developments ๐Ÿ”ฎ. Namespace developers SHOULD NOT use these characters in unencoded form, and should instead use the right %-encoding for each one ๐Ÿ™.

2.4. Excluded characters ๐Ÿšซ

This list is included only for the sake of completeness ๐Ÿ“‹. Any octets or characters on it are explicitly NOT part of the URN character set, and if used in a URN, MUST be %encoded ๐Ÿ’ฅ.

<excluded> ::= octets 1-32 (1-20 hex) | "\" | """ | "&" | "<"
               | ">" | "[" | "]" | "^" | "`" | "{" | "|" | "}" | "~"
               | octets 127-255 (7F-FF hex)

Also, octet 0 (0 hex) should NEVER be used, in either unencoded or %-encoded form ๐Ÿšจ.

A URN ends when an octet or character from the excluded character set (<excluded>) is encountered โœ‹. The character from the excluded character set is NOT part of the URN ๐Ÿ”š.

3. Support of existing legacy naming systems and new naming systems ๐Ÿ›๏ธ

Any namespace (existing or newly devised) that is proposed as a URN namespace and fulfills the criteria of URN namespaces MUST be expressed in this syntax ๐Ÿ“. If names in these namespaces contain characters other than those defined for the URN character set, they MUST be translated into canonical form as discussed in section 2.2 ๐Ÿ”„.

4. URN presentation and transport ๐ŸŽ

The URN syntax defines the canonical format for URNs, and all URN transport and interchanges MUST take place in this format ๐Ÿšš. Further, all URN-aware applications MUST offer the option of displaying URNs in this canonical form, so people can transcribe them directly (for example, by cut and paste) ๐Ÿ“‹โœ‚๏ธ. Such applications MAY support display of URNs in a more human-friendly form, and they may use a character set that includes characters that aren't permitted in URN syntax as defined in this RFC. That means they can swap %-notation for characters from some extended character set when showing URNs to humans ๐ŸŒˆ.

11. Editor's address ๐Ÿ’Œ

Okay bestie, here's who to reach out to! The editor is Ryan Moats at AT&T, and the address is:

Ryan Moats
AT&T
15621 Drexel Circle
Omaha, NE 68135-2358
USA

Phone:  +1 402 894-9456
EMail:  jayhawk@ds.internic.net

Appendix A. Handling of URNs by URL resolvers/browsers ๐Ÿฆ‹

Okay so the URN syntax was designed so that URNs can show up in places where URLs are expected. ๐Ÿ’… A resolver that follows the current URL syntax specification [3] will pull out a scheme value of "urn:" instead of a scheme value of "urn:<nid>". Plot twist, but it totally makes sense once you see it! โœจ

An URN MUST be treated as an opaque URL by URL resolvers, and it gets passed along (with the "urn:" tag still on it) to a URN resolver for resolution. ๐Ÿ”ฅ That URN resolver can be an external one the URL resolver already knows about, or it can be built right into the URL resolver. Either way works, periodt! ๐Ÿ’œ

To avoid confusing people, a URL browser SHOULD display the complete URN, including the "urn:" tag. ๐Ÿ™ˆ That way nobody mixes up URN namespace identifiers with URL scheme identifiers. Clean and iconic! ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from