TCP 標準被整理到 RFC 9293

看到「RFC 9293: Transmission Control Protocol (TCP)」這篇,主要是把本來分散在各個 RFC 的文件 (從 RFC 793 開始) 全部整理成一份,另外把一些已知的勘誤表放進來:

This document specifies the Transmission Control Protocol (TCP). TCP is an important transport-layer protocol in the Internet protocol stack, and it has continuously evolved over decades of use and growth of the Internet. Over this time, a number of changes have been made to TCP as it was specified in RFC 793, though these have only been documented in a piecemeal fashion. This document collects and brings those changes together with the protocol specification from RFC 793. This document obsoletes RFC 793, as well as RFCs 879, 2873, 6093, 6429, 6528, and 6691 that updated parts of RFC 793. It updates RFCs 1011 and 1122, and it should be considered as a replacement for the portions of those documents dealing with TCP requirements. It also updates RFC 5961 by adding a small clarification in reset handling while in the SYN-RECEIVED state. The TCP header control bits from RFC 793 have also been updated based on RFC 3168.

然後淘汰掉 (obselete) 一卡車 RFC 文件 XD

翻資料發現 2014 的時候 HTTP/1.1 被幹過一次類似的事情,不過是反過來被拆開:「HTTP/1.1 的更新」,這次把 RFC 2616 幹掉分成 RFC 7230RFC 7235

然後今年因為 HTTP 的關係又被幹了一次,這次 HTTP/1.1 又被整回來變成一份文件,但是把裡面的一些概念拆開:「HTTP 標準的翻新」。

其中 RFC 9110 定義 HTTP Semantics,RFC 9111 定義 HTTP Caching,然後 RFC 9112RFC 9113 拿來定義了 HTTP/1.1 與 HTTP/2,另外先把 HTTP/3 的號碼保留下來的 RFC 9114

不斷 refactor 以及加新功能的文件...

HTTP 標準的翻新

HTTP 的標準之前都是用新的 RFC 補充與修正舊的標準,所以整體讀起來會比較累,對於開始了解 HTTP 的人會需要交叉讀才能理解。

而這次 RFC 9110~9114 算是一次性的把文件全部重新整理出來,可以看到蠻多人 (以及團體) 都有丟出來對應的看法,這邊丟這兩篇:「A New Definition of HTTP」與「HTTP RFCs have evolved: A Cloudflare view of HTTP usage trends」。

而這五個 RFC,從名稱列出來就可以看出來命名簡單粗暴,把核心概念先拆出來講,然後再講不同 protocol 的部份:

Cloudflare 這邊提供了一些資料,可以看到三個 protocol 使用率都算高,而目前最高的是 HTTP/2:

另外比較特別的是 Safari 在 HTTP/3 的趨勢居然有倒縮的情況:

然後 bot 的部份幾乎大家都支援 HTTP/2 了,目前還沒看到太多 HTTP/3 的蹤跡,倒是 LinkedIn 的 bot 有個奇怪的 adoption 然後全部 rollback 的情況,而最近又開始少量導入了:

這次看起來淘汰了 (obsolete) 很多之前的文件,以後要引用得往這五份來引...

PHP 8.2 預計要將一些字串內指定變數的方法標為 Deprecated,在 9.0 移除

Twitter 上看到這個蠻大的改變:

裡面的連結是「PHP RFC: Deprecate ${} string interpolation」,在文件中提到了 PHP 語言支援的四種字串內指定變數的方式:

  1. Directly embedding variables (“$foo”)
  2. Braces outside the variable (“{$foo}”)
  3. Braces after the dollar sign (“${foo}”)
  4. Variable variables (“${expr}”, equivalent to (string) ${expr})

提案在 PHP 8.2 裡將 3 與 4 兩種方式標為 deprecated,並且在 PHP 9.0 移除,目前看起來是 31:1 通過了...

RFC 3339 與 ISO 8601 用範例的比較

