idnits 2.17.1 draft-eastlake-cturi-06.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 : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors 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 (26 December 2021) is 849 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Obsolete informational reference (is this intentional?): RFC 1738 (Obsoleted by RFC 4248, RFC 4266) Summary: 0 errors (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 INTERNET-DRAFT D. Eastlake 2 Intended status: Proposed Standard Futurewei Technologies 3 Expires: 25 June 2022 26 December 2021 5 Mapping Between MIME Types, Content-Types, and URIs 6 8 Abstract 10 Multipurpose Internet Mail Extension (MIME) Content-Type headers, the 11 MIME types used therein, and Uniform Resource Identifiers (URIs) are 12 being used, in different contexts, to label entities. A mapping is 13 specified from each kind of label into the other. This makes it 14 possible to express the meaning of almost any URI or Content-Type in 15 the syntax of the other. 17 Status of This Document 19 This Internet-Draft is submitted in full conformance with the 20 provisions of BCP 78 and BCP 79. 22 Distribution of this document is unlimited. Comments should be sent 23 to the author. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF), its areas, and its working groups. Note that 27 other groups may also distribute working documents as Internet- 28 Drafts. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 The list of current Internet-Drafts can be accessed at 36 https://www.ietf.org/1id-abstracts.html. The list of Internet-Draft 37 Shadow Directories can be accessed at 38 https://www.ietf.org/shadow.html. 40 Table of Contents 42 1. Introduction............................................3 43 1.1 Introduction to URIs and MIME Type/Content-Type........3 44 1.2 Definitions and Conventions............................4 45 1.3 Additional Features....................................4 46 1.4 Overview of Remaining Sections.........................5 48 2. Mapping of Content-Type to URI..........................6 49 2.1 Simple Mapping of MIME Type to URI.....................6 50 2.2 Mapping of Content-Type to URI.........................7 51 2.3 Content-Type Mapping Special Case for Closure..........7 52 2.4 Controlled Mapping of a Content-Type to a URI..........8 54 3. Mapping of URI to Content-Type..........................9 55 3.1 Simple Mapping of URI to Content-Type..................9 56 3.2 URI Mapping Special Case for Basic Closure............10 57 3.3 Controlled Mapping of a URI to a Content-Type.........10 59 4. Troublesome Characters.................................12 61 5. IANA Considerations and Potential Conflicts............13 62 6. Security Considerations................................13 64 Appendix..................................................15 66 Normative References......................................19 67 Informative References....................................19 68 Author's Address..........................................20 70 1. Introduction 72 Both MIME types and URIs have come to be used for type labeling and 73 similar information. Both new MIME types and XML applications using 74 new URIs for type labeling are continuing to be created and there 75 does not appear to be any prospect that either syntax will become so 76 dominant that the other will wither. 78 In most protocols where there are provisions for a general "type 79 label", that label is restricted to the syntax of a URI or the syntax 80 of a Content-Type. In some cases, it will be useful to be able to 81 express labels which already exist in the "other" syntax. That is, it 82 may be useful in a URI syntax slot to be able to express a MIME type 83 or Content-Type and, conversely, it may be useful in a Content-Type 84 syntax slot to be able to express a URI. 86 Ability to express Content-Types as URIs makes is easy to talk about 87 them in [RDF] or other languages which refer to things with URIs. If 88 one is sending, via SMTP, HTTP, or any other protocol using Content- 89 Types, keying material or other things typed by the URI format type 90 labels specified in [RFC3275] or [XMLENC] it is convenient to be able 91 to express such URI type labels as a Content-Type header. In the 92 SMIL 2.0 case of the systemComponent attribute, there is a specific 93 URI format attribute intended to contain Content-Type information 94 [SMIL]. These are just a few specific examples that need a way to 95 convert between URI and Content-Type syntaxes. 97 This document specifies how to map any Content-Type into a URI and 98 vice versa. 100 1.1 Introduction to URIs and MIME Type/Content-Type 102 The IETF Multipurpose Internet Mail Extensions (MIME) message body 103 standards developed into a general tagging and bagging mechanism. 104 This mechanism spread from SMTP mail to HTTP, USENET, and other 105 protocols. In MIME, the type of an object is given in a "Content- 106 Type" header line. [RFC2045] [RFC2046] [RFC6838] Such a line consists 107 of a MIME type and, optionally, additional parameters. A MIME type 108 consists of a MIME top level type, a slash, and a MIME subtype. 110 The original Uniform Resource Locator (URL [RFC1738]), used to point 111 to World Wide Web (WWW) resources, grew into the more general Uniform 112 Resource Identifier (URI [RFC3986]). Increasingly URIs are used as 113 general labels for algorithms [RFC3275], XML namespaces [XML NAME], 114 web based protocol data types, etc. (In some of these label uses, 115 URIs are considered opaque while in other cases they are assumed to 116 be de-referencable into something which explicates their meaning.) 118 1.2 Definitions and Conventions 120 Concerning URIs, please note the following: 122 (1) In this document, the term URI is used to include URI 123 Reference. That is, it includes the case where an octothorp 124 ("#") followed by a fragment identifier is suffixed to a pure 125 URI. 127 (2) Only absolute URIs are mappable. Relative URIs, with just a 128 hierarchical part, are not included in URI as used in this 129 document. They must first be converted to absolute URIs as 130 described in [RFC3986]. 132 (3) For presentation purposes, URIs are shown inside angle 133 brackets ("<...>") but these angle brackets are not actually a 134 part of the URI. 136 Concerning Content-Types, please note the following: 138 Content-Type values are shown preceded by "Content-Type: " and, 139 when long, they are line folded as per [RFC5322]. This prefix 140 and line folding are for presentation purposes and are not 141 actually a part of the Content-Type. 143 Concerning "URL encoding/decoding", please note the following: 145 These are operations on character strings represented by octet 146 sequences. "URL encoding" is the process of replacing certain 147 octets with the three octets for the character percent sign ("%") 148 followed by two hex digits for the value of the octet replaced. 149 "URL decoding" is the inverse process, i.e. replacing all three 150 octet sequences that start with the octet for percent sign and 151 the remainder of which consist of two hex digits (0-9, A-F, or a- 152 f) with a single octet whose value is represented by the two hex 153 digit sequence. The characters that are replaced by URL encoding 154 for the purposes of this draft are listed in Section 4. 156 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 157 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 158 "OPTIONAL" in this document are to be interpreted as described in BCP 159 14 [RFC2119] [RFC8174] when, and only when, they appear in all 160 capitals, as shown here. 162 1.3 Additional Features 164 Note that a URI or Content-Type could get converted back and forth 165 multiple times between these two syntaxes. To stop such multiple 166 conversions from resulting in ever longer and more complex tags, a 167 check is mandated so that if a conversion is of a previously 168 converted syntax, the previous conversion is reversed, in so far as 169 practical. 171 To improve the repeatability of the results from single or multiple 172 steps of syntax conversion, capitalization and punctuation 173 recommendations are made where tokens are case insensitive or 174 variable punctuation is allowed. 176 Finally, in cases where the default conversion does not provide for 177 sufficient control, optional elements are defined for inclusion in 178 URIs and Content-Types that provide substantial control over the 179 mapping output. 181 1.4 Overview of Remaining Sections 183 Sections 2 and 3 below give an explanation of the mapping specified, 184 more or less in English. The material is organized to start with the 185 simplest and most common rules and then add exceptions for special 186 cases and additional user control. 188 Section 4 lists characters that must be URI ("%") encoded when 189 mapping from a URI to a Content-Type. 191 Section 5 covers IANA Considerations and potential conflicts. 193 Section 6 give Security Considerations. 195 The Appendix presents some sample code in Perl. 197 2. Mapping of Content-Type to URI 199 This section starts with how to map a simple MIME type to a URI, in 200 Section 2.1. In 2.2, this is expanded to mapping a full Content-Type 201 with parameters. Section 2.3 adds the special check for the mapping 202 of a Content-Type which appears to have originally come from a URI. 203 And Section 2.4 describes how to control the mapping to a URI by 204 means of a special Content-Type parameter. 206 2.1 Simple Mapping of MIME Type to URI 208 For the simplest case of a Content-Type consisting of just a MIME 209 type, create a URI with scheme "ContentType" and a scheme dependent 210 part consisting of the MIME type. For example 212 Content-Type: image/JPEG 214 simply converts to 216 218 White space is not allowed in URIs so it must be removed. Scheme 219 names (the part before the first ":" in a URI) are case insensitive 220 but for readability and repeatability, the capitalization 221 "ContentType" SHOULD be used. Similarly, MIME top level types and 222 subtypes (the fields before and after the "/" in a MIME type field, 223 respectively) are case insensitive but SHOULD be all lower cased when 224 mapped to the URI form. For example 226 Content-type: x-FOO?bar/biZZare#sUb#tYpe 228 converts to 230 232 Note: There is no "//" after the "ContentType:" scheme as used 233 herein. Such a "//" would imply a specific structuring of the 234 scheme dependent part appearing in the URI after the 235 "ContentType:" as defined in [RFC3986]. Since that full 236 structuring is not used, "//" is not used. The meaning of URIs 237 starting with "ContentType://" is reserved for future definition. 239 Note: "Content-Type", with hyphen, is syntactically allowed as a 240 scheme name. However, [RFC7595] reserves embedded hyphens in 241 scheme names to indicate the prefix of an alternate tree of 242 scheme names. Therefore, the un-hyphenated ContentType is used. 244 2.2 Mapping of Content-Type to URI 246 A Content-Type header frequently includes more than just the 247 mandatory MIME type. It can also have type dependent parameters, 248 including private parameters, such as 250 Content-Type: text/plain; charset="us-ascii"; 251 x-mac-type="54455854"; x-mac-creator="4D4F5353" 253 Content-Type: image/tiff; application=faxbw 255 Content-Type parameters are mapped into a "query portion" suffix of 256 the URI in much the same way that HTML form fields [HTML] are. That 257 is, they are concatenated to the MIME type after a "?" and, if there 258 is more than one parameter, separated by "&". Thus the above Content- 259 Types would be mapped into the following URIs: 261 264 266 Parameter values in the mapped URI MUST always be enclosed in double 267 quotes ('"'). If the Content-Type has a trailing ";" but no 268 parameters, then "?" SHOULD NOT be added to the URI. 270 Note: Any occurrences of the "&" separator will have to be encoded as 271 "&" or other appropriate character reference if the URI is 272 used in XML outside a CDATA construct, or most other SGML derived 273 languages. However, "&" is the standard separator used in CGI 274 (Common Gateway Interface) parsing of query section parameters 275 for "mailto:" [RFC6068], "http:", etc., schemes. On balance, the 276 continued use of "&" has been chosen. 278 2.3 Content-Type Mapping Special Case for Closure 280 A URI may have been converted to a Content-Type and get converted 281 back. To stop this from resulting in an ever more complex syntax, a 282 check MUST be made to see if the MIME subtype of a Content-Type being 283 converted is in the "uri." subtype tree (see section 3.2 below). If 284 so, the URI is computed from the subtype by stripping the "uri." 285 prefix and undoing one level of URI encoding. The top level MIME 286 type is ignored in this case. In addition, Content-Type parameters, 287 if any, are added as a "query portion" and any "URI-fragment" 288 parameter is added as a fragment. 290 For example: 292 Content-Type: application/uri.mailto%3Auser%40host.example 294 Content-Type: application/uri.http%3A%2F%2Fx.test; foo="123"; 295 bar="abcd" 297 Content-Type: 298 application/uri.http%3A%2F%2Fa%3Ab%40c.text%2Fx%2Fy; 299 URI-fragment="z%25z" 301 are mapped to 303 305 307 309 Note: If a Content-Type or MIME Type is being written by a user and 310 they know that there is a URI which is a more natural expression 311 of the labeling desired, they can simply use an ".../uri." MIME 312 Type to start with. 314 2.4 Controlled Mapping of a Content-Type to a URI 316 There will be cases where greater control over the mapping is 317 desired. These are cases where a more natural URI exists rather than 318 the automatic "ContentType" URI scheme. 320 To accomplish this controlled mapping starting with a Content-Type, a 321 special Content-Type parameter "URI-body" is defined. If a Content- 322 Type does not have a MIME subtype in the "uri." tree and this 323 parameter is present, it is URL decoded to produce the non-query 324 portion of the URI mapped to and the original MIME top level and sub 325 types is preserved in a URI query parameter called "MIME-type". 327 For example 329 Content-Type: application/xml; URI-body="http://xml.example/foo" 331 would map to 333 335 3. Mapping of URI to Content-Type 337 Section 3.1 below describes the basic mapping of a URI into a 338 Content-Type. Section 3.2 specifies the exceptional processing when a 339 URI being converted to a Content-Type appears to have previously been 340 converted from a Content-Type. And Section 3.3 provides for greater 341 control over the mapping when needed. 343 3.1 Simple Mapping of URI to Content-Type 345 In the basic case, a URI maps to a Content-Type with a top level MIME 346 type of "application" and a MIME sub-type in the "uri." tree. The 347 "uri." is followed by the URL encoding of the URI excluding the query 348 and fragment parts. Any "query" parameters in the URI are mapped to 349 Content-Type parameters and, if the URI ends with a fragment 350 identifier, it is mapped to the special Content-Type parameter "URI- 351 fragment". 353 Note: Current URI syntax permits scheme dependent parts in which "?" 354 does not indicate a query section; however, no such syntaxes have 355 been publicly defined. 357 Some examples of the basic case follow: 359 361 363 365 convert to 367 Content-Type: application/uri.http%3A%2F%2Fexample.com%2Ftag42 369 Content-Type: application/uri.mailto%3AU%40example.net; 370 subject="misc"; body="line1%250D%250Aline2" 372 Content-Type: application/uri.xyz%3A%2F%2Fabc.test%2Fdef; 373 h="ijk"; URI-fragment="lmn" 375 Content-Type parameters values extracted from the query portion of a 376 URI MUST be surrounded with double quotes ('"'). When URI encoding, 377 if the hex value contains any letters (a-f), they SHOULD be upper 378 cased. 380 3.2 URI Mapping Special Case for Basic Closure 382 It is desirable that an arbitrary Content-Type be recovered 383 semantically intact when mapped to a URI and then that URI is mapped 384 back to a Content-Type. To approximate this as closely as practical, 385 the following special case is added to the simple case described in 386 section 3.1 above. 388 If the URI scheme is "ContentType:", then the Content-Type is 389 computed from the remaining part of the URI (the scheme specific 390 part), by replacing the first question mark ("?") and all subsequent 391 ampersands ("&") with the two character sequence semi-colon space ("; 392 "), and then undoing one level of URI encoding, i.e., replacing 393 percent sign ("%") followed by two hex digits with the octet having 394 that hex value. 396 For example 398 400 402 are mapped to 404 Content-Type: model/vnd.example.longish.sub#type.name 406 Content-Type: text/plain; charset="US-ASCII"; x-obscure="value" 408 Note: A URI produced by simple mapping from a normal Content-Type 409 will never have a fragment suffix. If one appears, it should be 410 mapped into a URI-fragment parameter, as specified in Section 3.1 411 above. 413 Note: If a type label URI is being written by a user and they know 414 that there is a Content-Type which is a more natural expression 415 of the labeling desired, they can simply use a "ContentType:" 416 scheme to start with. 418 3.3 Controlled Mapping of a URI to a Content-Type 420 There will be cases where greater control over the mapping is 421 desired. These are cases where a more natural Content-Type exists 422 than the "uri." subtree MIME subtype under the "application" type. 424 To accomplish this controlled mapping starting with a URI, a special 425 query part parameter "MIME-type" is defined. If a URI is not of 426 scheme ContentType and this special parameter is found, then the MIME 427 type is set to the parameter value after URL decoding and the URI 428 body (all of the URI except "query" parameters and any fragment 429 identifier) is preserved in a URL encoded "URI-body" Content-Type 430 parameter. 432 For example 434 436 would map to 438 Content-Type: message/rfc822; 439 URI-body="mailto:joe@blow.text"; URI-fragment="123" 441 4. Troublesome Characters 443 Troublesome characters are defined as those not permitted in a token 444 in [RFC2045] with the addition of percent sign and octothorp. That 445 is, any character code from 0 through 32 inclusive and character code 446 127 and any of "(", ")", "<", ">", "@", ",", ";", ":", "\", "/", "[", 447 "]", "?", "%", "#", and "=" are troublesome characters. 449 5. IANA Considerations and Potential Conflicts 451 IANA is requested to assign the following: 453 (1) The "ContentType" URI scheme. 455 (2) The "uri." MIME subtype tree. Since this subtree is totally 456 delegated to the URI specification, there are no independent 457 publication or review requirements for it. Any valid URI can be 458 used after the "uri." in any MIME top level type, after 459 troublesome characters (see section 4) in the URI are URL 460 encoded. 462 (3) In the context of URI to Content-Type mapping, a meaning is 463 specified for the "MIME-type" URI query section parameter. 465 (4) In the context of Content-Type to URI mapping, a meaning is 466 specified for the "URI-body" and "URI-fragment" Content-Type 467 parameters. 469 Because this document specifies the "ContentType" URI scheme and the 470 "uri." MIME subtype tree, no conflict can arise due to other uses of 471 them. 473 This is the first specification of a Content-Type parameters valid 474 across all MIME types, namely URI-body and URI-fragment. This is the 475 first specification of a universal URI query parameter, namely MIME- 476 type. The probability that any different use is currently being 477 made, or will in the foreseeable future have to be made, of these 478 names is low enough that it can be ignored. 480 It is possible that some processing systems are sensitive to the 481 presence of parameters they do not understand and will indicate 482 errors when presented with controlled mapping URIs or Content-Types. 483 However, Content-Type parameters and URI query parameters are usually 484 handled on receipt by such mechanisms as storing the name-value pair 485 in an associative array or as "environment variables" and ignoring 486 extra parameters. In fact, Content-Type processors are required by 487 [RFC2046] to ignore any parameters they do not understand and to 488 ignore parameter order. 490 6. Security Considerations 492 In some sense, the security considerations for MIME and content types 493 [RFC2046], URIs [RFC3986], and for every individual MIME type and URI 494 scheme can apply. 496 In addition, the deployment of mapping aware software may enable the 497 introduction into or transmission through MIME or Content-Type 498 contexts of URI semantics, including possibly dangerous action 499 schemes such as "mailto", and the introduction into or transmission 500 through URI contexts of MIME and content type semantics, including 501 possibly dangerous executable data types or the like. 503 Finally, implementation of controlled mapping may enable a malicious 504 user, by adding one of the special parameters specified herein, to 505 cause a surprising change in the semantics of a URI or Content-Type 506 produced by the mapping from an apparently innocuous Content-Type or 507 URI. Particular care should be given to screening the characters 508 resulting from URL decoding into character code sensitive fields. 510 Appendix 512 The following Perl code implements much of the mapping given in 513 Sections 2 and 3 above: 515 516 # Content-Type and URI intermapping example code 517 # Donald E. Eastlake 3rd, November 2001 519 # ----------- 520 # test driver 521 # ----------- 522 use strict; 523 print "Type a Content-Type, a URI, or 'Quit'. Do NOT include\n"; 524 print 525 "angle brackets around the URI or a 'Content-Type:' prefix.\n\n"; 526 while ( ) # get test input 527 { 528 my $test; 529 chomp ( $_ ); 530 if ( /^\s*([-\w\.+]+:[^\s]*)/ ) #test for URI 531 { 532 print "<$1>\n"; # echo 533 $test = uri2ct ( $1 ); 534 print " Content-Type: ", $test, "\n"; 535 $test = ct2uri ( $test ); 536 print "<$test>\n"; # converted back 537 } 538 elsif #test for Content-Type 539 ( m=^\s*([-_\w\.+#\$%!\?]+/[-_\w\.+#\$%!\?]+.*)= ) 540 # (note: RFC 2405 allows other characters in type and subtype) 541 { 542 print "Content-Type: $1\n"; # echo 543 $test = ct2uri ( $1 ); 544 print " <", $test, ">\n"; 545 $test = uri2ct ( $test ); 546 print "Content-Type: $test\n"; # converted back 547 } 548 elsif ( /^\s*$/ ) 549 elsif ( /exit|quit|halt|stop|end/i ) 550 { last; } 551 else { print "BAD INPUT: $_\n"; } 552 print "\n"; 553 } 554 print "EXIT\n"; 555 sleep 1; 556 exit; 558 # --------------------------- 559 # convert URI to Content-Type 560 # --------------------------- 561 sub uri2ct ($) { 562 my $result; my $item; 563 my %paramh; my @paraml; 564 @_[0] =~ m=\s*([^:/?#]+)?:([^?#]*)(\?([^#]*))?(#([^\s]*))?=; 565 # 1 2 3 4 5 6 566 my $scheme = lc ( $1 ); 567 my $main = $2; 568 @paraml = split ( /&/, $4 ); 569 foreach $item (@paraml) 570 { 571 $item =~ /([^=]+)=(.*)/; 572 $paramh{ lc ( $1 ) } = $2; 573 } 574 if ( $scheme eq "contenttype" ) 575 { $result = yestrouble ( $main ); } 576 elsif ( $result = $paramh{"mime-type"} ) 577 { 578 delete ( $paramh{"mime-type"} ); 579 $result =~ s/^"(.*)"$/$1/; 580 $result = yestrouble ( $result ) . '; URI-body="' . 581 notrouble ( $scheme . ":" . $main ) . '"'; 582 } 583 else 584 { 585 $result = "application/uri." . 586 notrouble ( $scheme . ":" . $main ); 587 } 588 if ( %paramh ) 589 { 590 my $key; my $value; 591 while (( $key, $value ) = each ( %paramh )) 592 { $result .= "; $key=" . dquote ( $value ); } 593 } 594 if ( $5 ) 595 { $result .= '; URI-fragment="' . notrouble ( $6 ) . '"'; } 596 return $result; 597 } # end uri2ct 599 # --------------------------- 600 # convert Content-Type to URI 601 # --------------------------- 602 sub ct2uri ($) { 603 my %paramh; my @paraml; 604 my $result; my $item; my $fragment; 605 @_[0] =~ 606 m&^\s*([-_\w\.+#\$%!\?]+)/([-_\w\.+#\$%!\?]+)\s*(;\s*(.*))?&; 607 # 1 2 3 4 608 my $type = lc ( notrouble ( $1 ) . "/" . notrouble ( $2 ) ); 609 my $minor = lc ( $2 ); 610 @paraml = split ( /\s*;\s*/, $4 ); 611 foreach $item ( @paraml ) 612 { 613 $item =~ /([^=\s]+)\s*=\s*(.*)/; 614 $paramh{ lc ( $1 ) } = $2; 615 } 616 if ( $minor =~ /^uri\.(.*)/i ) 617 { $result = yestrouble ( $1 ); } 618 elsif ( $result = $paramh{"uri-body"} ) 619 { 620 delete ( $paramh{"uri-body"} ); 621 $result = yestrouble ( $result ); 622 $result =~ s/^"(.*)"$/$1/ ; 623 $paramh{"MIME-type"} = $type; 624 } 625 else 626 { 627 $result = "ContentType:" . $type; 628 } 629 if ( $fragment = $paramh{"uri-fragment"} ) 630 { 631 delete ( $paramh{"uri-fragment"} ); 632 $fragment =~ s/^"(.*)"$/$1/; 633 } 634 if ( %paramh ) 635 { 636 my $key; my $value; 637 $result .= "?"; 638 while (( $key, $value ) = each ( %paramh )) 639 { 640 $result .= $key . '=' . dquote ( $value ) . "&"; 641 } 642 chop ( $result ); # get rid of trailing & 643 } 644 if ( $fragment ) 645 { $result .= '#' . yestrouble ( $fragment ) } 646 return $result; 647 } # end ct2uri 649 # ------------------- 650 # support subroutines 651 # ------------------- 653 # double quote string if not already double quoted 654 # ------------------------------------------------ 655 sub dquote ($) { 656 my $string = @_[0]; 657 if ( $string =~ /^".*"$/ ) 658 { return $string; } 659 return '"' . $string . '"'; 660 } 662 # URL encode troublesome characters 663 # --------------------------------- 664 sub notrouble ($) { 665 my $string = @_[0]; 666 my $result; 667 while ( $string =~ 668 m{([^%\?\(\)<>@,;:\\/\[\]="#]*)([%\?\(\)<>@,;:\\/\[\]="#])(.*)} 669 # 1 2 3 670 ) 671 { 672 $result .= "$1%" . sprintf ( "%02X", ord ( $2 ) ); 673 $string = $3; 674 } 675 return $result . $string; 676 } # end no trouble 678 # decode URL encoded string 679 # ------------------------- 680 sub yestrouble ($) { 681 my $string = @_[0]; 682 my $result; 683 while ( $string =~ /([^%]*)%([0-9a-fA-F]{2})(.*)/ ) 684 { 685 $result .= $1 . 686 chr ( unhexify ( substr ( $2, 0, 1 ) ) * 16 687 + unhexify ( substr ( $2, 1, 1 ) ) ); 688 $string = $3; 689 } 690 return $result . $string; 691 } # end yestrouble 693 # convert hex digit to corresponding integer 694 # ------------------------------------------ 695 sub unhexify ($) { 696 my $num = ord (@_[0]); 697 if ( $num >= ord ("0") && $num <= ord ("9") ) 698 { return ( $num - ord ("0" ) ); } 699 if ( $num >= ord ("A") && $num <= ord ("F") ) 700 { return ( $num - ord ("A" ) + 10 ); } 701 return ( $num - ord ("a" ) + 10 ); 702 } 703 705 Normative References 707 [RFC2046] - NFreed, N. and N. Borenstein, "Multipurpose Internet Mail 708 Extensions (MIME) Part Two: Media Types", RFC 2046, DOI 709 10.17487/RFC2046, November 1996, . 712 [RFC2119] - Bradner, S., "Key words for use in RFCs to Indicate 713 Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, 714 March 1997, . 716 [RFC3986] - Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 717 Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, 718 DOI 10.17487/RFC3986, January 2005, . 721 [RFC8174] - Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 722 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 723 2017, 725 Informative References 727 [HTML] - Dave Raggett, Arnaud Le Hors, Ian Jacobs, "HTML 4.01 728 Specification", , December 1999. 730 [RDF] - O. Lassila, R. Swick, "Resource Description Framework (RDF) 731 Model and Syntax Specification", , 22 February 1999. 734 [RFC1738] - Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform 735 Resource Locators (URL)", RFC 1738, DOI 10.17487/RFC1738, 736 December 1994, . 738 [RFC2045] - Freed, N. and N. Borenstein, "Multipurpose Internet Mail 739 Extensions (MIME) Part One: Format of Internet Message Bodies", 740 RFC 2045, DOI 10.17487/RFC2045, November 1996, 741 . 743 [RFC3275] - Eastlake 3rd, D., Reagle, J., and D. Solo, "(Extensible 744 Markup Language) XML-Signature Syntax and Processing", RFC 745 3275, DOI 10.17487/RFC3275, March 2002, . 748 [RFC5322] - Resnick, P., Ed., "Internet Message Format", RFC 5322, 749 DOI 10.17487/RFC5322, October 2008, . 752 [RFC6068] - Duerst, M., Masinter, L., and J. Zawinski, "The 'mailto' 753 URI Scheme", RFC 6068, DOI 10.17487/RFC6068, October 2010, 754 . 756 [RFC6838] - Freed, N., Klensin, J., and T. Hansen, "Media Type 757 Specifications and Registration Procedures", BCP 13, RFC 6838, 758 DOI 10.17487/RFC6838, January 2013, . 761 [RFC7595] - Thaler, D., Ed., Hansen, T., and T. Hardie, "Guidelines 762 and Registration Procedures for URI Schemes", BCP 35, RFC 7595, 763 DOI 10.17487/RFC7595, June 2015, . 766 [SMIL] - "Synchronized Multimedia Integration Language (SMIL 2.0)", 767 , 7 August 768 2001. 770 [XML NAME] - Tim Bray, Dave Hollander, Andrew Layman, "Namespaces in 771 XML", , 14 January 1999. 773 [XMLENC] - D. Eastlake, J. Reagle, "XML Encryption Syntax and 774 Processing", , 18 October 2001. 777 Author's Address 779 Donald E. Eastlake 3rd 780 Futurewei Technologies 781 2386 Panoramic Circle 782 Apopka, FL 32703 USA 784 Telephone: +1 508-333-2270 785 EMail: d3e3e3@gmail.com 787 Copyright and IPR Provisions 789 Copyright (c) 2021 IETF Trust and the persons identified as the 790 document authors. All rights reserved. 792 This document is subject to BCP 78 and the IETF Trust's Legal 793 Provisions Relating to IETF Documents 794 (http://trustee.ietf.org/license-info) in effect on the date of 795 publication of this document. Please review these documents 796 carefully, as they describe your rights and restrictions with respect 797 to this document. Code Components extracted from this document must 798 include Simplified BSD License text as described in Section 4.e of 799 the Trust Legal Provisions and are provided without warranty as 800 described in the Simplified BSD License. The definitive version of 801 an IETF Document is that published by, or under the auspices of, the 802 IETF. Versions of IETF Documents that are published by third parties, 803 including those that are translated into other languages, should not 804 be considered to be definitive versions of IETF Documents. The 805 definitive version of these Legal Provisions is that published by, or 806 under the auspices of, the IETF. Versions of these Legal Provisions 807 that are published by third parties, including those that are 808 translated into other languages, should not be considered to be 809 definitive versions of these Legal Provisions. For the avoidance of 810 doubt, each Contributor to the IETF Standards Process licenses each 811 Contribution that he or she makes as part of the IETF Standards 812 Process to the IETF Trust pursuant to the provisions of RFC 5378. No 813 language to the contrary, or terms, conditions or rights that differ 814 from or are inconsistent with the rights and licenses granted under 815 RFC 5378, shall have any effect and shall be null and void, whether 816 published or posted by such Contributor, or included with or in such 817 Contribution.