如何阅读RFC?

如何阅读RFC?

当我们接触这个计算机世界的时候,我们总会想,这些事物的来源,她们为何存在?存在的要求是什么?当我们不断地深入时候,总是希望进一步的了解他们,这大概就是RFC

如何阅读RFC

来源: How to read RFC?

无论好坏,请求注释文档(RFC)包含了我们在Internet上遇到的许多协议。这些RFC文档被开发人员视为圣经,他们会试着去发现隐藏的含义,即使无法理解也无关紧要。虽然这通常会导致挫败感 - 但更重要的是 - RFC其中的操作性和安全性思考。

然而,根据我对HTTP和其他一些事情的经验和收获,我们通过对RFC如何构建和发布的一些了解,可以更容易理解正在查看的RFC内容。

RFC阅读技巧实例

1.从哪儿开始阅读?

查找RFC的规范位置是RFC编辑器网站。但是,正如我们将在下面看到的那样,RFC编辑器缺少一些关键信息,因此大多数人都使用 tools.ietf.org

即使找到合适的RFC也很困难,因为有这么多的RFC(目前,将近9,000份)。显然,您可以使用通用Web搜索引擎找到它们,并且RFC编辑器在其站点上具有出色的搜索功能。

另一个方式是EveryRFC,我将它放在一起,以便按标题和关键字搜索RFC,并按标签进行探索。

毫无疑问,纯文本RFC难以阅读,这种情况可以通过一些方式改变; RFC编辑器正在包含一种新的RFC格式,具有更令人满意的演示和自定义选项。与此同时,如果您想要更多可用的RFC,您可以将第三方存储库用于选定的存储库; 例如,greenbytes保留与WebDAV相关的RFC列表,HTTP工作组维护与HTTP相关的RFC。

2.它是什么类型的RFC?

所有RFC在顶部都有一个横幅,看起来像这样:

Internet Engineering Task Force (IETF)                  R. Fielding, Ed.
Request for Comments: 7230                                         Adobe
Obsoletes: 2145, 2616                                    J. Reschke, Ed.
Updates: 2817, 2818                                           greenbytes
Category: Standards Track                                      June 2014
ISSN: 2070-1721

在左上角,这个说“互联网工程任务组(IETF)”。这表明这是IETF的产品; 虽然它并不广为人知,但还有其他方法可以发布不需要IETF共识的RFC; 例如,独立媒体

实际上,许多“媒体”在RFC编辑器文档上发布了RFC文档。但要注意,只有IETF流表明整个IETF已经审核并已就协议规范达成了共识

在较旧的文档(在RFC5705之前)在那里IETF被称为“网络工作组”,因此你需要多挖掘一下,看看它们是否代表了IETF的共识; 查看RFC编辑器站点“Status of this Memo ”部分可以了解标识情况。

在确认“请求文档”编号之前。它被称为“Internet-Draft互联网草案”,而不是RFC ; 说明这还只是一个提案,任何人都 可以写一个草案。仅仅因为某些东西是互联网草案但并不意味着它将被IETF采用。

RFC的类别是“标准跟踪”,“信息”,“实验”或“最佳实践”之一。这些之间的区别有时是模糊的,但如果它是由IETF(互联网工程组)产生的,那么它就有了合理的审查。但请注意,即使IETF已达成共识,信息实验也不是标准。

最后,RFC文档的作者会在标题的右侧著名。与学术界不同,这不是一份全面的文件清单; 通常,这是在“致谢”部分的底部附近完成的。在RFC中,这实际上是“谁编写了文档。”通常,您会看到附加的“Ed。”,这表明它们充当编辑人员,这是因为RFC或者草案是预先存在的(就像RFC修订时一样))。

3.RFC是最新的吗?

“RFC是一系列档案文件; 他们不能改变,即使是一个字符也不能改变”(参见RFC7158和RFC7159之间差异这样做是极端的;)。

因此,知道您正在查看正确的文档非常重要。标题包含几个元数据,可以帮助明白这是关于什么内容的RFC:

  • Obsoletes列出了完全被取代的RFC文档(取代文档会比旧文档大); 即,你应该使用这个文件,而不是那个。请注意,旧版本的协议不一定会在较新版本的协议出现时废弃; 例如,HTTP / 2不会废弃HTTP / 1.1,因为实现旧协议仍然是合法的(也是必要的)。但是,RFC7230确实废弃了RFC2616,RFC2616是该协议的参考。


  • update列出了本文档进行实质性更改的RFC; 换句话说,如果你正在阅读这边RFC文档,同时也应该阅读这些Update RFC 文章。


