Passa al contenuto principale

4. The HTTP Exchange (HTTP交换)

4.1. The HTTP Request (HTTP请求)

DoH客户端使用HTTP GET或POST方法以及本节的其他要求,将单个DNS查询编码为HTTP请求。DoH服务器通过使用URI模板来定义请求使用的URI。

本文档中定义的URI模板在HTTP方法为POST时不使用任何变量进行处理。当HTTP方法为GET时,单个变量"dns"被定义为DNS请求的内容 (如第6节所述),使用base64url [RFC4648] 编码。

DoH新媒体类型的未来规范必须 (MUST) 定义与本协议一起用于URI模板处理的变量。

DoH服务器必须 (MUST) 实现POST和GET两种方法。

使用POST方法时,DNS查询作为HTTP请求的消息主体包含在内,Content-Type请求头字段指示消息的媒体类型。POST请求通常比等效的GET请求更小。

使用GET方法对许多HTTP缓存实现更友好。

DoH客户端应该 (SHOULD) 包含HTTP Accept请求头字段,以指示响应中可以理解的内容类型。无论Accept请求头字段的值如何,客户端必须 (MUST) 准备好处理"application/dns-message" (如第6节所述) 响应,但也可以 (MAY) 处理它接收到的其他DNS相关媒体类型。

为了最大化HTTP缓存友好性,使用包含DNS消息头中的ID字段的媒体格式 (例如"application/dns-message") 的DoH客户端应该 (SHOULD) 在每个DNS请求中使用DNS ID为0。HTTP关联请求和响应,从而消除了在诸如"application/dns-message"之类的媒体类型中使用ID的需要。使用变化的DNS ID可能导致语义上等效的DNS查询被单独缓存。

DoH客户端可以像其他HTTP/2客户端使用 (或不使用) HTTP/2填充 (Padding) 和压缩 (Compression) [RFC7540] 一样使用它们。

4.1.1. HTTP Request Examples (HTTP请求示例)

这些示例使用来自 [RFC7540] 的HTTP/2风格格式。

这些示例使用URI模板为 https://dnsserver.example.net/dns-query{?dns} 的DoH服务来解析IN A记录。

请求被表示为具有媒体类型"application/dns-message"的主体。

第一个示例显示了一个使用GET方法查询 www.example.com 的示例:

:method = GET
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application/dns-message

DNS查询的数据在"dns"变量中。一些字符编码和填充细节已被省略。

第二个示例显示了一个使用POST方法进行相同查询的示例:

:method = POST
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query
accept = application/dns-message
content-type = application/dns-message
content-length = 33

<33 bytes represented by the following hex encoding>
00 00 01 00 00 01 00 00 00 00 00 00 03 77 77 77
07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00
01

最后,一个示例显示了如何使用JSON [RFC8259] (也称为"application/json"媒体类型) 查询 www.example.com 的A记录。这与DoH不兼容,但说明了内容协商的使用:

:method = GET
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application/dns-json

4.2. The HTTP Response (HTTP响应)

本文档中定义的唯一响应类型是"application/dns-message",但将来可能会定义其他响应格式。

DoH服务器必须 (MUST) 能够处理"application/dns-message"请求消息。

DoH服务器应该 (SHOULD) 能够提供"application/dns-message"响应。

DoH服务器可以 (MAY) 提供对使用GET方法请求的内容协商响应。

HTTP成功响应的Content-Type响应头字段指示响应的媒体类型。响应可以包含在第6节中定义的"application/dns-message"格式的DNS响应,或者是通过内容协商提供的其他类型。

如果有HTTP响应,HTTP响应头字段指示响应的格式。响应的媒体类型决定了如何解析和处理响应。DoH客户端必须 (MUST) 能够处理"application/dns-message"格式的响应,并可以 (MAY) 能够处理其他格式。

当使用"application/dns-message"内容类型时,响应消息主体包含完整的DNS响应 (包括所有头字段),除非HTTP响应码指示请求没有成功 (见下文)。DoH服务器必须 (MUST) 在响应的DNS头中设置"query identifier" (QID) 字段为零。DoH客户端必须 (MUST) 忽略DNS响应中的QID字段。

4.2.1. Handling DNS and HTTP Errors (处理DNS和HTTP错误)

如果DNS响应没有成功,DoH服务器仍然返回带有DNS响应的HTTP成功状态码 (2xx)。DNS响应自身会指示DNS级别的错误。

如果服务器无法解析请求,通常会返回HTTP 4xx错误。客户端应该 (SHOULD) 将此视为DNS SERVFAIL响应。

如果服务器拒绝服务,服务器可以 (MAY) 使用HTTP重定向 (3xx状态码)。DoH客户端必须 (MUST) 处理HTTP重定向。DoH客户端应该 (SHOULD) 对重定向的数量施加上限,以避免循环,类似于普通的HTTP客户端。

如果请求中缺少DNS查询或DoH服务器无法解析DNS查询,服务器应该 (SHOULD) 返回HTTP 400 (Bad Request) 错误。

如果DoH服务器遇到与DNS无关的技术问题,服务器应该 (SHOULD) 返回HTTP 500 (Internal Server Error) 错误。

如果DoH服务器在配置的URI路径上不提供DoH服务,它应该 (SHOULD) 返回HTTP 404 (Not Found) 错误。

如果DoH服务器不支持客户端提交的媒体类型,它应该 (SHOULD) 返回HTTP 415 (Unsupported Media Type) 错误。

4.2.2. HTTP Response Example (HTTP响应示例)

这显示了对4.1.1节第一个查询示例的响应:

:status = 200
content-type = application/dns-message
content-length = 64
cache-control = max-age=128

<64 bytes represented by the following hex encoding>
00 00 81 80 00 01 00 01 00 00 00 00 03 77 77 77
07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00
01 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f
6d 00 00 01 00 01 00 00 00 80 00 04 5d b8 d8 22

此示例的DNS响应表示 www.example.com 的IPv4地址是 93.184.216.34,此信息的TTL为128秒。