10. CoAP 与 HTTP 之间的跨协议代理
CoAP 支持 HTTP 功能的一个有限子集, 因此到 HTTP 的 cross-protocol proxying 比较直接. 在 CoAP 和 HTTP 之间代理可能有多种原因, 例如设计一个可通过任一协议使用的 Web 接口, 或实现 CoAP-HTTP proxy. 同样, CoAP 也可以被代理到其他协议, 例如 XMPP [RFC6120] 或 SIP [RFC3264]. 这些机制的定义超出本规范范围.
通过 forward-proxy 访问资源有两个可能方向:
CoAP-HTTP Proxying: 使 CoAP 客户端能够通过中介访问 HTTP 服务器上的资源. 这是通过在发往 CoAP-HTTP proxy 的 CoAP 请求中包含带有 "http" 或 "https" URI 的 Proxy-Uri 或 Proxy-Scheme Option 来发起的.
HTTP-CoAP Proxying: 使 HTTP 客户端能够通过中介访问 CoAP 服务器上的资源. 这是通过在发往 HTTP-CoAP proxy 的 HTTP 请求的 Request-Line 中指定 "coap" 或 "coaps" URI 来发起的.
无论哪种方式, 只有 CoAP 的 request/response model 被映射到 HTTP. Confirmable 或 Non-confirmable 报文等底层模型对代理功能不可见, 并且 MUST 不对代理功能产生影响. 以下各节描述对 forward-proxy 的请求处理. 本规范未规定 reverse-proxy, 因为代理功能对客户端透明, 代理表现得就像 origin server. 但是, 类似的考虑同样适用于 reverse-proxy 和 forward-proxy, 通常也会期望 reverse-proxy 以类似 forward-proxy 的方式运行. 作为实现说明, HTTP 客户端库可能因为不提供在 HTTP Request-Line 中放置 CoAP URI 的方式, 而使 HTTP-CoAP forward-proxy 难以运行. 因此 reverse-proxying 可能让代理具有更广的适用性. 单独的规范可以定义运行这种 HTTP-CoAP reverse-proxy 的 URI 约定 [MAPPING].
10.1. CoAP-HTTP 代理
如果请求包含 Proxy-Uri 或 Proxy-Scheme Option, 且其中带有 'http' 或 'https' URI [RFC2616], 则接收该请求的 CoAP 端点 (下文称为 "代理") 被请求对所指示的 HTTP 资源执行请求方法指定的操作, 并将结果返回给客户端. (另见 Section 5.7, 其中说明了如何构造发往代理的请求, 包括安全要求.)
本节针对任意 CoAP 请求规定代理应向客户端返回的 CoAP 响应. 代理实际如何满足请求属于实现细节, 尽管典型情形预期是代理转换请求并将其转发给 HTTP origin server.
由于 HTTP 和 CoAP 共享基本的请求方法集合, 在 HTTP 资源上执行 CoAP 请求与在 CoAP 资源上执行并无太大不同. 各个 CoAP 方法在 HTTP 资源上执行时的含义在本节各小节中说明.
如果代理无法或不愿处理带有 HTTP URI 的请求, 则向客户端返回 5.05 (Proxying Not Supported) 响应. 如果代理通过与第三方 (例如 HTTP origin server) 交互来处理请求, 但无法在合理时间范围内获得结果, 则返回 5.04 (Gateway Timeout) 响应. 如果可以获得结果但代理无法理解, 则返回 5.02 (Bad Gateway) 响应.
10.1.1. GET
GET 方法请求代理返回由 request URI 标识的 HTTP 资源表示.
成功时, SHOULD 返回 2.05 (Content) Response Code. 响应 payload MUST 是目标 HTTP 资源的表示, 并且 Content-Format Option MUST 相应设置. 响应 MUST 指示一个 Max-Age 值, 该值不大于该表示还能被认为新鲜的剩余时间. 如果 HTTP entity 具有 entity-tag, 代理 SHOULD 在响应中包含 ETag Option, 并按下面描述处理请求中的 ETag Options.
客户端可以通过包含以下 option 来影响 GET 请求的处理:
Accept: 请求 MAY 包含 Accept Option, 用于标识首选的响应 content-format.
ETag: 请求 MAY 包含一个或多个 ETag Options, 用于标识客户端已存储的响应. 这要求代理在原本会发送带有请求集合中某个 entity-tag 的 2.05 (Content) 响应时, 改为发送 2.03 (Valid) 响应. 注意, CoAP ETag 在 HTTP 意义上始终是 strong ETag. CoAP 没有与 HTTP weak ETag 等价的机制, 在 cross-proxy 中也没有好的方式使用它们.
10.1.2. PUT
PUT 方法请求代理使用随附的表示来更新或创建由 request URI 标识的 HTTP 资源.
如果在 request URI 处创建了新资源, MUST 向客户端返回 2.01 (Created) 响应. 如果修改了现有资源, MUST 返回 2.04 (Changed) 响应以指示请求成功完成.
10.1.3. DELETE
DELETE 方法请求代理删除 HTTP origin server 上由 request URI 标识的 HTTP 资源.
成功时, 或者资源在请求时不存在时, MUST 向客户端返回 2.02 (Deleted) 响应.
10.1.4. POST
POST 方法请求代理让 HTTP origin server 处理请求中随附的表示. POST 方法执行的实际功能由 origin server 决定, 并取决于 request URI 标识的资源.
如果 POST 方法执行的动作没有产生可由 URI 标识的资源, MUST 向客户端返回 2.04 (Changed) 响应. 如果已在 origin server 上创建资源, MUST 返回 2.01 (Created) 响应.
10.2. HTTP-CoAP 代理
如果 HTTP 请求包含带有 "coap" 或 "coaps" URI 的 Request-URI, 则接收该请求的 HTTP 端点 (下文称为 "代理") 被请求对所指示的 CoAP 资源执行请求方法指定的操作, 并将结果返回给客户端.
本节针对任意 HTTP 请求规定代理应向客户端返回的 HTTP 响应. 除非另有规定, 所有陈述均为 RECOMMENDED 行为. 某些高度受限的实现可能需要采用捷径. 代理实际如何满足请求属于实现细节, 尽管典型情形预期是代理转换请求并将其转发给 CoAP origin server. 各个 HTTP 方法在 CoAP 资源上执行时的含义在本节各小节中说明.
如果代理无法或不愿处理带有 CoAP URI 的请求, 则向客户端返回 501 (Not Implemented) 响应. 如果代理通过与第三方 (例如 CoAP origin server) 交互来处理请求, 但无法在合理时间范围内获得结果, 则返回 504 (Gateway Timeout) 响应. 如果可以获得结果但代理无法理解, 则返回 502 (Bad Gateway) 响应.
10.2.1. OPTIONS and TRACE
由于 CoAP 不支持 OPTIONS 和 TRACE 方法, MUST 向客户端返回 501 (Not Implemented) 错误.
10.2.2. GET
GET 方法请求代理返回由 Request-URI 标识的 CoAP 资源表示.
成功时, 返回 200 (OK) 响应. 响应 payload MUST 是目标 CoAP 资源的表示, 并且 Content-Type 和 Content-Encoding 头字段 MUST 相应设置. 响应 MUST 指示一个 max-age directive, 该 directive 指示的值不大于该表示还能被认为新鲜的剩余时间. 如果 CoAP 响应带有 ETag option, 代理应在响应中包含 ETag 头字段.
客户端可以通过包含以下 options 来影响 GET 请求的处理:
Accept: HTTP Accept 头字段中最优先的 media type 会被映射为 CoAP Accept option. CoAP Accept option 不支持 HTTP Accept 的 media-type ranges, parameters 和 extensions. 如果代理无法发送一个按照组合后的 Accept 字段值可接受的响应, 则代理发送 406 (Not Acceptable) 响应. 随后代理 MAY 使用 HTTP Accept 头字段中的其他 media types 重试请求.
Conditional GETs: 包含 "If-Match" 或 "If-None-Match" request-header field 的条件 HTTP GET 请求可以映射为相应的 CoAP 请求. "If-Modified-Since" 和 "If-Unmodified-Since" request-header fields 不由 CoAP 直接支持, 但可由缓存代理在本地实现.
10.2.3. HEAD
HEAD 方法与 GET 相同, 但服务器 MUST NOT 在响应中返回 message-body.
虽然 CoAP 中没有 HTTP HEAD 方法的直接等价物, HTTP-CoAP proxy 会响应针对 CoAP 资源的 HEAD 请求, 并返回不带 message-body 的 HTTP 头部.
实现说明: HTTP-CoAP proxy 可能希望尝试使用 block-wise transfer option [BLOCK] 来最小化实际传输的数据量, 但它需要准备好 origin server 不支持 block-wise transfers 的情况.
10.2.4. POST
POST 方法请求代理让 CoAP origin server 处理请求中随附的表示. POST 方法执行的实际功能由 origin server 决定, 并取决于 request URI 标识的资源.
如果 POST 方法执行的动作没有产生可由 URI 标识的资源, MUST 向客户端返回 200 (OK) 或 204 (No Content) 响应. 如果已在 origin server 上创建资源, MUST 返回 201 (Created) 响应.
如果 CoAP 响应中存在任何 Location-* Options, 则返回一个由这些 options 的值构造出的 Location 头字段.
10.2.5. PUT
PUT 方法请求代理使用随附的表示来更新或创建由 Request-URI 标识的 CoAP 资源.
如果在 Request-URI 处创建了新资源, 向客户端返回 201 (Created) 响应. 如果修改了现有资源, 则发送 200 (OK) 或 204 (No Content) Response Codes 之一, 以指示请求成功完成.
10.2.6. DELETE
DELETE 方法请求代理删除 CoAP origin server 上由 Request-URI 标识的 CoAP 资源.
如果响应包含描述状态的 entity, 成功响应为 200 (OK). 如果动作已执行但响应不包含 entity, 成功响应为 204 (No Content).
10.2.7. CONNECT
该方法目前无法由 HTTP-CoAP proxy 功能满足, 因为尚未规定从 TLS 到 DTLS 的隧道化. 目前, 向客户端返回 501 (Not Implemented) 错误.