idnits 2.17.1 draft-gregorio-uritemplate-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** It looks like you're using RFC 3978 boilerplate. You should update this to the boilerplate described in the IETF Trust License Policy document (see https://trustee.ietf.org/license-info), which is required now. -- Found old boilerplate from RFC 3978, Section 5.1 on line 20. -- Found old boilerplate from RFC 3978, Section 5.5, updated by RFC 4748 on line 671. -- Found old boilerplate from RFC 3979, Section 5, paragraph 1 on line 682. -- Found old boilerplate from RFC 3979, Section 5, paragraph 2 on line 689. -- Found old boilerplate from RFC 3979, Section 5, paragraph 3 on line 695. 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 Copyright Line does not match the current year -- 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 (Mar 26, 2008) is 5874 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' ** Obsolete normative reference: RFC 4395 (Obsoleted by RFC 7595) -- 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: 3 errors (**), 0 flaws (~~), 1 warning (==), 12 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group J. Gregorio, Ed. 3 Internet-Draft Google 4 Intended status: Standards Track M. Hadley, Ed. 5 Expires: September 27, 2008 Sun Microsystems 6 M. Nottingham, Ed. 8 D. Orchard 9 BEA Systems, Inc. 10 Mar 26, 2008 12 URI Template 13 draft-gregorio-uritemplate-03 15 Status of this Memo 17 By submitting this Internet-Draft, each author represents that any 18 applicable patent or other IPR claims of which he or she is aware 19 have been or will be disclosed, and any of which he or she becomes 20 aware will be disclosed, in accordance with Section 6 of BCP 79. 22 Internet-Drafts are working documents of the Internet Engineering 23 Task Force (IETF), its areas, and its working groups. Note that 24 other groups may also distribute working documents as Internet- 25 Drafts. 27 Internet-Drafts are draft documents valid for a maximum of six months 28 and may be updated, replaced, or obsoleted by other documents at any 29 time. It is inappropriate to use Internet-Drafts as reference 30 material or to cite them other than as "work in progress." 32 The list of current Internet-Drafts can be accessed at 33 http://www.ietf.org/ietf/1id-abstracts.txt. 35 The list of Internet-Draft Shadow Directories can be accessed at 36 http://www.ietf.org/shadow.html. 38 This Internet-Draft will expire on September 27, 2008. 40 Abstract 42 A URI Template is a compact sequence of characters used for the 43 construction of URIs. This specification defines the URI Template 44 syntax and the process for expanding a URI Template into a URI, along 45 with guidelines and security considerations for the use of URI 46 Templates on the Internet. The URI Template syntax allows for the 47 construction of strings that are a superset of URIs, allowing an 48 implementation to process any URI Template without knowing the 49 scheme-specific requirements of every possible resulting URI. 51 Editorial Note 53 To provide feedback on this Internet-Draft, join the W3C URI mailing 54 list (http://lists.w3.org/Archives/Public/uri/) [1]. 56 Table of Contents 58 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 59 1.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . 3 60 1.2. Design Considerations . . . . . . . . . . . . . . . . . . 4 61 1.3. Applicability . . . . . . . . . . . . . . . . . . . . . . 4 62 1.4. Notational Conventions . . . . . . . . . . . . . . . . . . 4 63 2. Characters . . . . . . . . . . . . . . . . . . . . . . . . . . 5 64 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 65 4. URI Template . . . . . . . . . . . . . . . . . . . . . . . . . 5 66 4.1. Variables . . . . . . . . . . . . . . . . . . . . . . . . 5 67 4.2. Template Expansions . . . . . . . . . . . . . . . . . . . 6 68 4.3. Error Handling . . . . . . . . . . . . . . . . . . . . . . 6 69 4.4. URI Template Substitution . . . . . . . . . . . . . . . . 7 70 4.4.1. ('var') substitution . . . . . . . . . . . . . . . . . 8 71 4.4.2. The 'opt' operator . . . . . . . . . . . . . . . . . . 8 72 4.4.3. The 'neg' operator . . . . . . . . . . . . . . . . . . 8 73 4.4.4. The 'prefix' operator . . . . . . . . . . . . . . . . 9 74 4.4.5. The 'suffix' operator . . . . . . . . . . . . . . . . 9 75 4.4.6. The 'join' operator . . . . . . . . . . . . . . . . . 9 76 4.4.7. The 'list' operator . . . . . . . . . . . . . . . . . 10 77 4.5. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 11 78 5. Security Considerations . . . . . . . . . . . . . . . . . . . 12 79 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12 80 7. Appendix A - Parsing URI Template Expansions . . . . . . . . . 13 81 8. Normative References . . . . . . . . . . . . . . . . . . . . . 13 82 Appendix A. Contributors . . . . . . . . . . . . . . . . . . . . 14 83 Appendix B. Revision History . . . . . . . . . . . . . . . . . . 14 84 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 15 85 Intellectual Property and Copyright Statements . . . . . . . . . . 16 87 1. Introduction 89 A URI Template provides a simple and extensible format for URI 90 construction. A URI Template is a string that contains embedded 91 expansions, text marked off in matching braces ('{', '}'), that 92 denotes a part of the string that is to be substituted by a template 93 processor to produce a URI. A URI Template is transformed into a URI 94 by substituting the expansions with their calculated value. 96 Several specifications have defined URI Templates with varying levels 97 of formality, such as WSDL, WADL and OpenSearch. This specification 98 is derived from these concepts, giving a rigorous definition to such 99 templates. 101 This specification uses the terms "character" and "coded character 102 set" in accordance with the definitions provided in [RFC2978], and 103 "character encoding" in place of what [RFC2978] refers to as a 104 "charset". 106 1.1. Overview 108 A URI Template allows a structural description of URIs while allowing 109 a consumer of the template to construct a final URI by providing the 110 values of the expansion variables. For example, given the following 111 URI Template: 113 http://www.example.com/users/{userid} 115 And the following variable value 117 userid := "fred" 119 The expansion of the URI Template is: 121 http://www.example.com/users/fred 123 Here is an example that constructs a query from multiple variables: 125 http://www.example.com/?{-join|&|query,number} 127 And the following variables 129 query := "mycelium" 130 number := 100 132 The expansion of the URI Template is: 134 http://www.example.com/?query=mycelium&number=100 136 The template expansion describes in a machine readable manner how the 137 URI is to be constructed. 139 http://www.example.com/?{-join|&|query,number} 140 \____________________/ 141 | 142 | 143 Join 'var=value' for each variable 144 in ['query', 'number'] with '&'. 146 1.2. Design Considerations 148 The URI Template syntax has been designed to carefully balance the 149 need for a powerful substitution mechanism with ease of 150 implementation and security. The syntax is designed to be easy to 151 parse while at the same time providing enough flexibility to express 152 many common templating scenarios. 154 Another consideration was to keep the syntax and processing in-line 155 with the pre-existing templating schemes present in OpenSearch, WSDL 156 and WADL. 158 The final design consideration was control over the placement of 159 reserved characters in the URI generated from a URI Template. The 160 reserved characters in a URI Template can only appear in the non- 161 expansion text, or in the argument to an operator, both locations are 162 dictated by the URI Template author. Given the percent-encoding 163 rules for variable values this means that the source of all 164 structure, i.e reserved characters, in a URI generated from a URI 165 Template is decided by the URI Template author. 167 1.3. Applicability 169 While URI Templates use a notation that is similar to some URI path 170 matching notations in web frameworks, URI Templates were not designed 171 for that use case, nor are they appropriate for that purpose. URI 172 Templates are not URIs, they do not identify an abstract or physical 173 resource, they are not to be treated like URIs, nor should not be 174 used in places where a URI would be expected. 176 1.4. Notational Conventions 178 This specification uses the Augmented Backus-Naur Form (ABNF) 179 notation of [RFC5234], including the following core ABNF syntax rules 180 defined by that specification: ALPHA (letters) and DIGIT (decimal 181 digits). See [RFC3986] for the definitions of the URI-reference, 182 percent-encoded, reserved, and unreserved rules. 184 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 185 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 186 document are to be interpreted as described in [RFC2119]. 188 2. Characters 190 A URI Template is a sequence of characters, and has the same issues 191 as URIs with regard to codepoints and character sets. That is, URI 192 Template characters are frequently encoded as octets for transport or 193 presentation. This specification does not mandate any particular 194 character encoding for mapping between URI characters and the octets 195 used to store or transmit those characters. When a URI appears in a 196 protocol element, the character encoding is defined by that protocol; 197 without such a definition, a URI is assumed to be in the same 198 character encoding as the surrounding text. 200 The ABNF notation defines its terminal values to be non-negative 201 integers (codepoints) based on the US-ASCII coded character set 202 [ASCII]. Because a URI is a sequence of characters, we must invert 203 that relation in order to understand the URI syntax. Therefore, the 204 integer values used by the ABNF must be mapped back to their 205 corresponding characters via US-ASCII in order to complete the syntax 206 rules. 208 3. Terminology 210 o template processor - A program or library that converts a URI 211 Template into a URI. 212 o template expansion - The text between '{' and '}', including the 213 enclosing brackets. 215 4. URI Template 217 A URI Template is a sequence of characters that contains any number 218 of embedded template expansions, see Section 4.2. Each expansion 219 references one or more variables whose values are used when 220 determining the substition value for an expansion. A URI Template 221 becomes a URI when all the template expansions are substituted with 222 their values (see Section 4.4). The generated URI will be a URI- 223 reference, i.e. either an absolute URI or a relative reference. 225 4.1. Variables 227 Every variable is either a Unicode string or a list of Unicode 228 strings. 230 A template expansion MAY reference variables that are unknown to the 231 template processor. Those variables are 'undefined' and template 232 expansion takes into consideration 'undefined' variables. 233 Conversely, every variable that he template processor knows about is 234 considered 'defined'. 236 A variable that contains a string of length zero MUST NOT be 237 considered 'undefined' by the template processor. A list variable 238 that contains no members, that is of zero length, MUST NOT be 239 considered 'undefined' by the template processor. 241 Beyond the scope of this specification is the allowable programming 242 constructs that can be used for a list variable. For example, a 243 Python implementation might allow only built-in list types, or it may 244 allow any iterable to be used as the source for a list variable. 246 Some variables may be supplied with default values. The default 247 value must comde from ( unreserved / pct-encoded ). Note that there 248 is no notation for supplying default values to list variables. 250 A variable may appear in more than one expansion in a URI Template. 251 The value used for that variable MUST remain the same for every 252 template expansion when converting a URI Template into a URI. 254 4.2. Template Expansions 256 Template expansions are the parameterized components of a URI 257 Template. A template expansion MUST match the 'expansion' rule. 259 op = 1*ALPHA 260 arg = *(reserved / unreserved / pct-encoded) 261 var = varname [ "=" vardefault ] 262 vars = var [ *("," var) ] 263 varname = (ALPHA / DIGIT)*(ALPHA / DIGIT / "." / "_" / "-" ) 264 vardefault = *(unreserved / pct-encoded) 265 operator = "-" op "|" arg "|" vars 266 expansion = "{" ( var / operator ) "}" 268 4.3. Error Handling 270 During template substitution error conditions may arise. The exact 271 circumstances for those errors are described in Section 4.4. When an 272 error occurs the template processor MUST NOT return a URI. It is 273 language specific and beyond the scope of this document how the 274 template processor signals that an error has occured and that a URI 275 will not be generated from the template. 277 4.4. URI Template Substitution 279 Template substitution is the process of turning a URI Template into a 280 URI given definitions for the variables used in the template. 281 Substitution replaces each expansion with its calculated value. A 282 template processor take two inputs, a URI Template and a set of 283 variables, and returns a URI-reference. 285 Before substitution the template processor MUST convert every 286 variable value into a sequence of characters in ( unreserved / pct- 287 encoded ). The template processor does that using the following 288 algorithm: The template processor normalizes the string using NFKC, 289 converts it to UTF-8 [RFC3629], and then every octet of the UTF-8 290 string that falls outside of ( unreserved ) MUST be percent-encoded, 291 as per [RFC3986], section 2.1. For variables that are lists, the 292 above algorithm is applied to each value in the list. 294 The Unicode Standard [UNIV4] defines various equivalences between 295 sequences of characters for various purposes. Unicode Standard Annex 296 #15 [UTR15] defines various Normalization Forms for these 297 equivalences, in particular Normalization Form KC (NFKC, 298 Compatibility Decomposition, followed by Canonical Composition). 299 Since different Normalized Forms unicode strings will have different 300 UTF-8 represenations the only way to guarantee that template 301 processors will produce the same URI is to require a common 302 Normalized Form. 304 Requiring that all characters outside of ( unreserved ) be percent 305 encoded means that the only characters outside of ( unreserved ) that 306 will appear in the generated URI-reference will come from outside the 307 template expansions in the URI Template or from the argument of a 308 template expansion. This means that the designer of the URI Template 309 determines the placement of reserved characters in the resulting URI, 310 and thus the structure of the resulting generated URI-reference. 312 If the expansion is an operator then the substitution value is 313 determined by the given operator. Each operator works only on the 314 variables that are defined within their expansion. 316 The result of substitution MUST match the URI-reference rule and 317 SHOULD also match any known rules for the scheme of the resulting 318 URI. 320 If a template processor encounters an operator that it does not 321 understand then it MUST fail and MUST NOT produce a URI from the URI 322 Template. The list of operators that a template processor knows is 323 not constrained by this specification, that is, later specifications 324 may add new operators. 326 Every expansion consists of either a variable ('var') or an operator 327 expression ('operator'), and the rules for how to expand each of 328 these is given below. For every expansion a template MUST have at 329 least one variable name in the template expansion. It is an error if 330 no variables are supplied. All of the variables supplied to a 331 template expansion MAY be undefined and the expansion rules below 332 specify how to process the template expansion in that situation. 334 4.4.1. ('var') substitution 336 In a variable ('var') expansion, if the variable is defined then 337 substitute the value of the variable, otherwise substitute the 338 default value. If no default value is given then substitute with the 339 empty string. 341 Example: 343 foo := "fred" 345 "{foo}" -> "fred" 346 "{bar=wilma}" -> "wilma" 347 "{baz}" -> "" 349 4.4.2. The 'opt' operator 351 If each variable is undefined or an empty list then substitute the 352 empty string, otherwise substitute the value of 'arg'. 354 Example: 356 foo := "fred" 358 "{-opt|fred@example.org|foo}" -> "fred@example.org" 359 "{-opt|fred@example.org|bar}" -> "" 361 4.4.3. The 'neg' operator 363 If each variable is undefined or an empty list then substitute the 364 value of arg, otherwise substitute the empty string. 366 Example: 368 foo := "fred" 370 "{-neg|fred@example.org|foo}" -> "" 371 "{-neg|fred@example.org|bar}" -> "fred@example.org" 373 4.4.4. The 'prefix' operator 375 The prefix operator MUST only have one variable in its expansion. 376 More than one variable is an error condition. If the variable is 377 undefined or an empty list then substitute the empty string. If the 378 variable is a defined non-list then substitute the value of arg 379 preceeded by the value of the variable. If the variable is a defined 380 list then substitute the concatenation of every list value preceeded 381 by the arg. 383 Example: 385 foo := "fred" 386 bar := ["fee", "fi", "fo", "fum"] 387 baz := [] 389 "{-prefix|/|foo}" -> "/fred" 390 "{-prefix|/|bar}" -> "/fee/fi/fo/fum" 391 "{-prefix|/|baz}" -> "" 392 "{-prefix|/|qux}" -> "" 394 4.4.5. The 'suffix' operator 396 The prefix operator MUST only have one variable in its expansion. 397 More than one variable is an error condition. If the variable is 398 undefined or an empty list then substitute the empty string. If the 399 variable is a defined non-list then substitute the value of arg 400 followed by the value of the variable. If the variable is a defined 401 list then substitute the concatenation of every list value followed 402 by the arg. 404 Example: 406 foo := "fred" 407 bar := ["fee", "fi", "fo", "fum"] 408 baz := [] 410 "{-suffix|/|foo}" -> "fred/" 411 "{-suffix|/|bar}" -> "fee/fi/fo/fum/" 412 "{-suffix|/|baz}" -> "" 413 "{-suffix|/|qux}" -> "" 415 4.4.6. The 'join' operator 417 Supplying a list variable to the join operator is an error. For each 418 variable that is defined and non-empty create a keyvalue string that 419 is the concatenation of the variable name, "=", and the variable 420 value. Concatenate more than one keyvalue string with intervening 421 values of arg to create the substitution value. The order of 422 variables MUST be preserved during substitution. 424 Example: 426 foo := "fred" 427 bar := "barney" 428 baz := "" 430 "{-join|&|foo,bar,baz,qux}" -> "foo=fred&bar=barney&baz=" 431 "{-join|&|bar}" -> "bar=barney" 432 "{-join|&|qux}" -> "" 434 4.4.7. The 'list' operator 436 The listjoin operator MUST have only one variable in its expansion 437 and that variable must be a list. More than one variable is an 438 error. If the list is non-empty then substitute the concatenation of 439 all the list members with intervening values of arg. If the list is 440 empty or the variable is undefined them substitute the empty string. 442 Example: 444 foo := ["fred", "barney", "wilma"] 445 bar := ["a", "", "c"] 446 baz := ["betty"] 447 qux := [] 449 "{-list|/|foo}" -> "fred/barney/wilma" 450 "{-list|/|bar}" -> "a//c" 451 "{-list|/|baz}" -> "betty" 452 "{-list|/|qux}" -> "" 453 "{-list|/|corge}" -> "" 455 4.5. Examples 457 Given the following template variable names and values: 459 +---------+----------------------------------+ 460 | Name | Value | 461 +---------+----------------------------------+ 462 | foo | \u03d3 | 463 | bar | fred | 464 | baz | 10,20,30 | 465 | qux | ["10","20","30"] | 466 | corge | [] | 467 | grault | | 468 | garply | a/b/c | 469 | waldo | ben & jerrys | 470 | fred | ["fred", "", "wilma"] | 471 | plugh | ["\u017F\u0307", "\u0073\u0307"] | 472 | 1-a_b.c | 200 | 473 +---------+----------------------------------+ 475 Table 1 477 The variable 'foo' is the unicode character GREEK UPSILON WITH ACUTE 478 AND HOOK SYMBOL. This character was chosen because it is one of only 479 three characters that has a different normal form for each of the 480 four normalization forms (NFC, NFD, NFKC, NFKD). The name 'xyzzy' 481 has not been defined, the value of 'grault' is the empty string. The 482 variables qux, corge, fred, and plugh are lists. 484 The following URI Templates will be expanded as shown: 486 ---- 487 http://example.org/?q={bar} 488 http://example.org/?q=fred 490 /{xyzzy} 491 / 493 http://example.org/?{-join|&|foo,bar,xyzzy,baz} 494 http://example.org/?foo=%CE%8E&bar=fred&baz=10%2C20%2C30 496 http://example.org/?d={-list|,|qux} 497 http://example.org/?d=10,20,30 499 http://example.org/?d={-list|&d=|qux} 500 http://example.org/?d=10&d=20&d=30 502 http://example.org/{bar}{bar}/{garply} 503 http://example.org/fredfred/a%2Fb%2Fc 505 http://example.org/{bar}{-prefix|/|fred} 506 http://example.org/fred/fred//wilma 508 {-neg|:|corge}{-suffix|:|plugh} 509 :%E1%B9%A1:%E1%B9%A1: 511 ../{waldo}/ 512 ../ben%20%26%20jerrys/ 514 telnet:192.0.2.16{-opt|:80|grault} 515 telnet:192.0.2.16:80 517 :{1-a_b.c}: 518 :200: 520 ---- 522 5. Security Considerations 524 A URI Template does not contain active or executable content. Other 525 security considerations are the same as those for URIs, see section 7 526 of RFC3986. 528 6. IANA Considerations 530 In common with RFC3986, URI scheme names form a registered namespace 531 that is managed by IANA according to the procedures defined in 532 [RFC4395]. No IANA actions are required by this document. 534 7. Appendix A - Parsing URI Template Expansions 536 Parsing a valid URI Template expansion does not require building a 537 parser from the given ABNF. Instead, the set of allowed characters 538 in each part of URI Template expansion has been chosen to avoid 539 complex parsing, and breaking an expansion into its component parts 540 can be achieved by a series of splits of the character string. 542 Here is example Python code that parses a URI Template expansion and 543 returns the operator, argument, and variables as a tuple. The 544 variables are returned as a dictionary of variable names mapped to 545 their default values. If no default is given then the name maps to 546 None. 548 def parse_expansion(expansion): 549 if "|" in expansion: 550 (op, arg, vars_) = expansion.split("|") 551 op = op[1:] 552 else: 553 (op, arg, vars_) = (None, None, expansion) 554 vars_ = vars_.split(",") 556 variables = {} 557 for var in vars_: 558 if "=" in var: 559 (varname, vardefault) = var.split("=") 560 else: 561 (varname, vardefault) = (var, None) 562 variables[varname] = vardefault 564 return (op, arg, variables) 566 And here is an example of the parse_expansion() function being used. 568 >>> parse_expansion("-join|&|a,b,c=1") 569 ('join', '&', {'a': None, 'c': '1', 'b': None}) 570 >>> parse_expansion("c=1") 571 (None, None, {'c': '1'}) 573 8. Normative References 575 [ASCII] American National Standards Institute, "Coded Character 576 Set - 7-bit American Standard Code for Information 577 Interchange", ANSI X3.4, 1986. 579 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 580 Requirement Levels", BCP 14, RFC 2119, March 1997. 582 [RFC2978] Freed, N. and J. Postel, "IANA Charset Registration 583 Procedures", BCP 19, RFC 2978, October 2000. 585 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 586 10646", STD 63, RFC 3629, November 2003. 588 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 589 Resource Identifier (URI): Generic Syntax", STD 66, 590 RFC 3986, January 2005. 592 [RFC4395] Hansen, T., Hardie, T., and L. Masinter, "Guidelines and 593 Registration Procedures for New URI Schemes", BCP 115, 594 RFC 4395, February 2006. 596 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 597 Specifications: ABNF", STD 68, RFC 5234, January 2008. 599 [UNIV4] The Unicode Consortium, "The Unicode Standard, Version 600 4.0.1, defined by: The Unicode Standard, Version 4.0 601 (Reading, MA, Addison-Wesley, 2003. ISBN 0-321-18578-1), 602 as amended by Unicode 4.0.1 603 (http://www.unicode.org/versions/Unicode4.0.1/)", 604 March 2004. 606 [UTR15] Davis, M. and M. Duerst, "Unicode Normalization Forms", 607 Unicode Standard Annex # 15, April 2003. 609 [1] 611 Appendix A. Contributors 613 The following people made significant contributions to this 614 specification: Michaeljohn Clement, DeWitt Clinton, John Cowan, James 615 H. Manger, and James Snell. 617 Appendix B. Revision History 619 03 - Added more examples. Introduced error conditions and defined 620 their handling. Changed listjoin to list. Changed -append to 621 -suffix, and allowed -prefix and -suffix to accept list variables. 622 Clarified the handling of unicode. 624 02 - Added operators and came up with coherent percent-encoding and 625 reserved character story. Added large examples section which is 626 extracted and tested against the implementation. 628 01 630 00 - Initial Revision. 632 Authors' Addresses 634 Joe Gregorio (editor) 635 Google 637 Email: joe@bitworking.org 638 URI: http://bitworking.org/ 640 Marc Hadley (editor) 641 Sun Microsystems 643 Email: Marc.Hadley@sun.com 644 URI: http://sun.com/ 646 Mark Nottingham (editor) 648 Email: mnot@pobox.com 649 URI: http://mnot.net/ 651 David Orchard 652 BEA Systems, Inc. 654 Email: dorchard@bea.com 655 URI: http://bea.com/ 657 Full Copyright Statement 659 Copyright (C) The IETF Trust (2008). 661 This document is subject to the rights, licenses and restrictions 662 contained in BCP 78, and except as set forth therein, the authors 663 retain all their rights. 665 This document and the information contained herein are provided on an 666 "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS 667 OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND 668 THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS 669 OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF 670 THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED 671 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 673 Intellectual Property 675 The IETF takes no position regarding the validity or scope of any 676 Intellectual Property Rights or other rights that might be claimed to 677 pertain to the implementation or use of the technology described in 678 this document or the extent to which any license under such rights 679 might or might not be available; nor does it represent that it has 680 made any independent effort to identify any such rights. Information 681 on the procedures with respect to rights in RFC documents can be 682 found in BCP 78 and BCP 79. 684 Copies of IPR disclosures made to the IETF Secretariat and any 685 assurances of licenses to be made available, or the result of an 686 attempt made to obtain a general license or permission for the use of 687 such proprietary rights by implementers or users of this 688 specification can be obtained from the IETF on-line IPR repository at 689 http://www.ietf.org/ipr. 691 The IETF invites any interested party to bring to its attention any 692 copyrights, patents or patent applications, or other proprietary 693 rights that may cover technology that may be required to implement 694 this standard. Please address the information to the IETF at 695 ietf-ipr@ietf.org.