遗憾的是,ASCII格式文本 RFC(例如,在RFC编辑器站点上的RFC)不会告诉你当前正在查看的文档哪些文档更新或废弃了。这就是大多数人在tools.ietf.org上使用RFC存储库的原因,它将这些信息放在这样的Banner

[Docs] [txt|pdf] [draft-ietf-http...] [Tracker] [Diff1] [Diff2] [Errata]
​
Obsoleted by: 7230, 7231, 7232, 7233, 7234, 7235          DRAFT STANDARD
Updated by: 2817, 5785, 6266, 6585                          Errata Exist

工具页面上的每个数字都是一个链接,因此您可以轻松找到当前文档。

即使是最新的RFC也经常出现问题。在工具横幅中,您还会在右侧看到“Errata Exist”上面的勘误表链接警告。

勘误表Errata是对文档的更正和澄清,更正和澄清是不值得发布新的RFC。但有时它们会对RFC的实现方式产生重大影响(例如,如果规范中的错误是一个严重的错误),那么它们值得通过。

例如,这是RFC7230勘误表Errata。当阅读勘误表时,请记住他们的状态; 许多人的修订被拒绝,因为有人误解了规范。



4.理解RFC背景

对于开发人员来说,查看RFC中的语句,实现他们看到的内容,但实际会与作者的意图相反,这种情况比想象中更为常见。

这是因为在选择性地阅读规范时,以一种不能被误解的方式编写规范是极其困难的(任何仿佛圣经一样的文档都会出现类似情况)。

因此,不仅需要阅读直接相关的文本,还必须(至少)阅读它引用的任何相关内容,无论是相同的规范还是不同的规范。如果您无法阅读整个RFC,那么通过阅读任何可能相关的部分也会有很大帮助。

例如,HTTP消息头被定义为由CRLF(回车\r换行\n)分隔,但是如果你在这里跳过,你会看到“收件人可以将单个LF(换行\n)识别为行终止符并忽略任何前面的CR(回车\n)。”

同样重要的是要记住,许多协议都设立了IANA注册管理机构来管理其扩展点; 这些注册管理机构不是规范,是事实的来源。例如,HTTP方法的规范列表在此注册表中,而不是任何HTTP规范。

5.RFC语法要求

几乎所有的RFC都有类似于顶部的样板:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.

这些RFC2119关键字有助于定义互操作性,但它们有时也会使开发人员感到困惑。看到规范说出如下内容是很常见的:

The Foo message MUST NOT contain a Bar header.

该要求被置于协议假象“Foo message”上。如果您要发送一个,很明显它不需要包含Bar header; 如果你包含一个,它将不是一个符合要求的消息。

但是,收件人的行为不太清楚; 如果你看到带有“Bar header“的“Foo message“,你会怎么做?

一些开发人员会拒绝包含“Bar header“的“Foo message“,即使规范没有说明这样做。其他人仍将处理消息,但剥离Bar header,或忽略Bar header - 即使规范明确指出需要处理所有header。

所有这些事情都可能 -或者无意中 - 导致一些互操作性问题。正确的做法是遵循标题的正常处理,除非有相反的特定要求

这是因为通常会写规范以便明确指定行为; 换句话说,允许未明确禁止的所有内容(只要没说的都是允许,但是一旦严格规定就需要严格遵循)。因此,过多地阅读规范可能会无意中造成伤害,因为你会被引入其他人必须解决的新思维。

在理想的世界中,规范将根据处理消息的人的行为来定义,如下所示:

Senders of the Foo message MUST NOT include a Bar header. Recipients
of a Foo message that includes a Bar header MUST ignore the Bar header,
but MUST NOT remove it.

如果没有这个,最好在规范的其他地方寻找有关错误处理的更加一般的建议(例如,HTTP的一致性和错误处理部分)。

另外,请记住要求的目标 :大多数规范都有一套高度发展的术语,用于区分协议中的不同角色。

例如,HTTP具有代理代理是一种中介,它实现客户端和服务器(但不是用户代理或源服务器); 他们需要关注针对所有这些角色的要求。

同样,HTTP根据具体情况区分“生成”消息并仅在某些要求中“转发”消息。注意这种特定的术语可以为你节省很多猜测。

SHOULD



是的,应该得到自己的部分。尽管努力消除它,但这个多余的术语困扰着许多RFC。RFC2119将其描述为:

