Next: rfc.uuid
- UUID, Previous: rfc.tls
- トランスポート・レイヤ・セキュリティ, Up: ライブラリモジュール - ユーティリティ [Contents][Index]
rfc.uri
- URIの解析と作成RFC 2396 (https://www.ietf.org/rfc/rfc2396.txt)で定義されている Uniform Resource Identifiers、 またRFC 2397で定義されているData URI Schemeをパーズおよび構築する 手続き群を提供します。
First, lets review the structure of URI briefly. The following graph shows how the URI is constructed:
URI-+-scheme | +-specific--+--authority-+--userinfo | +--host | +--port +--path +--query +--fragment
Not all URIs have this full hierarchy. For example,
mailto:admin@example.com
has only scheme (mailto
)
and specific (admin@example.com
) parts.
Most popular URI schemes, however, organize resources
in a tree, so they adopt authority (which usually identifies
the server) and the hierarchical path. In the URI
http://example.com:8080/search?q=key#results
, the authority
part is example.com:8080
, the path is /search
,
the query is key
and the fragment is results
.
The userinfo can be provided before hostname, such as anonymous
in ftp://anonymous@example.com/pub/
.
We have procedures that decompose a URI into those parts, and that compose a URI from those parts.
{rfc.uri} Extract specific part(s) from the given URI. You can fully decompose URI by the procedures described below, but in actual applications, you often need only some of the parts. This procedure comes handy for it.
The parts argument may be a symbol, or a list of symbols, to name the desired parts. The recognized symbos are as follows.
scheme
The scheme part, as string.
authority
The authority part, as string.
If URI doesn’t have the part, #f
.
userinfo
The userinfo part, as string. If URI doesn’t have the part, #f
.
host
The host part, as string. If URI doesn’t have the part, #f
.
port
The port part, as integer. If URI doesn’t have the part, #f
.
path
The path part, as string. If URI isn’t hierarchical, this returns the specific part.
query
The query part, as string. If URI doesn’t have the part, #f
.
fragment
The fragment part, as string. If URI doesn’t have the part, #f
.
scheme+authority
The scheme and authority part.
host+port
The host and port part.
userinfo+host+port
The userinfo, host and port part.
path+query
The path and query part.
path+query+fragment
The path, query and fragment part.
(define uri "http://foo:bar@example.com:8080/search?q=word#results") (uri-ref uri 'scheme) ⇒ "http" (uri-ref uri 'authority) ⇒ "//foo:bar@example.com:8080/" (uri-ref uri 'userinfo) ⇒ "foo:bar" (uri-ref uri 'host) ⇒ "example.com" (uri-ref uri 'port) ⇒ 8080 (uri-ref uri 'path) ⇒ "/search" (uri-ref uri 'query) ⇒ "q=word" (uri-ref uri 'fragment) ⇒ "results" (uri-ref uri 'scheme+authority) ⇒ "http://foo:bar@example.com:8080/" (uri-ref uri 'host+port) ⇒ "example.com:8080" (uri-ref uri 'userinfo+host+port) ⇒ "foo:bar@example.com:8080" (uri-ref uri 'path+query) ⇒ "/search?q=word" (uri-ref uri 'path+query+fragment)⇒ "/search?q=word#results"
You can extract multiple parts at once by specifying a list of parts. A list of parts is returned.
(uri-ref uri '(host+port path+query)) ⇒ ("example.com:8080" "/search?q=word")
{rfc.uri}
URIの一般的なパーザです。これらの関数はURIエンコーディングを
デコードしません。URIスキームによってどの部分をデコードすべきかが
異なるからです。パージングを行った後に、後述のuri-decode
等を
使ってデコードを行ってください。
uri-parse
は最も手軽な手続きで、uriを以下に示す部分に
分割し、多値で返します。
もし該当する部分がuriに無かった場合は、その部分には#f
が返ります。
"mailto:foo@example.com"
の"mailto"
)。
ftp://anonymous@ftp.example.com/pub/foo
の"anonymous"
)。
ftp://anonymous@ftp.example.com/pub/foo
の
"ftp.example.com"
)。
http://www.example.com:8080/
の8080
)。
http://www.example.com/index.html
の"/index.html"
)。
http://www.example.com/search?key=xyz&lang=en
の
"key=xyz&lang=en"
)。
http://www.example.com/document.html#section4
の
"section4"
)。
以下の手続きはより詳細に、段階をふんでuriを分割してゆくものです。
uri-scheme&specific
は URI uri を引数に取り、
スキーム部分と、そのスキーム特有の部分を表す2つの値を返します。
uri がスキーム部分を持たない場合、#f
を返します。
(uri-scheme&specific "mailto:sclaus@north.pole") ⇒ "mailto" and "sclaus@north.pole" (uri-scheme&specific "/icons/new.gif") ⇒ #f and "/icons/new.gif"
URI が階層的な記法を用いている場合、すなわち、
“//authority/path?query#fragment
”
のような場合、スキーム特有の部分を uri-decompose-hierarchical
に渡すと、authority、path、query、fragment
の4つの値が返ります。
(uri-decompose-hierarchical "//www.foo.com/about/company.html") ⇒ "www.foo.com", "/about/company.html", #f and #f (uri-decompose-hierarchical "//zzz.org/search?key=%3fhelp") ⇒ "zzz.org", "/search", "key=%3fhelp" and #f (uri-decompose-hierarchical "//jjj.jp/index.html#whatsnew") ⇒ "jjj.jp", "/index.html", #f and "whatsnew" (uri-decompose-hierarchical "my@address") ⇒ #f, #f, #f and #f
さらに、階層的 URI の authority の部分を
uri-decompose-authority
に渡すと、userinfo、
host、port が返ります。
(uri-decompose-authority "yyy.jp:8080") ⇒ #f, "yyy.jp" and "8080" (uri-decompose-authority "[::1]:8080") ;(IPv6 host address) ⇒ #f, "::1" and "8080" (uri-decompose-authority "mylogin@yyy.jp") ⇒ "mylogin", "yyy.jp" and #f
{rfc.uri}
Data URI文字列uriをパーズします。data:
スキームは有っても無くても
構いません。渡されたuriがdata uriとして無効な文字列であればエラーが投げられます。
二つの値、パーズされたContent-Typeおよびデコードされたデータを返します。
Content-Typeがtext/*
であればデコードされたデータは文字列で、
そうでなければu8vectorで返されます。
Content-Typeはmime-parse-content-type
でパーズされます
(rfc.mime
- MIMEメッセージ処理参照)。結果のデータ形式は次のようなリストです。
(type subtype (attribute . value) …)
.
いくつか例を示します。
(uri-decompose-data "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ==") ⇒ ("text" "plain" ("charset" . "utf-8")) and "(hello world)" (uri-decompose-data "data:application/octet-stream;base64,AAECAw==") ⇒ ("application" "octet-stream") and #u8(0 1 2 3)
{rfc.uri} 与えられたコンポーネントから URI を構成します。 妥当な URI を作成するためのコンポーネントの組み合わせはたくさんあります。 以下のダイアグラムは、考え得る組み合わせの方法を示しています。
/-----------------specific-------------------\ | | scheme-+------authority-----+-+-------path*---------+- | | | | \-userinfo-host-port-/ \-path-query-fragment-/
キーワード引数に #f
が与えられた場合、それはキーワード引数が
指定されないことと等価です。これは URI をパーズした結果を渡す場合に
特に有用です。
コンポーネントに適切でない文字が含まれている場合は、
url-compose
に渡す前に正しくエスケープされなければなりません。
いくつかの例を示します。
(uri-compose :scheme "http" :host "foo.com" :port 80 :path "/index.html" :fragment "top") ⇒ "http://foo.com:80/index.html#top" (uri-compose :scheme "http" :host "foo.net" :path* "/cgi-bin/query.cgi?keyword=foo") ⇒ "http://foo.net/cgi-bin/query.cgi?keyword=foo" (uri-compose :scheme "mailto" :specific "a@foo.org") ⇒ "mailto:a@foo.org" (receive (authority path query fragment) (uri-decompose-hierarchical "//foo.jp/index.html#whatsnew") (uri-compose :authority authority :path path :query query :fragment fragment)) ⇒ "//foo.jp/index.html#whatsnew"
{rfc.uri} 引数は、完全な、あるいは部分的なURIを表す文字列です。 この手続きは、RFC3986 Section 5.2. “Relative Resolution” に 示されるアルゴリズムに従い、relative-uriをbase-uriからの相対 として解決します。
relative-uri2 … が与えられた場合は、まずrelative-uri がbase-uriを基準に解決され、その結果を新たな基準として次の relative-uri2を解決し、以下同様に続けます。
(uri-merge "http://example.com/foo/index.html" "a/b/c") ⇒ "http://example.com/foo/a/b/c" (uri-merge "http://example.com/foo/search?q=abc" "../about#me") ⇒ "http://example.com/about#me" (uri-merge "http://example.com/foo" "http://example.net/bar") ⇒ "http://example.net/bar" (uri-merge "http://example.com/foo/" "q" "?xyz") ⇒ "http://example.com/foo/q?xyz"
{rfc.uri} 与えられたdataからData URIを構築して文字列で返します。
data引数は文字列かu8vectorでなければなりません。
content-typeキーワード引数は、#f
(デフォルト)、
content typeを表現する文字列 (例: "text/plain;charset=utf-8"
)、
もしくはパーズされたcontent type (例: ("application" "octet-stream")
)です。
#f
である場合は、dataが完全な文字列であれば
text/plain
にGaucheのネイティブ文字エンコーディングに基づくcharset
を
つけたもの、dataがそれ以外であればapplication/octet-stream
が
使われます。
encodingキーワード引数は#f
(デフォルト)、
もしくはシンボルuri
またはbase64
です。これは文字エンコーディングではなく
トランスファーエンコーディングであることに注意。
#f
の場合は、テキストデータならuri
が、バイナリデータならbase64
が
使われます。
(uri-compose-data "(hello world)") ⇒ "data:text/plain;charset=utf-8,%28hello%20world%29" (uri-compose-data "(hello world)" :encoding 'base64) ⇒ "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ==" (uri-compose-data '#u8(0 1 2 3)) ⇒ "data:application/octet-stream;base64,AAECAw=="
{rfc.uri}
URI エンコーディング、すなわち、%
でエスケープされた URI 文字列を
デコードします。uri-decode
は現在の入力ポートから入力を受け取り、
デコードした結果を現在の出力ポートに書き出します。
uri-decode-string
は string を入力とし、デコードした
文字列を返します。
cgi-decode が真の場合は、+
がスペース文字に置換されます。
uri-decode-string
には、外部の文字エンコーディングを指定する
encodingキーワード引数を与えることができます。この引数が与えれた
場合、デコードされたオクテットの列を指定された文字エンコーディングであると
してGaucheの内部文字エンコーディングへと変換したものが返されます。
{rfc.uri}
安全でない文字を、%
によるエスケープでエンコードします。
uri-encode
は現在の入力ポートから入力を受け取り、
結果を現在の出力ポートに書き出します。
uri-encode-string
は string を入力とし、エンコードした
文字列を返します。
デフォルトでは、RFC3986 で"非予約文字"として規定されていない文字は
エスケープされます。noescape 引数に異なる文字集合を渡すことで、
それらがエンコードされるのを抑止することができます。
例えば古いRFC2396では"非予約文字"がいくつか多かったのですが、
*rfc2396-unreserved-char-set*
(下記参照) を渡すことで
それらの文字がエスケープされるのを防ぐことができます。
マルチバイト文字は、デフォルトではGauche のネイティブなマルチバイト表現の
オクテット・ストリームとしてエンコードされます。ただし
uri-encode-string
にはencodingキーワード引数を渡すことができて、
その場合はまずstringが指定された文字エンコーディングへと変換されます。
{rfc.uri}
これらの定数はそれぞれ、RFC2396とRFC3986で定義されている
「非予約文字」の文字集合に束縛されています。
(文字集合の操作については、文字集合およびscheme.charset
- R7RS文字集合
を参照して下さい。)
Next: rfc.uuid
- UUID, Previous: rfc.tls
- トランスポート・レイヤ・セキュリティ, Up: ライブラリモジュール - ユーティリティ [Contents][Index]