结构
GLibUri
自:2.66
描述 [src]
struct GUri {
/* No available fields */
}
GUri
类型及相关函数可用于将 URI 解析为组件,并从各个组件构建有效的 URI。
由于 GUri
仅表示绝对 URI,所有 GUri
都将具有 URI 方案,因此 g_uri_get_scheme()
始终会返回非 NULL
答案。同样,根据定义,所有 URI 都有路径组件,因此 g_uri_get_path()
始终会返回非 NULL
字符串(可能为空)。
如果 URI 字符串具有 “权限”组件(即,如果方案后跟的是 ://
而不是 :
),那么 GUri
将包含主机名,可能还有端口和“用户信息”。此外,根据 GUri
的构建/解析方式(例如,使用 G_URI_FLAGS_HAS_PASSWORD
和 G_URI_FLAGS_HAS_AUTH_PARAMS
标志),用户信息可能会被拆分到用户名、密码,以及其它授权相关参数。
通常,GUri
的组件将对所有 %
编码的字符进行解码。但是,如果你使用 G_URI_FLAGS_ENCODED
构建/解析 GUri
,则 %
编码将保留在用户信息、路径和查询字段中(并且在使用 G_URI_FLAGS_NON_DNS
创建主机字段时也保留)。特别是,在 URI 可能包含二进制数据或非 UTF-8 文本,或者对组件进行解码可能会更改对 URI 的解释时,这是必要的。
例如,使用编码标志
g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue", G_URI_FLAGS_ENCODED, &err);
g_assert_cmpstr (g_uri_get_query (uri), ==, "query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue");
当默认的 %
解码行为将得到
g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue", G_URI_FLAGS_NONE, &err);
g_assert_cmpstr (g_uri_get_query (uri), ==, "query=http://host/path?param=value");
在解码过程中,如果遇到无效的 UTF-8 字符串,解析将失败,并显示指示错误字符串位置的错误
g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fbad%3D%00alue", G_URI_FLAGS_NONE, &err);
g_assert_error (err, G_URI_ERROR, G_URI_ERROR_BAD_QUERY);
如果需要手动处理,则应该传递 G_URI_FLAGS_ENCODED
或 G_URI_FLAGS_ENCODED_QUERY
。特别是,如果查询字符串包含 =
字符,并且以 % 编码,则应该让 g_uri_parse_params()
对查询解码一次。
GUri
在构建后是不可变的,可以从多个线程安全地访问。它的引用计数是原子的。
请注意,GUri
的范围是帮助在各种应用程序中处理 URI,遵循 RFC 3986。特别是,它不打算涵盖 Web 浏览器的需求,也不实施 WHATWG URL 标准。没有提供任何 API 来帮助防止 同形异义词攻击,因此 GUri
不适合格式化 URI 以向用户显示,用于做出与安全性相关的决策。
相对 URI 和绝对 URI
如 RFC 3986 中定义的,URI 的层次结构表示它们既可以是“相对引用”(有时称为“相对 URI”),也可以是“URI”(为清楚起见,本文档中的“URI”被称为“绝对 URI”——虽然 与 RFC 3986 相比,但始终允许片断标识符)。
相对引用缺少一个或多个 URI 组件。特别是,它们没有方案。除了必须指定(但可能为空)的路径之外,其他任何组件(例如主机名、查询等)都可能缺失。该路径可能是相对的,从 ./
开始,而不是 /
。
例如,有效的相对引用是 ./path?query
、/?query#fragment
或 //example.com
。
绝对 URI 指定了一个方案。没有的 URI 的任何其他组件都指定为在 URI 中显示未设置,而不是使用 g_uri_parse_relative()
相对于基本 URI 解析。
例如,一个有效的绝对 URI 是 file:///home/bob
或 https://search.com?query=string
。
GUri
实例始终是绝对 URI。一个字符串可以是绝对 URI 或相对引用;请参见各个函数的文档,了解它们接受的形式。
解析 URI
用于解析 URI 的最简约的 API 是 g_uri_split()
和 g_uri_split_with_user()
。这些将 URI 拆分为其组成部分,并返回这些部分;这两者之间的区别在于 g_uri_split()
将 URI 的“用户信息”组件视为单个元素,而 g_uri_split_with_user()
可以(根据传递的 GUriFlags
)将其视为包含用户名、密码和认证参数。或者,当您只对用于向服务发起网络连接的组件(方案、主机和端口)感兴趣时,可以使用 g_uri_split_network()
。
g_uri_parse()
类似于 g_uri_split()
,但它不返回单个字符串,而是返回 GUri
结构(并且它需要 URI 是绝对 URI)。
g_uri_resolve_relative()
和 g_uri_parse_relative()
允许您解析相对于基本 URI 的相对 URI。 g_uri_resolve_relative()
接受两个字符串并返回一个字符串,并且 g_uri_parse_relative()
接受一个 GUri
和一个字符串返回一个 GUri
。
所有解析函数都使用一个 GUriFlags
参数准确描述如何解析 URI;请参阅该类型的文档来详细了解可以传递的特定标志。如果您需要根据 URI 类型选择不同标志,则可以在 URI 字符串上使用 g_uri_peek_scheme()
首先检查方案,并使用该信息来决定使用什么标志对其进行解析。
例如,在解析 Web URI 的参数时,您可能希望使用 G_URI_PARAMS_WWW_FORM
,因此,请将 g_uri_peek_scheme()
的结果与 http
和 https
比较。
构建 URI
g_uri_join()
和 g_uri_join_with_user()
可用于从一组组件字符串构建有效的 URI 字符串。它们是 g_uri_split()
和 g_uri_split_with_user()
的反函数。
类似地,g_uri_build()
和 g_uri_build_with_user()
可用于从一组组件字符串构建一个 GUri
。
与解析函数一样,构建函数使用一个 GUriFlags
参数。特别是,重要的是要记住您正在使用的 URI 组件是否已经过 %
编码。如果是,您必须传递 G_URI_FLAGS_ENCODED
标志。
file://
URI
请注意,Windows 和 Unix 都定义了解析 file://
URI 的特殊规则(在 Unix 上涉及非 UTF-8 字符集,在 Windows 上涉及路径分隔符的解释)。GUri
不会实现这些规则。如果您想要正确地在 file://
URI 和本地文件名之间进行转换,请使用 g_filename_from_uri()
和 g_filename_to_uri()
。
URI 相等性
请注意,没有 g_uri_equal ()
函数,因为对 URI 进行有用的比较需要 GUri
所不具备的特定于方案的知识。GUri
可以帮助进行规范化,如果您使用各种编码过的 GUriFlags
以及 G_URI_FLAGS_SCHEME_NORMALIZE
,但是它并不全面。例如,根据 data:
URI 规范,data:,foo
和 data:;base64,Zm9v
解析为同一内容,但 GLib 无法处理。
自 2.66 起可以获取:
函数
g_uri_build_with_user
根据 flags
从给定的组件创建新的 GUri
(无条件添加 G_URI_FLAGS_HAS_PASSWORD
)。flags
必须与传递的值一致,特别是使用 G_URI_FLAGS_ENCODED
对 %
编码的值。
自:2.66
g_uri_is_valid
按 flags
解析 uri_string
以确定它是否是一个有效的 绝对 URI,即它不需要被解析为另一个 URI 相对使用 g_uri_parse_relative()。
自:2.66
g_uri_list_extract_uris
将符合 RFC 2483 定义的文本/uri-list MIME 类型的 URI 列表拆分为单个 URI,并舍弃所有注释。URI 没有经过验证。
since: 2.6
g_uri_parse_params
许多 URI 方案将一个或多个属性/值对包含在 URI 值中。这种方法可用于将它们解析到哈希表中。当一个属性出现多次时,最后一个值是最终返回的值。如果你需要以不同的方式处理重复的属性,请使用 GUriParamsIter
。
自:2.66
g_uri_parse_scheme
获取 URI 字符串的方案部分。RFC 3986 会将方案解码为
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
常见方案包括 file
、https
、svn+ssh
等。
自 2.16 起:
g_uri_peek_scheme
获取 URI 字符串的方案部分。RFC 3986 会将方案解码为
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
常见方案包括 file
、https
、svn+ssh
等。
自:2.66
g_uri_resolve_relative
根据 flags
解析 uri_ref
,如果它是一个 相对 URI,则将其相对于 base_uri_string
进行解析。如果结果不是有效的绝对 URI,则它将被丢弃,并返回一个错误。
自:2.66
g_uri_split
根据 flags
解析 uri_ref
(可以是 绝对或相对 URI),并返回各个部分。uri_ref
中没有出现的任何组件都将返回 NULL
(但请注意,所有 URI 总是都有一个路径组件,尽管这个组件可能为空字符串)。
自:2.66
g_uri_split_network
根据 flags
解析 uri_string
(必须是 绝对 URI),并返回与连接到主机相关的各个部分。有关详细信息,请参阅 g_uri_split()
的文档;它主要是一个包装函数,具有更简单的参数。但是,如果 uri_string
是相对 URI,或者不包含主机名部分,它将返回一个错误。
自:2.66
g_uri_split_with_user
根据 flags
解析 uri_ref
(可以是 绝对或相对 URI),并返回各个部分。uri_ref
中没有出现的任何组件都将返回 NULL
(但请注意,所有 URI 总是都有一个路径组件,尽管这个组件可能为空字符串)。
自:2.66
实例方法
g_uri_get_auth_params
获取 uri
的认证参数,这些参数可能包含 %
编码,具体取决于创建 uri
时使用的标志。(如果 uri
不是使用 G_URI_FLAGS_HAS_AUTH_PARAMS
创建的,那么这将是 NULL
)。
自:2.66
g_uri_get_host
获取 uri
的主机。它永远不会包含 %
编码字符,除非它是非 UTF-8(仅当使用 G_URI_FLAGS_NON_DNS
创建 uri
时才会出现这种情况)。
自:2.66
g_uri_get_password
获取 uri
的密码,密码可能包含 %
编码,具体取决于创建 uri
时使用的标志。(如果 uri
不是使用 G_URI_FLAGS_HAS_PASSWORD
创建的,那么这将是 NULL
)。
自:2.66
g_uri_get_user
获得uri
userinfo 的“用户名”组件,该组件可能包含 %
编码,具体取决于创建 uri
时使用的标志。如果 uri
不是使用 G_URI_FLAGS_HAS_PASSWORD
或 G_URI_FLAGS_HAS_AUTH_PARAMS
创建的,则它与 g_uri_get_userinfo() 相同。
自:2.66
g_uri_parse_relative
根据 flags
解析 uri_ref
,如果它是 相对 URI,则相对于 base_uri
解析它。如果结果不是有效的绝对 URI,则会将其丢弃,并返回一个错误。
自:2.66
g_uri_to_string_partial
返回表示 uri
的字符串,受 flags
中选项的约束。有关更多详细信息,请参见 g_uri_to_string()
和 GUriHideFlags
。
自:2.66