idnits 2.17.1 draft-gregorio-uritemplate-07.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == Line 957 has weird spacing: '...r}/here up/f...' == Line 1253 has weird spacing: '...| false false...' -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (Sep 26, 2011) is 4589 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'ASCII' -- Possible downref: Non-RFC (?) normative reference: ref. 'UNIV4' -- Possible downref: Non-RFC (?) normative reference: ref. 'UTR15' -- Possible downref: Non-RFC (?) normative reference: ref. '1' Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 7 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group J. Gregorio 3 Internet-Draft Google 4 Intended status: Standards Track R. Fielding 5 Expires: March 29, 2012 Adobe 6 M. Hadley 7 MITRE 8 M. Nottingham 9 Rackspace 10 D. Orchard 11 Salesforce.com 12 Sep 26, 2011 14 URI Template 15 draft-gregorio-uritemplate-07 17 Abstract 19 A URI Template is a compact sequence of characters for describing a 20 range of Uniform Resource Identifiers through variable expansion. 21 This specification defines the URI Template syntax and the process 22 for expanding a URI Template into a URI reference, along with 23 guidelines for the use of URI Templates on the Internet. 25 Editorial Note (to be removed by RFC Editor) 27 To provide feedback on this Internet-Draft, join the W3C URI mailing 28 list (http://lists.w3.org/Archives/Public/uri/) [1]. 30 Status of this Memo 32 This Internet-Draft is submitted in full conformance with the 33 provisions of BCP 78 and BCP 79. 35 Internet-Drafts are working documents of the Internet Engineering 36 Task Force (IETF). Note that other groups may also distribute 37 working documents as Internet-Drafts. The list of current Internet- 38 Drafts is at http://datatracker.ietf.org/drafts/current/. 40 Internet-Drafts are draft documents valid for a maximum of six months 41 and may be updated, replaced, or obsoleted by other documents at any 42 time. It is inappropriate to use Internet-Drafts as reference 43 material or to cite them other than as "work in progress." 45 This Internet-Draft will expire on March 29, 2012. 47 Copyright Notice 48 Copyright (c) 2011 IETF Trust and the persons identified as the 49 document authors. All rights reserved. 51 This document is subject to BCP 78 and the IETF Trust's Legal 52 Provisions Relating to IETF Documents 53 (http://trustee.ietf.org/license-info) in effect on the date of 54 publication of this document. Please review these documents 55 carefully, as they describe your rights and restrictions with respect 56 to this document. Code Components extracted from this document must 57 include Simplified BSD License text as described in Section 4.e of 58 the Trust Legal Provisions and are provided without warranty as 59 described in the Simplified BSD License. 61 Table of Contents 63 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 64 1.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . 3 65 1.2. Levels and Expression Types . . . . . . . . . . . . . . . 5 66 1.3. Design Considerations . . . . . . . . . . . . . . . . . . 9 67 1.4. Limitations . . . . . . . . . . . . . . . . . . . . . . . 10 68 1.5. Notational Conventions . . . . . . . . . . . . . . . . . . 11 69 1.6. Character Encoding and Unicode Normalization . . . . . . . 12 70 2. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 71 2.1. Literals . . . . . . . . . . . . . . . . . . . . . . . . . 13 72 2.2. Expressions . . . . . . . . . . . . . . . . . . . . . . . 13 73 2.3. Variables . . . . . . . . . . . . . . . . . . . . . . . . 14 74 2.4. Value Modifiers . . . . . . . . . . . . . . . . . . . . . 15 75 2.4.1. Prefix Values . . . . . . . . . . . . . . . . . . . . 15 76 2.4.2. Composite Values . . . . . . . . . . . . . . . . . . . 16 77 3. Expansion . . . . . . . . . . . . . . . . . . . . . . . . . . 17 78 3.1. Literal Expansion . . . . . . . . . . . . . . . . . . . . 17 79 3.2. Expression Expansion . . . . . . . . . . . . . . . . . . . 18 80 3.2.1. Variable Expansion . . . . . . . . . . . . . . . . . . 18 81 3.2.2. Simple String Expansion: {var} . . . . . . . . . . . . 20 82 3.2.3. Reserved expansion: {+var} . . . . . . . . . . . . . . 20 83 3.2.4. Fragment expansion: {#var} . . . . . . . . . . . . . . 21 84 3.2.5. Label expansion with dot-prefix: {.var} . . . . . . . 22 85 3.2.6. Path segment expansion: {/var} . . . . . . . . . . . . 22 86 3.2.7. Path-style parameter expansion: {;var} . . . . . . . . 23 87 3.2.8. Form-style query expansion: {?var} . . . . . . . . . . 24 88 3.2.9. Form-style query continuation: {&var} . . . . . . . . 24 89 4. Security Considerations . . . . . . . . . . . . . . . . . . . 25 90 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 25 91 6. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 25 92 7. Normative References . . . . . . . . . . . . . . . . . . . . . 25 93 Appendix A. Implementation Hints . . . . . . . . . . . . . . . . 26 94 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 29 96 1. Introduction 98 1.1. Overview 100 A Uniform Resource Identifier (URI) [RFC3986] is often used to 101 identify a specific resource within a common space of similar 102 resources. For example, personal web spaces are often delegated 103 using a common pattern, such as 105 http://example.com/~fred/ 106 http://example.com/~mark/ 108 or a set of dictionary entries might be grouped in a hierarchy by the 109 first letter of the term, as in 111 http://example.com/dictionary/c/cat 112 http://example.com/dictionary/d/dog 114 or a service interface might be invoked with various user input in a 115 common pattern, as in 117 http://example.com/search?q=cat&lang=en 118 http://example.com/search?q=chien&lang=fr 120 URI Templates provide a mechanism for abstracting a space of resource 121 identifiers such that the variable parts can be easily identified and 122 described. URI templates can have many uses, including discovery of 123 available services, configuring resource mappings, defining computed 124 links, specifying interfaces, and other forms of programmatic 125 interaction with resources. For example, the above resources could 126 be described by the following URI templates: 128 http://example.com/~{username}/ 129 http://example.com/dictionary/{term:1}/{term} 130 http://example.com/search{?q,lang} 132 We define the following terms: 133 o expression - The text between '{' and '}', including the enclosing 134 braces, as defined in Section 2. 135 o expansion - The string result obtained from a template expression 136 after processing it according to its expression type, list of 137 variable names, and value modifiers, as defined in Section 3. 138 o template processor - A program or library that, given a URI 139 Template and a set of variables with values, transforms the 140 template string into a URI-reference by parsing the template for 141 expressions and substituting each one with its corresponding 142 expansion. 144 A URI Template provides both a structural description of a URI space 145 and, when variable values are provided, machine-readable instructions 146 on how to construct a URI corresponding to those values. A URI 147 Template is transformed into a URI-reference by replacing each 148 delimited expression with its value as defined by the expression type 149 and the values of variables named within the expression. The 150 expression types range from simple string expansion to multiple 151 name=value lists. The expansions are based on the URI generic 152 syntax, allowing an implementation to process any URI Template 153 without knowing the scheme-specific requirements of every possible 154 resulting URI. 156 For example, the following URI Template includes a form-style 157 parameter expression, as indicated by the "?" operator appearing 158 before the variable names. 160 http://www.example.com/foo{?query,number} 162 The expansion process for expressions beginning with the question- 163 mark ("?") operator follows the same pattern as form-style interfaces 164 on the World Wide Web: 166 http://www.example.com/foo{?query,number} 167 \_____________/ 168 | 169 | 170 For each defined variable in [ 'query', 'number' ], 171 substitute "?" if it is the first substitution or "&" 172 thereafter, followed by the variable name, '=', and the 173 variable's value. 175 If the variables have the values 177 query := "mycelium" 178 number := 100 180 then the expansion of the above URI Template is 182 http://www.example.com/foo?query=mycelium&number=100 184 Alternatively, if 'query' is undefined, then the expansion would be 186 http://www.example.com/foo?number=100 188 or if both variables are undefined, then it would be 190 http://www.example.com/foo 192 A URI Template may be provided in absolute form, as in the examples 193 above, or in relative form. A template MUST be expanded before the 194 resulting reference can be resolved from relative to absolute form. 196 Although the URI syntax is used for the result, the template string 197 is allowed to contain the broader set of characters that can be found 198 in IRI references [RFC3987]. A URI Template is therefore also an IRI 199 template, and the result of template processing can be transformed to 200 an IRI by following the process defined in Section 3.2 of [RFC3987]. 202 1.2. Levels and Expression Types 204 URI Templates are similar to a macro language with a fixed set of 205 macro definitions: the expression type determines the expansion 206 process. The default expression type is simple string expansion, 207 wherein a single named variable is replaced by its value as a string 208 after UTF-8 encoding the characters and then pct-encoding any octets 209 that are not in the unreserved set. 211 Since most template processors implemented prior to this 212 specification have only implemented the default expression type, we 213 refer to these as Level 1 templates. 215 .-----------------------------------------------------------------. 216 | Level 1 examples, with variables having values of | 217 | | 218 | var := "value" | 219 | hello := "Hello World!" | 220 | | 221 |-----------------------------------------------------------------| 222 | Op Expression Expansion | 223 |-----------------------------------------------------------------| 224 | | Simple string expansion (Sec 3.2.2) | 225 | | | 226 | | {var} value | 227 | | {hello} Hello%20World%21 | 228 `-----------------------------------------------------------------' 230 Level 2 templates add the plus ("+") operator, for expansion of 231 values that are allowed to include reserved characters, and the 232 crosshatch ("#") operator for expansion of fragment identifiers. 234 .-----------------------------------------------------------------. 235 | Level 2 examples, with variables having values of | 236 | | 237 | var := "value" | 238 | hello := "Hello World!" | 239 | path := "/foo/bar" | 240 | | 241 |-----------------------------------------------------------------| 242 | Op Expression Expansion | 243 |-----------------------------------------------------------------| 244 | + | Reserved string expansion (Sec 3.2.3) | 245 | | | 246 | | {+var} value | 247 | | {+hello} Hello%20World! | 248 | | {+path}/here /foo/bar/here | 249 | | here?ref={+path} here?ref=/foo/bar | 250 |-----+-----------------------------------------------------------| 251 | # | Fragment expansion, crosshatch-prefixed (Sec 3.2.4) | 252 | | | 253 | | X{#var} X#value | 254 | | X{#hello} X#Hello%20World! | 255 `-----------------------------------------------------------------' 257 Level 3 templates add more complex operators for lists of comma- 258 separated values, dot-prefixed labels, slash-prefixed path segments, 259 semicolon-prefixed path parameters, and the forms-style construction 260 of a query syntax consisting of name=value pairs that are separated 261 by an ampersand character. 263 .-----------------------------------------------------------------. 264 | Level 3 examples, with variables having values of | 265 | | 266 | var := "value" | 267 | hello := "Hello World!" | 268 | empty := "" | 269 | path := "/foo/bar" | 270 | x := "1024" | 271 | y := "768" | 272 | | 273 |-----------------------------------------------------------------| 274 | Op Expression Expansion | 275 |-----------------------------------------------------------------| 276 | | String expansion with multiple variables (Sec 3.2.2) | 277 | | | 278 | | map?{x,y} map?1024,768 | 279 | | {x,hello,y} 1024,Hello%20World%21,768 | 280 | | | 281 |-----+-----------------------------------------------------------| 282 | + | Reserved expansion with multiple variables (Sec 3.2.3) | 283 | | | 284 | | {+x,hello,y} 1024,Hello%20World!,768 | 285 | | {+path,x}/here /foo/bar,1024/here | 286 | | | 287 |-----+-----------------------------------------------------------| 288 | # | Fragment expansion with multiple variables (Sec 3.2.4) | 289 | | | 290 | | {#x,hello,y} #1024,Hello%20World!,768 | 291 | | {#path,x}/here #/foo/bar,1024/here | 292 | | | 293 |-----+-----------------------------------------------------------| 294 | . | Label expansion, dot-prefixed (Sec 3.2.5) | 295 | | | 296 | | X{.var} X.value | 297 | | X{.x,y} X.1024.768 | 298 | | | 299 |-----+-----------------------------------------------------------| 300 | / | Path segments, slash-prefixed (Sec 3.2.6) | 301 | | | 302 | | {/var} /value | 303 | | {/var,x}/here /value/1024/here | 304 | | | 305 |-----+-----------------------------------------------------------| 306 | ; | Path-style parameters, semicolon-prefixed (Sec 3.2.7) | 307 | | | 308 | | {;x,y} ;x=1024;y=768 | 309 | | {;x,y,empty} ;x=1024;y=768;empty | 310 | | | 311 |-----+-----------------------------------------------------------| 312 | ? | Form-style query, ampersand-separated (Sec 3.2.8) | 313 | | | 314 | | {?x,y} ?x=1024&y=768 | 315 | | {?x,y,empty} ?x=1024&y=768&empty= | 316 | | | 317 |-----+-----------------------------------------------------------| 318 | & | Form-style query continuation (Sec 3.2.9) | 319 | | | 320 | | ?fixed=yes{&x} ?fixed=yes&x=1024 | 321 | | {&x,y,empty} &x=1024&y=768&empty= | 322 | | | 323 `-----------------------------------------------------------------' 325 Finally, Level 4 templates add the ability to specify value modifiers 326 as a suffix to the variable name. The prefix modifier (":") 327 indicates that only a limited number of characters from the beginning 328 of the value are used by the expansion. The explode ("*") modifier 329 indicates that the variable is to be treated as a composite value, 330 consisting of either a list of names or an associative array of 331 (name, value) pairs, that is expanded as if each member were a 332 separate variable. 334 .-----------------------------------------------------------------. 335 | Level 4 examples, with variables having values of | 336 | | 337 | var := "value" | 338 | hello := "Hello World!" | 339 | path := "/foo/bar" | 340 | list := [ "red", "green", "blue" ] | 341 | keys := [("semi",";"),("dot","."),("comma",",")] | 342 | | 343 | Op Expression Expansion | 344 |-----------------------------------------------------------------| 345 | | String expansion with value modifiers (Sec 3.2.2) | 346 | | | 347 | | {var:3} val | 348 | | {var:30} value | 349 | | {list} red,green,blue | 350 | | {list*} red,green,blue | 351 | | {keys} semi,%3B,dot,.,comma,%2C | 352 | | {keys*} semi=%3B,dot=.,comma=%2C | 353 | | | 354 |-----+-----------------------------------------------------------| 355 | + | Reserved expansion with value modifiers (Sec 3.2.3) | 356 | | | 357 | | {+path:6}/here /foo/b/here | 358 | | {+list} red,green,blue | 359 | | {+list*} red,green,blue | 360 | | {+keys} semi,;,dot,.,comma,, | 361 | | {+keys*} semi=;,dot=.,comma=, | 362 | | | 363 |-----+-----------------------------------------------------------| 364 | # | Fragment expansion with value modifiers (Sec 3.2.4) | 365 | | | 366 | | {#path:6}/here #/foo/b/here | 367 | | {#list} #red,green,blue | 368 | | {#list*} #red,green,blue | 369 | | {#keys} #semi,;,dot,.,comma,, | 370 | | {#keys*} #semi=;,dot=.,comma=, | 371 | | | 372 |-----+-----------------------------------------------------------| 373 | . | Label expansion, dot-prefixed (Sec 3.2.5) | 374 | | | 375 | | X{.var:3} X.val | 376 | | X{.list} X.red,green,blue | 377 | | X{.list*} X.red.green.blue | 378 | | X{.keys} X.semi,%3B,dot,.,comma,%2C | 379 | | X{.keys*} X.semi=%3B.dot=..comma=%2C | 380 | | | 381 |-----+-----------------------------------------------------------| 382 | / | Path segments, slash-prefixed (Sec 3.2.6) | 383 | | | 384 | | {/var:1,var} /v/value | 385 | | {/list} /red,green,blue | 386 | | {/list*} /red/green/blue | 387 | | {/list*,path:4} /red/green/blue/%2Ffoo | 388 | | {/keys} /semi,%3B,dot,.,comma,%2C | 389 | | {/keys*} /semi=%3B/dot=./comma=%2C | 390 | | | 391 |-----+-----------------------------------------------------------| 392 | ; | Path-style parameters, semicolon-prefixed (Sec 3.2.7) | 393 | | | 394 | | {;hello:5} ;hello=Hello | 395 | | {;list} ;list=red,green,blue | 396 | | {;list*} ;red;green;blue | 397 | | {;keys} ;keys=semi,%3B,dot,.,comma,%2C | 398 | | {;keys*} ;semi=%3B;dot=.;comma=%2C | 399 | | | 400 |-----+-----------------------------------------------------------| 401 | ? | Form-style query, ampersand-separated (Sec 3.2.8) | 402 | | | 403 | | {?var:3} ?var=val | 404 | | {?list} ?list=red,green,blue | 405 | | {?list*} ?red&green&blue | 406 | | {?keys} ?keys=semi,%3B,dot,.,comma,%2C | 407 | | {?keys*} ?semi=%3B&dot=.&comma=%2C | 408 | | | 409 |-----+-----------------------------------------------------------| 410 | & | Form-style query continuation (Sec 3.2.9) | 411 | | | 412 | | {&var:3} &var=val | 413 | | {&list} &list=red,green,blue | 414 | | {&list*} &red&green&blue | 415 | | {&keys} &keys=semi,%3B,dot,.,comma,%2C | 416 | | {&keys*} &semi=%3B&dot=.&comma=%2C | 417 | | | 418 `-----------------------------------------------------------------' 420 1.3. Design Considerations 422 Mechanisms similar to URI Templates have been defined within several 423 specifications, including WSDL, WADL and OpenSearch. This 424 specification extends and formally defines the syntax so that URI 425 Templates can be used consistently across multiple Internet 426 applications and within Internet message fields, while at the same 427 time retaining compatibility with those earlier definitions. 429 The URI Template syntax has been designed to carefully balance the 430 need for a powerful expansion mechanism with the need for ease of 431 implementation. The syntax is designed to be trivial to parse while 432 at the same time providing enough flexibility to express many common 433 template scenarios. Implementations are able to parse the template 434 and perform the expansions in a single pass. 436 Templates are simple and readable when used with common examples 437 because the single-character operators match the URI generic syntax 438 delimiters. The operator's associated delimiter (".", ";", "/", "?", 439 "&", and "#") is omitted when none of the listed variables are 440 defined. Likewise, the expansion process for ";" (path-style 441 parameters) will omit the "=" when the variable value is empty, 442 whereas the process for "?" (form-style parameters) will not omit the 443 "=" when the value is empty. Multiple variables and list values have 444 their values joined with "," if there is no predefined joining 445 mechanism for the operator. The "+" and "#" operators will 446 substitute unencoded reserved characters found inside the variable 447 values; the other operators will pct-encode reserved characters found 448 in the variable values prior to expansion. 450 The most common cases for URI spaces can be described with Level 1 451 template expressions. If we were only concerned with URI generation, 452 then the template syntax could be limited to just simple variable 453 expansion, since more complex forms could be generated by changing 454 the variable values. However, URI Templates have the additional goal 455 of describing the layout of identifiers in terms of preexisting data 456 values. The template syntax therefore includes operators that 457 reflect how resource identifiers are commonly allocated. Likewise, 458 since prefix substrings are often used to partition large spaces of 459 resources, modifiers on variable values provide a way to specify both 460 the substring and the full value string with a single variable name. 462 1.4. Limitations 464 Since a URI Template describes a superset of the identifiers, there 465 is no implication that every possible expansion for each delimited 466 variable expression corresponds to a URI of an existing resource. 467 Our expectation is that an application constructing URIs according to 468 the template will be provided with an appropriate set of values for 469 the variables being substituted, or at least a means of validating 470 user data-entry for those values. 472 URI Templates are not URIs: they do not identify an abstract or 473 physical resource, they are not parsed as URIs, and should not be 474 used in places where a URI would be expected unless the template 475 expressions will be expanded by a template processor prior to use. 476 Distinct field, element, or attribute names should be used to 477 differentiate protocol elements that carry a URI Template from those 478 that expect a URI reference. 480 Some URI Templates can be used in reverse for the purpose of variable 481 matching: comparing the template to a fully formed URI in order to 482 extract the variable parts from that URI and assign them to the named 483 variables. Variable matching only works well if the template 484 expressions are delimited by the beginning or end of the URI or by 485 characters that cannot be part of the expansion, such as reserved 486 characters surrounding a simple string expression. In general, 487 regular expression languages are better suited for variable matching. 489 1.5. Notational Conventions 491 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 492 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 493 document are to be interpreted as described in [RFC2119]. 495 This specification uses the Augmented Backus-Naur Form (ABNF) 496 notation of [RFC5234]. The following ABNF rules are imported from 497 the normative references [RFC5234], [RFC3986], and [RFC3987]. 499 ALPHA = %x41-5A / %x61-7A ; A-Z / a-z 500 DIGIT = %x30-39 ; 0-9 501 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" 503 pct-encoded = "%" HEXDIG HEXDIG 504 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 505 reserved = gen-delims / sub-delims 506 gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" 507 sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 508 / "*" / "+" / "," / ";" / "=" 510 ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF 511 / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD 512 / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD 513 / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD 514 / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD 515 / %xD0000-DFFFD / %xE1000-EFFFD 517 iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD 519 1.6. Character Encoding and Unicode Normalization 521 This specification uses the terms "character" and "coded character 522 set" in accordance with the definitions provided in [RFC2978], and 523 "character encoding" in place of what [RFC2978] refers to as a 524 "charset". 526 The ABNF notation defines its terminal values to be non-negative 527 integers (codepoints) that are a superset of the US-ASCII coded 528 character set [ASCII]. This specification defines terminal values as 529 codepoints within the Unicode coded character set [UNIV4]. 531 In spite of the syntax and template expansion process being defined 532 in terms of Unicode codepoints, it should be understood that 533 templates occur in practice as a sequence of characters in whatever 534 form or encoding is suitable for the context in which they occur, 535 whether that be octets embedded in a network protocol element or 536 paint applied to the side of a bus. This specification does not 537 mandate any particular character encoding for mapping between URI 538 Template characters and the octets used to store or transmit those 539 characters. When a URI Template appears in a protocol element, the 540 character encoding is defined by that protocol; without such a 541 definition, a URI Template is assumed to be in the same character 542 encoding as the surrounding text. It is only during the process of 543 template expansion that a string of characters in a URI Template is 544 REQUIRED to be processed as a sequence of Unicode codepoints. 546 The Unicode Standard [UNIV4] defines various equivalences between 547 sequences of characters for various purposes. Unicode Standard Annex 548 #15 [UTR15] defines various Normalization Forms for these 549 equivalences. The normalization form determines how to consistently 550 encode equivalent strings. In theory, all URI processing 551 implementations, including template processors, should use the same 552 normalization form for generating a URI reference. In practice, they 553 do not. If a value has been provided by the same server as the 554 resource, then it can be assumed that the string is already in the 555 form expected by that server. If a value is provided by a user, such 556 as via a data-entry dialog, then the string SHOULD be normalized as 557 Normalization Form C (NFC: Canonical Decomposition, followed by 558 Canonical Composition) prior to being used in expansions by a 559 template processor. 561 Likewise, when non-ASCII data that represents readable strings is 562 pct-encoded for use in a URI reference, a template processor MUST 563 first encode the string as UTF-8 [RFC3629] and then pct-encode any 564 octets that are not allowed in a URI reference. 566 2. Syntax 568 A URI Template is a string of printable Unicode characters that 569 contains zero or more embedded variable expressions, each expression 570 being delimited by a matching pair of braces ('{', '}'). 572 URI-Template = *( literals / expression ) 574 Although templates (and template processor implementations) are 575 described above in terms of four gradual levels, we define the URI- 576 Template syntax in terms of the ABNF for Level 4. A template 577 processor limited to lower level templates MAY exclude the ABNF rules 578 applicable only to higher levels. However, it is RECOMMENDED that 579 all parsers implement the full syntax such that unsupported levels 580 can be properly identified as such to the end user. 582 2.1. Literals 584 The characters outside of expressions in a URI Template string are 585 intended to be copied literally to the URI-reference if the character 586 is allowed in a URI (reserved / unreserved / pct-encoded) or, if not 587 allowed, copied to the URI-reference in its UTF-8 pct-encoded form. 589 literals = %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B 590 / %x5D-5F / %x61-7A / %x7E / ucschar / iprivate 591 / pct-encoded 592 ; any Unicode character except: CTL, SP, 593 ; DQUOTE, "'", "%" (aside from pct-encoded), 594 ; "<", ">", "\", "^", "`", "{", "|", "}" 596 2.2. Expressions 598 Template expressions are the parameterized parts of a URI Template. 599 Each expression contains an optional operator, which defines the 600 expression type and its corresponding expansion process, followed by 601 a comma-separated list of variable specifiers (variable names and 602 optional value modifiers). If no operator is provided, the 603 expression defaults to simple variable expansion of unreserved 604 values. 606 expression = "{" [ operator ] variable-list "}" 607 operator = "+" / "#" / "." / "/" / ";" / "?" / "&" 608 / op-reserve 609 op-reserve = "=" / "," / "!" / "@" / "|" 610 ; reserved for local use: "$" / "(" / ")" 612 The operator characters have been chosen to reflect each of their 613 roles as reserved characters in the URI generic syntax. The 614 operators defined in Section 3 of this specification include: 616 + Reserved character strings; 618 # Fragment identifiers prefixed by "#"; 620 . Name labels or extensions prefixed by "."; 622 / Path segments prefixed by "/"; 624 ; Path parameter name or name=value pairs prefixed by ";"; 626 ? Query component beginning with "?" and consisting of 627 name=value pairs separated by "&"; and, 629 & Continuation of query-style &name=value pairs within 630 a literal query component. 632 The operator characters equals ("="), comma (","), exclamation ("!"), 633 at-sign ("@"), and pipe ("|") are reserved for future extensions. 635 The expression syntax specifically excludes use of the dollar ("$") 636 and parentheses ["(" and ")"] characters so that they remain 637 available for local language extensions outside the scope of this 638 specification. 640 2.3. Variables 642 After the operator (if any), each expression contains a list of one 643 or more comma-separated variable specifiers (varspec). The variable 644 names serve multiple purposes: documentation for what kinds of values 645 are expected, identifiers for associating values within a template 646 processor, and the literal string to use for the name in name=value 647 expansions (aside from when exploding an associative array). 649 variable-list = varspec *( "," varspec ) 650 varspec = varname [ modifier ] 651 varname = varchar *( varchar / "." ) 652 varchar = ALPHA / DIGIT / "_" / pct-encoded 654 A varname MAY contain one or more pct-encoded triplets. These 655 triplets are considered an essential part of the variable name and 656 are not decoded during processing. A varname containing pct-encoded 657 characters is not the same variable as a varname with those same 658 characters decoded. Applications that provide URI Templates are 659 expected to be consistent in their use of pct-encoding within 660 variable names. 662 An expression MAY reference variables that are unknown to the 663 template processor or whose value is set to a special "undefined" 664 value, such as undef or null. Such undefined variables are given 665 special treatment by the expansion process. 667 A variable value that is a string of length zero is not considered 668 undefined; it has the defined value of an empty string. 670 A variable may have a composite value in the form of a list of values 671 or an associative array of (name, value) pairs. Such value types are 672 not directly indicated by the template syntax, but do have an impact 673 on the expansion process. A composite value with zero member values 674 is considered undefined. 676 2.4. Value Modifiers 678 Each of the variables in a Level 4 template expression can have a 679 modifier indicating either that its expansion is limited to a prefix 680 of the variable's value string or that its expansion is exploded as a 681 composite value in the form of a value list or an associative array 682 of (name, value) pairs. 684 modifier = prefix / explode 686 2.4.1. Prefix Values 688 A prefix modifier indicates that the variable expansion is limited to 689 a prefix of the variable's value string. Prefix modifiers are often 690 used to partition an identifier space hierarchically, as is common in 691 reference indices and hash-based storage. It also serves to limit 692 the expanded value to a maximum number of characters. Prefix 693 modifiers are not applicable to variables that have composite values. 695 prefix = ":" max-length 696 max-length = %x31-39 *DIGIT ; positive integer 698 The max-length is a positive integer that refers to a maximum number 699 of characters from the beginning of the variable's value as a Unicode 700 string. Note that this numbering is in characters, not octets, in 701 order to avoid splitting between the octets of a multi-octet UTF-8 702 encoded character or within a pct-encoded triplet. If the max-length 703 is greater than the length of the variable's value, then the entire 704 value string is used. 706 For example, 708 Given the variable assignments 710 var := "value" 711 semi := ";" 713 Example Template Expansion 715 {var} value 716 {var:20} value 717 {var:3} val 718 {semi} %3B 719 {semi:2} %3B 721 2.4.2. Composite Values 723 An explode ("*") modifier indicates that the variable is to be 724 treated as a composite value consisting of either a list of names or 725 an associative array of (name, value) pairs. Hence, the expansion 726 process is applied to each member of the composite as if it were 727 listed as a separate variable. This kind of variable specification 728 is significantly less self-documenting than non-exploded variables, 729 since there is less correspondence between the variable name and how 730 the URI reference appears after expansion. 732 explode = "*" 734 Since URI Templates do not contain an indication of type or schema, 735 the type for an exploded variable is assumed to be determined by 736 context. For example, the processor might be supplied values in a 737 form that differentiates values as strings, lists, or associative 738 arrays. Likewise, the context in which the template is used (script, 739 mark-up language, IDL, etc.) might define rules for associating 740 variable names with types, structures, or schema. 742 Explode modifiers improve brevity in the URI Template syntax. For 743 example, a resource that provides a geographic map for a given street 744 address might accept a hundred permutations on fields for address 745 input, including partial addresses (e.g., just the city or postal 746 code). Such a resource could be described as a template with each 747 and every address component listed in order, or with a far more 748 simple template that makes use of an explode modifier, as in 750 /mapper{?address*} 752 along with some context that defines what the variable named 753 "address" can include, such as by reference to some other standard 754 for addressing (e.g., UPU S42 or AS/NZS 4819:2003). A recipient 755 aware of the schema can then provide appropriate expansions, such as: 757 /mapper?city=Newport%20Beach&state=CA 759 The expansion process for exploded variables is dependent on both the 760 operator being used and whether the composite value is to be treated 761 as a list of values or as an associative array of (name, value) 762 pairs. Structures are processed as if they are an associative array 763 with names corresponding to the fields in the structure definition 764 and "." separators used to indicate name hierarchy in substructures. 766 3. Expansion 768 The process of URI Template expansion is to scan the template string 769 from beginning to end, copying literal characters and replacing each 770 expression with the result of applying the expression's operator to 771 the value of each variable named in the expression. Each variable's 772 value MUST be formed prior to template expansion. 774 The requirements on expansion for each aspect of the URI Template 775 grammar are defined in this section. A non-normative algorithm for 776 the expansion process as a whole is provided in Appendix A. 778 If a template processor encounters an error outside of an expression, 779 such as a character sequence that does not match the 780 grammar, then processing of the template SHOULD cease, the URI- 781 reference result SHOULD contain the expanded part of the template 782 followed by the remainder unexpanded, and the location and type of 783 error SHOULD be indicated to the invoking application. If an error 784 is encountered inside an expression, such as an operator or value 785 modifier that it does not recognize or cannot support, then the 786 expression SHOULD be copied to the result unexpanded, processing of 787 the remainder of the template SHOULD continue, and the location and 788 type of error SHOULD be indicated to the invoking application. If an 789 error occurs, the result returned might not be a valid URI reference; 790 it will be an incompletely expanded template string that is only 791 intended for diagnostic use. 793 3.1. Literal Expansion 795 If the literal character is allowed anywhere in the URI syntax 796 (unreserved / reserved / pct-encoded ), then it is copied directly to 797 the result string. Otherwise, the pct-encoded equivalent of the 798 literal character is copied to the result string by encoding the 799 character in UTF-8 (a sequence of octets) and then encoding each 800 octet as a pct-encoded triplet. 802 3.2. Expression Expansion 804 Each expression is indicated by an opening brace ("{") character and 805 continues until the next closing brace ("}"). The expression is 806 expanded by determining the expression type and then following that 807 type's expansion process for each comma-separated varspec in the 808 expression. Level 1 templates are limited to the default operator 809 (simple string value expansion) and a single variable per expression. 810 Level 2 templates are limited to a single varspec per expression. 812 The expression type is determined by looking at the first character 813 after the opening brace. If the character is an operator, then 814 remember the expression type associated with that operator for later 815 expansion decisions and skip to the next character for the variable- 816 list. If the first character is not an operator, then the expression 817 type is simple string expansion and the first character is the 818 beginning of the variable-list. 820 The examples in the subsections below use the following definitions 821 for variable values: 823 dom := "example.com" 824 dub := "me/too" 825 hello := "Hello World!" 826 half := "50%" 827 var := "value" 828 who := "fred" 829 base := "http://example.com/home/" 830 path := "/foo/bar" 831 list := [ "red", "green", "blue" ] 832 keys := [("semi",";"),("dot","."),("comma",",")] 833 v := "6" 834 x := "1024" 835 y := "768" 836 empty := "" 837 empty_keys := [] 838 undef := null 840 3.2.1. Variable Expansion 842 A variable that is undefined has no value and is ignored by the 843 expansion process. A variable defined as a list value is considered 844 undefined if the list contains zero members. A variable defined as 845 an associative array of (name, value) pairs is considered undefined 846 if the array contains zero members or if all member names in the 847 array have undefined values. If all of the variables in an 848 expression are undefined, then the expression's expansion is the 849 empty string. 851 Variable expansion of a defined, non-empty value results in a 852 substring of allowed URI characters. A template processor MUST 853 encode the value string as UTF-8 and transform each octet that is not 854 in the allowed set into the corresponding pct-encoded triplet. The 855 allowed set depends on the expression type: reserved ("+") and 856 fragment ("#") expansions allow the set of characters in ( unreserved 857 / reserved / pct-encoded ) to be passed through without pct-encoding, 858 whereas all other expression types allow only unreserved characters 859 to be passed through without pct-encoding. Note that the percent 860 character ("%") is only allowed as part of a pct-encoded triplet and 861 only for reserved/fragment expansion: in all other cases, a value of 862 "%" MUST be pct-encoded as "%25" by variable expansion. 864 If a variable appears more than once in an expression or within 865 multiple expressions of a URI Template, the value of that variable 866 MUST remain static throughout the expansion process (i.e., the 867 variable must have the same value for the purpose of calculating each 868 expansion). However, if reserved characters or pct-encoded triplets 869 occur in the value, they will be pct-encoded by some expression types 870 and not by others. 872 For a variable that is a simple string value, expansion consists of 873 appending the encoded value to the result string. The explode 874 modifier has no effect. The prefix modifier limits the expansion to 875 the first max-length characters of the decoded value. If the value 876 contains multibyte UTF-8, care must be taken to avoid splitting the 877 value in mid-character: count each Unicode codepoint as one 878 character. 880 For a variable that is a list of values, expansion consists of 881 concatenating the defined member string values, encoded as above, 882 with a separator string inserted between those values. If no explode 883 modifier is given, the separator string is a comma (","). If an 884 explode modifier is given, the separator string is defined per 885 operator by the following table, where NUL is the default expression 886 type: 888 .-----------------------------------------------------------------. 889 | operator: NUL + . / ; ? & # | 890 | separator: "," "," "." "/" ";" "&" "&" "," | 891 `-----------------------------------------------------------------' 893 For a variable that is an associative array, expansion consists of a 894 list of either "name,value" (without explode modifier) or 895 "name=value" (with explode modifier) pairs, excluding any pairs for 896 which the corresponding value is undefined, with a separator string 897 inserted between defined pairs. The separator string is defined in 898 the same way as for list variables above. Both the name and value 899 strings are encoded in the same way as simple string values. 901 3.2.2. Simple String Expansion: {var} 903 Simple string expansion is the default expression type when no 904 operator is given. 906 For each defined variable in the variable-list, perform variable 907 expansion, as defined in Section 3.2.1, with the allowed characters 908 being those in the unreserved set. If more than one variable has a 909 defined value, append a comma (",") to the result string as a 910 separator between variable expansions. 912 Example Template Expansion 914 {var} value 915 {hello} Hello%20World%21 916 {half} 50%25 917 O{empty}X OX 918 O{undef}X OX 919 {x,y} 1024,768 920 {x,hello,y} 1024,Hello%20World%21,768 921 ?{x,empty} ?1024, 922 ?{x,undef} ?1024 923 ?{undef,y} ?768 924 {var:3} val 925 {var:30} value 926 {list} red,green,blue 927 {list*} red,green,blue 928 {keys} semi,%3B,dot,.,comma,%2C 929 {keys*} semi=%3B,dot=.,comma=%2C 931 3.2.3. Reserved expansion: {+var} 933 Reserved expansion, as indicated by the plus ("+") operator for Level 934 2 and above templates, is identical to simple string expansion except 935 that the substituted values may also contain pct-encoded triplets and 936 characters in the reserved set. 938 For each defined variable in the variable-list, perform variable 939 expansion, as defined in Section 3.2.1, with the allowed characters 940 being those in the set (unreserved / reserved / pct-encoded). If 941 more than one variable has a defined value, append a comma (",") to 942 the result string as a separator between variable expansions. 944 Example Template Expansion 946 {+var} value 947 {+hello} Hello%20World! 948 {+half} 50%25 950 {base}index http%3A%2F%2Fexample.com%2Fhome%2Findex 951 {+base}index http://example.com/home/index 952 O{+empty}X OX 953 O{+undef}X OX 955 {+path}/here /foo/bar/here 956 here?ref={+path} here?ref=/foo/bar 957 up{+path}{var}/here up/foo/barvalue/here 958 {+x,hello,y} 1024,Hello%20World!,768 959 {+path,x}/here /foo/bar,1024/here 961 {+path:6}/here /foo/b/here 962 {+list} red,green,blue 963 {+list*} red,green,blue 964 {+keys} semi,;,dot,.,comma,, 965 {+keys*} semi=;,dot=.,comma=, 967 3.2.4. Fragment expansion: {#var} 969 Fragment expansion, as indicated by the crosshatch ("#") operator for 970 Level 2 and above templates, is identical to reserved expansion 971 except that a crosshatch character (fragment delimiter) is appended 972 first to the result string if any of the variables are defined. 974 Example Template Expansion 976 {#var} #value 977 {#hello} #Hello%20World! 978 {#half} #50%25 979 foo{#empty} foo# 980 foo{#undef} foo 981 {#x,hello,y} #1024,Hello%20World!,768 982 {#path,x}/here #/foo/bar,1024/here 983 {#path:6}/here #/foo/b/here 984 {#list} #red,green,blue 985 {#list*} #red,green,blue 986 {#keys} #semi,;,dot,.,comma,, 987 {#keys*} #semi=;,dot=.,comma=, 989 3.2.5. Label expansion with dot-prefix: {.var} 991 Label expansion, as indicated by the dot (".") operator for Level 3 992 and above templates, is useful for describing URI spaces with varying 993 domain names or path selectors (e.g., filename extensions). 995 For each defined variable in the variable-list, append "." to the 996 result string and then perform variable expansion, as defined in 997 Section 3.2.1, with the allowed characters being those in the 998 unreserved set. 1000 Since "." is in the unreserved set, a value that contains a "." has 1001 the effect of adding multiple labels. 1003 Example Template Expansion 1005 {.who} .fred 1006 {.who,who} .fred.fred 1007 {.half,who} .50%25.fred 1008 www{.dom} www.example.com 1009 X{.var} X.value 1010 X{.empty} X. 1011 X{.undef} X 1012 X{.var:3} X.val 1013 X{.list} X.red,green,blue 1014 X{.list*} X.red.green.blue 1015 X{.keys} X.semi,%3B,dot,.,comma,%2C 1016 X{.keys*} X.semi=%3B.dot=..comma=%2C 1017 X{.empty_keys} X 1018 X{.empty_keys*} X 1020 3.2.6. Path segment expansion: {/var} 1022 Path segment expansion, as indicated by the slash ("/") operator in 1023 Level 3 and above templates, is useful for describing URI path 1024 hierarchies. 1026 For each defined variable in the variable-list, append "/" to the 1027 result string and then perform variable expansion, as defined in 1028 Section 3.2.1, with the allowed characters being those in the 1029 unreserved set. 1031 Note that the expansion process for path segment expansion is 1032 identical to that of label expansion aside from the substitution of 1033 "/" instead of ".". However, unlike ".", a "/" is a reserved 1034 character and will be pct-encoded if found in a value. 1036 Example Template Expansion 1038 {/who} /fred 1039 {/who,who} /fred/fred 1040 {/half,who} /50%25/fred 1041 {/who,dub} /fred/me%2Ftoo 1042 {/var} /value 1043 {/var,empty} /value/ 1044 {/var,undef} /value 1045 {/var,x}/here /value/1024/here 1046 {/var:1,var} /v/value 1047 {/list} /red,green,blue 1048 {/list*} /red/green/blue 1049 {/list*,path:4} /red/green/blue/%2Ffoo 1050 {/keys} /semi,%3B,dot,.,comma,%2C 1051 {/keys*} /semi=%3B/dot=./comma=%2C 1053 3.2.7. Path-style parameter expansion: {;var} 1055 Path-style parameter expansion, as indicated by the semicolon (";") 1056 operator in Level 3 and above templates, is useful for describing URI 1057 path parameters, such as "path;property" or "path;name=value". 1059 For each defined variable in the variable-list: 1060 o append ";" to the result string; 1061 o if the variable has a simple string value or no explode modifier 1062 is given, then: 1063 * append the variable name (encoded as if it were a literal 1064 string) to the result string; 1065 * if the variable's value is not empty, append "=" to the result 1066 string; 1067 o perform variable expansion, as defined in Section 3.2.1, with the 1068 allowed characters being those in the unreserved set. 1070 Example Template Expansion 1072 {;who} ;who=fred 1073 {;half} ;half=50%25 1074 {;empty} ;empty 1075 {;v,empty,who} ;v=6;empty;who=fred 1076 {;v,bar,who} ;v=6;who=fred 1077 {;x,y} ;x=1024;y=768 1078 {;x,y,empty} ;x=1024;y=768;empty 1079 {;x,y,undef} ;x=1024;y=768 1080 {;hello:5} ;hello=Hello 1081 {;list} ;list=red,green,blue 1082 {;list*} ;red;green;blue 1083 {;keys} ;keys=semi,%3B,dot,.,comma,%2C 1084 {;keys*} ;semi=%3B;dot=.;comma=%2C 1086 3.2.8. Form-style query expansion: {?var} 1088 Form-style query expansion, as indicated by the question-mark ("?") 1089 operator in Level 3 and above templates, is useful for describing an 1090 entire optional query component. 1092 For each defined variable in the variable-list: 1093 o append "?" to the result string if this is the first defined value 1094 or append "&" thereafter; 1095 o if the variable has a simple string value or no explode modifier 1096 is given, append the variable name (encoded as if it were a 1097 literal string) and an equals character ("=") to the result 1098 string; and, 1099 o perform variable expansion, as defined in Section 3.2.1, with the 1100 allowed characters being those in the unreserved set. 1102 Example Template Expansion 1104 {?who} ?who=fred 1105 {?half} ?half=50%25 1106 {?x,y} ?x=1024&y=768 1107 {?x,y,empty} ?x=1024&y=768&empty= 1108 {?x,y,undef} ?x=1024&y=768 1109 {?var:3} ?var=val 1110 {?list} ?list=red,green,blue 1111 {?list*} ?red&green&blue 1112 {?keys} ?keys=semi,%3B,dot,.,comma,%2C 1113 {?keys*} ?semi=%3B&dot=.&comma=%2C 1115 3.2.9. Form-style query continuation: {&var} 1117 Form-style query continuation, as indicated by the ampersand ("&") 1118 operator in Level 3 and above templates, is useful for describing 1119 optional &name=value pairs in a template that already contains a 1120 literal query component with fixed parameters. 1122 For each defined variable in the variable-list: 1123 o append "&" to the result string; 1124 o if the variable has a simple string value or no explode modifier 1125 is given, append the variable name (encoded as if it were a 1126 literal string) and an equals character ("=") to the result 1127 string; and, 1128 o perform variable expansion, as defined in Section 3.2.1, with the 1129 allowed characters being those in the unreserved set. 1131 Example Template Expansion 1133 {&who} &who=fred 1134 {&half} &half=50%25 1135 ?fixed=yes{&x} ?fixed=yes&x=1024 1136 {&x,y,empty} &x=1024&y=768&empty= 1137 {&x,y,undef} &x=1024&y=768 1139 {&var:3} &var=val 1140 {&list} &list=red,green,blue 1141 {&list*} &red&green&blue 1142 {&keys} &keys=semi,%3B,dot,.,comma,%2C 1143 {&keys*} &semi=%3B&dot=.&comma=%2C 1145 4. Security Considerations 1147 A URI Template does not contain active or executable content. Other 1148 security considerations are the same as those for URIs, as described 1149 in section 7 of [RFC3986]. 1151 5. IANA Considerations 1153 No IANA actions are required by this document. 1155 6. Acknowledgments 1157 The following people made significant contributions to this 1158 specification: Mike Burrows, Michaeljohn Clement, DeWitt Clinton, 1159 John Cowan, Robbie Gates, James H. Manger, Marc Portier, and James 1160 Snell. 1162 7. Normative References 1164 [ASCII] American National Standards Institute, "Coded Character 1165 Set - 7-bit American Standard Code for Information 1166 Interchange", ANSI X3.4, 1986. 1168 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1169 Requirement Levels", BCP 14, RFC 2119, March 1997. 1171 [RFC2978] Freed, N. and J. Postel, "IANA Charset Registration 1172 Procedures", BCP 19, RFC 2978, October 2000. 1174 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 1175 10646", STD 63, RFC 3629, November 2003. 1177 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 1178 Resource Identifier (URI): Generic Syntax", STD 66, 1179 RFC 3986, January 2005. 1181 [RFC3987] Duerst, M. and M. Suignard, "Internationalized Resource 1182 Identifiers (IRIs)", RFC 3987, January 2005. 1184 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 1185 Specifications: ABNF", STD 68, RFC 5234, January 2008. 1187 [UNIV4] The Unicode Consortium, "The Unicode Standard, Version 1188 4.0.1, defined by: The Unicode Standard, Version 4.0 1189 (Reading, MA, Addison-Wesley, 2003. ISBN 0-321-18578-1), 1190 as amended by Unicode 4.0.1 1191 (http://www.unicode.org/versions/Unicode4.0.1/)", 1192 March 2004. 1194 [UTR15] Davis, M. and M. Duerst, "Unicode Normalization Forms", 1195 Unicode Standard Annex # 15, April 2003. 1197 [1] 1199 Appendix A. Implementation Hints 1201 The normative sections on expansion describe each operator with a 1202 separate expansion process for the sake of descriptive clarity. In 1203 actual implementations, we expect the expressions to be processed 1204 left-to-right using a common algorithm that has only minor variations 1205 in process per operator. This appendix describes one such algorithm. 1207 Initialize an empty result string and its non-error state. 1209 Scan the template and copy literals to the result string (as in 1210 Section 3.1) until an expression is indicated by a "{" or the 1211 template ends. When it ends, return the result string and its 1212 current error or non-error state. 1213 o If an expression is found, scan the template to the next "}" and 1214 extract the characters in between the braces. 1215 o If the template ends before a "}", then append the "{" and 1216 extracted characters to the result string and return with an error 1217 status indicating the expression is malformed. 1219 Examine the first character of the extracted expression for an 1220 operator. 1222 o If the expression ended (i.e., is "{}"), an operator is found that 1223 is unknown or unimplemented, or the character is not in the 1224 varchar set (Section 2.3), then append "{", the extracted 1225 expression, and "}" to the result string, remember that the result 1226 is in an error state, and then go back to scan the remainder of 1227 the template. 1228 o If a known and implemented operator is found, store the operator 1229 and skip to the next character to begin the varspec-list. 1230 o Otherwise, store the operator as NUL (simple string expansion). 1232 Use the following value table to determine the processing behavior by 1233 expression type operator. The entry for "first" is the string to 1234 append to the result first if any of the expression's variables are 1235 defined. The entry for "sep" is the separator to append to the 1236 result before any second (or subsequent) defined variable expansion. 1237 The entry for "named" is a boolean for whether or not the expansion 1238 includes the variable or key name when no explode modifier is given. 1239 The entry for "ifemp" is a string to append to the name if its 1240 corresponding value is empty. The entry for "allow" indicates what 1241 characters to allow unencoded within the value expansion: (U) means 1242 any character not in the unreserved set will be encoded; (U+R) means 1243 any character not in the (unreserved / reserved / pct-encoding) set 1244 will be encoded; and, for both cases, disallowed characters are 1245 encoded as UTF-8 (a sequence of octets) and then each octet is 1246 encoded as a pct-encoded triplet. 1248 .------------------------------------------------------------------. 1249 | NUL + . / ; ? & # | 1250 |------------------------------------------------------------------| 1251 | first | "" "" "." "/" ";" "?" "&" "#" | 1252 | sep | "," "," "." "/" ";" "&" "&" "," | 1253 | named | false false false false true true true false | 1254 | ifemp | "" "" "" "" "" "=" "=" "" | 1255 | allow | U U+R U U U U U U+R | 1256 `------------------------------------------------------------------' 1258 With the above table in mind, process the variable-list as follows: 1260 For each varspec, extract the varname and optional modifier, lookup 1261 the value for that variable, and then: 1262 o If the varname is unknown or corresponds to a variable with an 1263 undefined value (Section 3.2.1), then skip to the next varspec. 1264 o If this is the first defined variable for this expression, append 1265 the first string for this expression type to the result string and 1266 remember that it has been done. Otherwise, append the sep string 1267 to the result string. 1269 o If this variable's value is a string, then: 1270 * if named is true, append the varname to the result string using 1271 the same encoding process as for literals, and 1272 + if the value is empty, append the ifemp string to the result 1273 string and skip to the next varspec; 1274 + otherwise, append "=" to the result string. 1275 * if a prefix modifier is present and the prefix length is less 1276 than the value string length in number of Unicode characters, 1277 append that number of characters from the beginning of the 1278 value string to the result string, after encoding any 1279 characters that are not in the allow set, while taking care not 1280 to split multi-octet or pct-encoded triplet characters that 1281 represent a single Unicode codepoint; 1282 * otherwise, append the value to the result string after encoding 1283 any characters that are not in the allow set. 1284 o If this variable's value is a list, then: 1285 * if no explode modifier is given, then: 1286 + if named is true, append the varname to the result string 1287 using the same encoding process as for literals, and 1288 - if the value is empty, append the ifemp string to the 1289 result string and skip to the next varspec; 1290 - otherwise, append "=" to the result string; and 1291 + append each defined list member to the result string, after 1292 encoding any characters that are not in the allow set, with 1293 a comma (",") appended to the result between each defined 1294 list member. 1295 * else if an explode modifier is given, then: 1296 + append each defined list member to the result string, after 1297 encoding any characters that are not in the allow set, with 1298 the sep string appended to the result between each defined 1299 list member. 1300 o If this variable's value is an associative array or any other form 1301 of paired (name, value) structure, then: 1302 * if no explode modifier is given, then: 1303 + if named is true, append the varname to the result string 1304 using the same encoding process as for literals, and 1305 - if the value is empty, append the ifemp string to the 1306 result string and skip to the next varspec; 1307 - otherwise, append "=" to the result string; and 1308 + append each pair with a defined value to the result string 1309 as "name,value", after encoding any characters that are not 1310 in the allow set, with a comma (",") appended to the result 1311 between each defined pair. 1312 * else if an explode modifier is given, then: 1313 + append each pair with a defined value to the result string 1314 as "name=value", after encoding any characters that are not 1315 in the allow set, with the sep string appended to the result 1316 between each defined pair. 1318 When the variable-list for this expression is exhausted, go back to 1319 scan the remainder of the template. 1321 Authors' Addresses 1323 Joe Gregorio 1324 Google 1326 Email: joe@bitworking.org 1327 URI: http://bitworking.org/ 1329 Roy T. Fielding 1330 Adobe Systems Incorporated 1332 Email: fielding@gbiv.com 1333 URI: http://roy.gbiv.com/ 1335 Marc Hadley 1336 The MITRE Corporation 1338 Email: mhadley@mitre.org 1339 URI: http://mitre.org/ 1341 Mark Nottingham 1342 Rackspace 1344 Email: mnot@mnot.net 1345 URI: http://www.mnot.net/ 1347 David Orchard 1348 Salesforce.com 1350 URI: http://www.pacificspirit.com/