Hacker News 首頁上看到「RFC 3339 vs. ISO 8601 (ijmacd.github.io)」這個連結,原始網站是「RFC 3339 vs ISO 8601」。

兩個都是試著定義日期與時間的表達方式,其中 ISO 8601 是在 1988 年定義出來的,被廣泛應用在很多 spec 裡,但最大的問題就是 ISO 8601 沒辦法公開免費取得,這點在前幾個月也在 Hacker News 上被討論過:「ISO-8601 date format reference not publicly available (twitter.com/isostandards)」。

RFC 3339 是在 2002 年訂出來,其中一個目標就是試著解決 ISO 8601 不公開的問題 (沒講明就是了):

This document includes an Internet profile of the ISO 8601 [ISO8601] standard for representation of dates and times using the Gregorian calendar.

這份 RFC 3339 與 ISO 8601 的比較可以讓設計 spec 的人可以看一下,在大多數的情況下,RFC 3339 應該是夠用的...

Amazon SES 總算支援 2048 bits RSA key 了

Amazon SES 總算是支援 2048 bits RSA key 了:「Amazon SES now supports 2048-bit DKIM keys」。

然後講一些幹話... 隔壁微軟早在 2019 年就支援 2048 bits RSA key 了:

Until now, Amazon SES supported a DKIM key length of 1024-bit, which is the current industry standard.

另外用 ECC 演算法的一直都沒進 standard,像是已經先 book 了 RFC 8463 位置的 Ed25519,在 draft 狀態放好久了:「A New Cryptographic Signature Method for DomainKeys Identified Mail (DKIM)」,還有用 ECDSA 的「Defining Elliptic Curve Cryptography Algorithms for use with DKIM」也是放著,不知道是卡到什麼東西,可能是專利?

QUIC 成為標準,從 RFC 8999 到 RFC 9002

前幾天的新聞了,這兩天 FastlyCloudflare 也都發文章出來了,QUIC 成為標準:「QUIC is now RFC 9000」、「QUIC Version 1 is live on Cloudflare」。

主要是這兩家都發稿宣傳他們的平台都支援 QUIC 了,接下來可以等一些測試報告,看看在 web 這種已經有不少複雜的 workaround 機制下,TCP BBR 環境的 HTTP/2 跟 QUIC 環境會有多少差異... 記得 QUIC 也是 BBR-based 的演算法。

在 QUIC 下的 https 協定會走 443/udp,如果防火牆是預設阻擋所有連線,然後逐條開放的話,需要另外開這組設定。

另外就是等 nginx 支援了,在「NGINX QUIC Preview」這邊有些資料,然後「">nginx-quic: log」裡面可以看到東西,裡面不少 commit 只是跟 nginx 本家同步而已,不過還是可以看到一些跟 QUIC 有關的...

在 HTTP Header 裡面傳結構性資料

忘了在哪邊看到的,好像是 Twitter 上看到的,mnotphk 兩個人弄了一個新的 RFC 標準,可以在 HTTP header 裡面傳結構性資料:「Structured Field Values for HTTP」。

第一個最直接的問題就在「A.1. Why Not JSON?」這個章節說明,考慮了既有的限制,包括 JSON spec,以及市場上既有的 JSON library 的實做。

但也因為自己定義了資料結構,Serializing & Parsing 就得另外再開發 library 處理,這樣會有多少 framework 支援就是個問題了,而且對於開發者來說,直接塞 JSON 很好理解,這個標準的前景不知道會怎麼樣...

RFC 定義的 application/problem+json (或是 xml)

剛剛在 Clubhouse 上聽到保哥提到了 RFC 7807 這個東西 (Problem Details for HTTP APIs),剛剛翻瀏覽器累積的 tab,發現原來先前有看到,而且有打算要出新版的消息:

RFC 7807 裡面這樣定義的方式可以讓 client 端直接判斷 Content-Type 知道這個回傳資料是不是錯誤訊息,不然以前都是 JSON 就得再另外包裝。用 Content-Type 的作法可以讓判斷條件變得清晰不少。

