结构
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