SHOULD  This word, or the adjective "RECOMMENDED", mean that there
        may exist valid reasons in particular circumstances to ignore a
        particular item, but the full implications must be understood and
        carefully weighed before choosing a different course.

在实践中,作者经常使用SHOULD和SHOULD NOT,这表示“我们希望你这样做,但我们知道我们不能总是要求这么做。”

例如,在HTTP方法概述中,我们看到:

When a request method is received that is unrecognized or not
implemented by an origin server, the origin server SHOULD respond
with the 501 (Not Implemented) status code. When a request method
is received that is known by an origin server but not allowed for
the target resource, the origin server SHOULD respond with the 405
(Method Not Allowed) status code.

这个SHOULD不是必须的,因为服务器可能会合理地决定采取另一个行动; 如果请求被认为是来自攻击者的客户端,则可能丢弃连接,或者要求HTTP身份验证,则可能会在到达405之前使用401(未经过身份验证)强制执行该请求。

SHOULD并不意味着服务器可以自由地忽略一个要求,这看起来对RFC不太尊重。

有时候,我们会看到一个遵循这种形式的SHOULD部分:

A sender that generates a message containing a payload body SHOULD
generate a Content-Type header field in that message unless the
intended media type of the enclosed representation is unknown to
the sender.

注意“除非unless” - 它指定了应该允许的“特殊情况”。可以说这可以指定为SHOULD,因为Unless部分仍然适用,但这种规范风格有点普遍。

6.RFC阅读实例

另一个非常常见的缺陷是浏览示例的规范,并实现它们的功能。

不幸的是,示例通常得到作者最少的关注,因为它们需要随协议的每次更改而更新。

因此,它们通常是规范中最不可靠的部分。是的,作者应该在发布前绝对仔细检查这些例子,但错误确实会出现纰漏。

此外,即使是一个完美的例子也可能无法说明是关于你正在寻找的协议的相关; 为简洁起见,它们经常被截断,或者在解码发生后显示。

尽管需要更多时间,但最好还是阅读实际文本; 示例Examples不是RFC规范。

7.ABNF

增强型BNF通常用于定义伪协议。例如:

FooHeader = 1#foo
foo       = 1*9DIGIT [ ";" "bar" ]

一旦你习惯了它,ABNF提供了一个易于理解的协议元素应该是什么样子的草图。

但是,ABNF是“有理想和抱负的” - 它确定了一个理想的消息形式,而你生成的那些消息确实需要与之匹配。它没有指定如何处理未能匹配的已接收消息。事实上,很多规范关于在处理所有协议上很难说清楚和ABNF的关系。

如果你试图严格执行他们的ABNF,大多数协议将会严重失败,但有时它很重要。在上面的例子中,分号周围不允许有空格,但你可以打赌有些人会把它放在那里,有些实现过程中会接受它。

因此,请确保阅读ABNF周围的文本以了解其他要求或上下文联系,并意识到如果没有直接要求,您可能必须将解析调整为比ABNF暗示的更容易接受的输入。

一些规范开始承认ABNF的期望性质并指定包含错误处理的显式解析算法。如果指定ABNF,应严格遵循这些,以确保互操作性。



8.考虑安全因素

RFC3552以来,RFC样式包含了“安全注意事项”部分。

因此,如果没有关于安全性的实质性部分,很少发布RFC; 审核流程不允许草案只是说“此协议没有考虑安全因素”。

因此,无论您是在实施还是部署协议,都必须阅读并确保您了解“安全注意事项”部分; 如果你不这样做,很可能会有一些东西会让你不知所措(没有考虑的安全因素)。

遵循其参考(如果有的话)也是一个好主意。如果没有,请尝试查找用于理解所讨论问题的一些术语。



9.发现更多

如果RFC没有回答您的问题,或者您不确定其文本的意图,最好的办法是找到最相关的工作组并在他们的邮件列表中提出问题。如果没有涉及相关主题的活动工作组,请尝试相应区域的邮件列表。

提交勘误通常不是您应该采取的第一步 - 第一步一般是:与某人交谈。



许多工作组现在正在使用Github来管理他们的规范; 如果您对有效规范有疑问,请继续提交问题。如果它已经是RFC,通常最好使用邮件列表,除非您找到截然不同的指示。

我确信还有更多关于如何阅读RFC的文章,有些人会质疑我在这里写的内容,但这就是我对它们的看法。我希望它很有用。


附加

rfc-editor.org/rfc-inde

tools.ietf.org/rfc/inde

发布于 2018-09-15

文章被以下专栏收录