在 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 年之前應該也是這樣讀就是了...

PHP 8 將會移除 XML-RPC,改放到 PECL 內

Twitter 上看到「PHP RFC: Unbundle ext/xmlrpc」這則消息,PHP 官方打算把 XML-RPC (也就是 git repository 裡面的 ext/xmlrpc) 拆出去,移到 PECL

Unbundle ext/xmlrpc (i.e. move it to PECL) without any explicit deprecation.

主要的考慮是在於目前的 library 已經年久失修:

ext/xmlrpc relies on on libxmlrpc-epi, which is abandoned. Even worse, we are bundling a modified 0.51, while the latest version is 0.54.1. This is exacerbated by the fact that the system library is usually built against libexpat, but the bundled library is likely to be built against libxml2 using our compatibility layer.

另外應該也是因為 XML-RPC 用的人不多吧,投票是沒什麼玄念的 50:0,而且在 Packagist 上面也可以翻到一些用 PHP 實做的替代品,拿 xmlrpc 這個關鍵字搜了一下可以看到一些...

RFC8482 廢掉 DNS 查詢的 ANY query 了...

看到 Cloudflare 的「RFC8482 - Saying goodbye to ANY」這篇,裡面提到 RFC8482 廢掉了 ANY 查詢:「Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY」。

The Domain Name System (DNS) specifies a query type (QTYPE) "ANY". The operator of an authoritative DNS server might choose not to respond to such queries for reasons of local policy, motivated by security, performance, or other reasons.

對 Cloudflare 的痛點主要在於營運上的困難,因為 ANY 回應的 UDP packet size 很大,很容易造成放大攻擊:

把拒絕 ANY 查詢變成標準後,讓 DNS provider 手上多了一把武器可以用。

ACME,RFC 8555

這邊講的是因為 Let's Encrypt 所發明的 ACME 協定,可以協助自動化發憑證的協定。

剛剛看到「Automatic Certificate Management Environment (ACME)」這個頁面,上面標 PROPOSED STANDARD,但點進去的 txt 檔開頭則是 Standards Track 了:

Internet Engineering Task Force (IETF)                         R. Barnes
Request for Comments: 8555                                         Cisco
Category: Standards Track                             J. Hoffman-Andrews
ISSN: 2070-1721                                                      EFF
                                                             D. McCarney
                                                           Let's Encrypt
                                                               J. Kasten
                                                  University of Michigan
                                                              March 2019

不知道是不是兩邊不同步 (或是我對流程有誤會?),但這有一個標準文件可以參考了...

RFC 8446:TLS 1.3

看到 RFC 8446 (The Transport Layer Security (TLS) Protocol Version 1.3) 正式推出了,也就是 TLS 1.3 正式成為 IETF 的標準 (Standards Track)。

Cloudflare 寫了一篇文章「A Detailed Look at RFC 8446 (a.k.a. TLS 1.3)」描述了 TLS 1.3 的特點,有興趣的人可以看一看,尤其是 1-RTT 的部份對效能幫助很大 (0-RTT 因為 replay attack 問題,我應該暫時都不會考慮,要等到有一個合理的防禦模型出來)。

另外一個是 OpenSSL 目前最新版是 1.1.0h,當初就決定要等 TLS 1.3 正式成為標準才會出 1.1.1 (參考「OpenSSL 1.1.1 將支援 TLS 1.3」,這也熬了一年啊... 支援後會就有很多軟體可以直接套用了,可以來期待了。

保護 TLS 的 Hostname

看到「Encrypted Server Name Indication for TLS 1.3」這個,由 FastlyCloudflareApple 的人聯手推出的 draft,想要保護 TLS 連線一開始明文傳輸的 hostname 部分。看起來是透過 DNS 發佈 public key,然後使用者用這把 public key 保護 hostname 的部分...

而 DNS 的部分可以透過 DNS over TLS 或是 DNS over HTTPS 來保護,這樣讓 ISP 沒有任何資訊可以看到 hostname,把暴露的資訊再降低...

來繼續關注這個技術...

RFC 的 Feed...

想說應該有這樣的東西,就找到「https://tools.ietf.org/html/new-rfcs.rss」這頁,本來以為直接就是 RSS feed 了 (因為網址),一打開來發現看起來像是個網頁,結果最上面這樣說明:

Don't panic. This web page is actually a data file that is meant to be read by RSS reader programs.

馬上打開來看 page source code,果然是 XSL

<?xml-stylesheet title="CSS_formatting" type="text/css" href="css/rss.css"?>
<?xml-stylesheet title="XSL_formatting" type="text/xml" href="rss2html.xsl"?>

好久沒看到這個了,大概是十年前想要做到資料與效果分離 (client-side rendering) 的方式...