除了 application/problem+jsonapplication/problem+xml 以外,在「3.1. Members of a Problem Details Object」裡面則是說明 JSON (或是 XML) 裡面有哪些必要以及可選的資訊要填,然後「3.2. Extension Members」這邊則大概描述一下怎麼擴充。

先有個印象,之後新規劃的東西可以考慮進去...

GET 與 POST 的差異

看到這篇在講 HTTP (& HTTPS) 裡面 GET 與 POST 的差異,剛好把一些標準的定義拿出來翻一翻,算是複習基本概念:「Get safe」。

第一個基本概念主要是 idempotence (& idempotent),重複被呼叫不會造成狀態的再次改變:

Idempotence ([...]) is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.

數學定義是這樣跑:

An element x of a magma (M, •) is said to be idempotent if:

x • x = x.

If all elements are idempotent with respect to •, then • is called idempotent. The formula ∀x, x • x = x is called the idempotency law for •.

這點在 HTTP 標準 (RFC 7231) 裡面的定義也類似:

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.

第二個基本概念是 Safe method (也是在同樣的 RFC 裡被提到),主要的思想是 read-only,這也是文章作者的標題要講的事情:

Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.

然後標準的 HTTP method 是有定義的:

   +---------+------+------------+---------------+
   | Method  | Safe | Idempotent | Reference     |
   +---------+------+------------+---------------+
   | CONNECT | no   | no         | Section 4.3.6 |
   | DELETE  | no   | yes        | Section 4.3.5 |
   | GET     | yes  | yes        | Section 4.3.1 |
   | HEAD    | yes  | yes        | Section 4.3.2 |
   | OPTIONS | yes  | yes        | Section 4.3.7 |
   | POST    | no   | no         | Section 4.3.3 |
   | PUT     | no   | yes        | Section 4.3.4 |
   | TRACE   | yes  | yes        | Section 4.3.8 |
   +---------+------+------------+---------------+

不過文章裡面提到的第一個例子並沒有很好,POST 不保證 safe 沒錯,但不代表 safe operation 就不能用 POST。

這邊用 URI resource 的概念 (以及 SEO?) 或是用 Post/Redirect/Get 的概念來說明會比較好:

<form method="get" action="/search">
<input type="search" name="term">

不過文章後續提到的問題的確就是我自己都會犯錯的問題:

“Log out” links that should be forms with a “log out” button—you can always style it to look like a link if you want.

“Unsubscribe” links in emails that immediately trigger the action of unsubscribing instead of going to a form where the POST method does the unsubscribing. I realise that this turns unsubscribing into a two-step process, which is a bit annoying from a usability point of view, but a destructive action should never be baked into a GET request.

這兩個動作都會造成 server 端的狀態改變,不應該用 GET,而我自己常常忘記第一個... 這邊其實可以用 form 產生 POST 需求,並且用 css 效果包起來,達到看起來跟一般的連結一樣。

寫起來讓自己多一點印象,之後避免再犯一樣的錯誤...

RFC 裡面的 MUST/SHOULD/MAY

讀 RFC 文件時常看到會使用這組定義,甚至有些非 RFC 文件也會使用:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

這邊提到的 RFC 2119 就是 1997 年訂的「Key words for use in RFCs to Indicate Requirement Levels」這篇,以 2020 年的現在來說,這組定義已經被人熟知,用這組定義可以讓閱讀的人很輕鬆的了解條件的強制性。

剛剛在讀新的文件時發現這段文字有更新,往回查發現是針對大小寫的差異提出更新:「Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words」,主要是這兩條:

  • The words have the meanings specified herein only when they are in all capitals.
  • When these words are not capitalized, they have their normal English meanings and are not affected by this document.

然後也更新了引用的部份:

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.

不過就算是 2017 年之前應該也是這樣讀就是了...