我正在尝试向实现超文本咖啡壶控制协议(HTCPCP/1.0,在 RFC 2324 中定义)的服务器发送 BREW 请求,该协议是使用 cURL 构建在 HTTP 之上的协议。
我想煮一杯加奶油和一杯香草糖浆的咖啡,但到目前为止我的所有请求都被服务器拒绝了。
令人困惑的是,RFC 规定 Content-Type 必须设置为“application/coffee-pot-command”(第 2.11 节),但也规定 Content-Type 必须设置为“message/coffeepot”(第 4 节),另外还规定“message/coffeepot”的内容必须包含coffee-message-body,定义为coffee-message-body =“start”|“stop”)。我选择了“application/coffee-pot-command”,纯粹是把它放在第一位(但我两种都尝试过)。
接下来,我添加了一个“Accept-Additions”标题,将牛奶类型指定为“奶油”,将糖浆类型指定为“香草”。RFC 概述了此标头的 BNF:
Accept-Additions = "Accept-Additions" ":"
#( addition-range [ accept-params ] )
addition-type = ( "*"
| milk-type
| syrup-type
) *( ";" parameter )
milk-type = ( "Cream" | "Half-and-half" | "Whole-milk"
| "Part-Skim" | "Skim" | "Non-Dairy" )
syrup-type = ( "Vanilla" | "Almond" | "Raspberry"
| "Chocolate" )
Run Code Online (Sandbox Code Playgroud)
我对这部分的最佳猜测是我需要添加以下标头:
--header "Accept-Additions: Skim;1,Vanilla;1"
Run Code Online (Sandbox Code Playgroud)
虽然我没有解释 BNF 的经验,所以这可能是完全错误的。
所有这些促使我使用 cURL 构建以下请求:
curl -X POST https://theserver.com --header "Content-Type:application/coffee-pot-command" --header "Accept-Additions:Skim;1,Vanilla;1"
Run Code Online (Sandbox Code Playgroud)
然而服务员一直告诉我“无效饮料,不能冲泡”。我哪里出错了?
有一个名为““咖啡”URI 方案”的部分,其中包含更多 BNF:
coffee-url = coffee-scheme ":" [ "//" host ]
["/" pot-designator ] ["?" additions-list ]
coffee-scheme = ( "koffie" ; Afrikaans, Dutch
| "coffee" ; English
)
Run Code Online (Sandbox Code Playgroud)
但我不知道如何解释这一点。我需要在某处添加“coffee:/pot-0”吗?如果是的话,如何在 cURL 中做到这一点?这就是我所缺少的吗?我知道 RFC 是愚人节,但服务器是真实的。为任何能提供帮助的人提供免费咖啡。
我知道这是一个老问题,但我正在尝试实现 HTCPCP 服务器,并且我还发现 RFC 在某些方面是矛盾的、不完整的或看似不准确的。在与 RFC 进行斗争之后,我认为使用 curl 构建请求的适当方法是:
curl 'theserver.com` \
--request 'BREW' \
--header 'Scheme: coffee' \
--header 'Content-Type: message/coffeepot' \
--header 'Accept-Additions: milk-type/Cream, syrup-type/Vanilla' \
--data 'coffee-message-body=start'
Run Code Online (Sandbox Code Playgroud)
上面的语法可能与您正在(曾经?)尝试交互的服务器上的实现一致,也可能不一致,但我在下面解释了我的推理。
从 RFC2324 的第 2 节和第 3 节可以清楚地看出,有效的 HTCPCP URL 应该以coffee:schema 开头,而不是以https:.
第 3 节中的方案是来自 RFC2068 的 URI 通用语法的简化版本,并且似乎限制 HTCPCP 只接受net-pathURI 的形式;“//”后跟网络位置。file:/不允许本地路径(如HTTP 中的路径)。因此,要向位于 的 HTCPCP 服务器发出请求theserver.com,URL 必须以coffee://theserver.com(或国际化的等效形式,例如koffie://theserver.com南非荷兰语/荷兰语)开头。
话虽如此,curl 不允许您指定任意方案,因此我将其移至其自己的 HTTP“方案”标头中,该标头在 Rack 中以 HTTP_SCHEME 形式出现。在我的服务器上,如果设置了 HTTP_SCHEME,我会手动将 url_scheme 更改为 HTTP_SCHEME 值。
URI 的下一部分是可选的,除非有多个罐。对于具有多个罐的服务器,您需要附加/pot-#其中 # 是罐编号。假设索引为零的底池,第二个底池可以在 处访问coffee://theserver.com/pot-1。
URI 的最后(也是可选)部分是附加内容。RFC 没有提供示例(第 3 节可能与第 2.2.2.1 节相矛盾),但我阅读第 3 节的方式是,添加请求应作为附加到 URL 的参数/值对进行传递。如果是这样,您请求的奶油类型为牛奶类型,香草类型为糖浆类型,则意味着additions-listURL 末尾的正确字符串是milk-type=Cream&syrup-type=Vanilla。
将所有这些组合在一起,最终的 URL(假设 HTCPCP 服务器没有多个可用的 Pot)是theserver.com?milk-type=Cream&syrup-type=Vanilla
如果有多个罐子可用,则该地址的第二个罐子(再次假设罐子索引为零)将是theserver.com/pot-1?milk-type=Cream&syrup-type=Vanilla
这种方法的缺点,也许是第 2.2.2.1 节存在的原因,是它似乎不允许替代添加。如果我的第一选择牛奶是奶油,但我也对全脂牛奶感到满意,我如何使用参数/值对指定(并确定优先级)?
对我来说,一个合乎逻辑的答案是,我们请求在 URL 中添加所需的内容,但我们使用标头包含可接受的添加内容(包括任何允许的替换)Accept-Additions。但话又说回来,精心设计的Accept-Additions标头会使 URL 中的添加内容完全多余。在我的实现中,我认为400 Bad Request如果 URL 中存在添加列表但与标头中接受的添加冲突,我将返回错误。
再一次,RFC 中关于如何设置此标头的说明似乎存在印刷错误,并且缺乏示例,但考虑到它似乎是在 2068 上紧密建模的(并明确提到了请求标Accept头字段),我认为其目的是复制accept-params2068的优先级系统。
假设我喜欢白咖啡,脂肪越多越好,但我宁愿喝黑咖啡也不愿喝大豆、大米或杏仁“奶”。在这种情况下,我对牛奶类型的偏好可能是:
为了使用2068 质量值语法来指示这一点,标头可以是:
Accept-Additions: milk-type/Cream,
milk-type/Skim; q=0.5,
milk-type/none; q=0.25,
milk-type/Whole-milk; q=0.75,
milk-type/Half-and-half; q=0.5,
milk-type/Part-skim; q=0.5
Run Code Online (Sandbox Code Playgroud)
顺序无关紧要,因为偏好来自 qvalue。请注意,我从HTTP 规范的标头借用了全小写的none值/语法。Accept-Ranges
就你而言,如果你只想要一杯加奶油的香草咖啡,我怀疑标题应该是:
Accept-Additions: milk-type/Cream, syrup-type/Vanilla
Run Code Online (Sandbox Code Playgroud)
关于媒体类型的矛盾陈述,第 4 节专门讨论了媒体类型,而第 2.1.1 节仅作为旁白提及。此外,第 4 节中的语言比第 2.1.1 节中的语言更强,因此适当的媒体类型是message/coffeepot。
还应该注意的是,该BREW方法是首选的POST,并且主体需要包含coffee-message-body = "start" | "stop",因此组合所有这些部分并开始用奶油冲泡香草咖啡(不接受替代品)的最终卷曲命令将是:
Accept-Additions: milk-type/Cream,
milk-type/Skim; q=0.5,
milk-type/none; q=0.25,
milk-type/Whole-milk; q=0.75,
milk-type/Half-and-half; q=0.5,
milk-type/Part-skim; q=0.5
Run Code Online (Sandbox Code Playgroud)
如果您同意additions-listURL 中的 是多余的,则命令(这次使用 --curl 参数)将是:
Accept-Additions: milk-type/Cream, syrup-type/Vanilla
Run Code Online (Sandbox Code Playgroud)
希望您能收到 2xx 返回代码,并且咖啡将开始冲泡。如果 Cream 或 Vanilla 不可用,您应该返回一个406 Not Acceptable返回代码,并且响应正文应包含当前可用的添加内容。
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |