url.el 部分 HTTPS 链接没法工作?

我从源编译安装的 Emacs Mac Port 完全正常,可是从 brew install emacs 安装的 Emacs 有部分 HTTPS 链接有问题,比如:

~ $ emacs --batch --eval '(with-current-buffer (url-retrieve-synchronously "https://example.com/") (print (buffer-string)))'
Contacting host: example.com:443

""
~ $ emacs --batch --eval '(with-current-buffer (url-retrieve-synchronously "https://unpkg.com/[email protected]/dist/data.json") (print (buffer-string)))'
Contacting host: unpkg.com:443

"HTTP/1.1 400 Bad Request
Server: cloudflare
Date: Tue, 28 May 2019 04:38:28 GMT
Content-Type: text/html
Content-Length: 269
Connection: close
CF-RAY: -

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor=\"white\">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>cloudflare</center>
</body>
</html>
"
~ $

一个没有返回,另一个返回 400,感觉是 Emacs 的锅,但是不知道具体怎么回事。

但有些 HTTPS 链接却没有问题,如:https://www.gnu.org/

~ $ emacs --batch --eval '(with-current-buffer (url-retrieve-synchronously "https://www.gnu.org/") (print (buffer-string)))'
Contacting host: www.gnu.org:443

"HTTP/1.1 200 OK
...

估计一个有 TLS,一个沒有。

不明白怎么回事。没了解过 HTTPS 客户端是怎么工作的。

可以先用curl测试的吧

嗯,这些链接是正常的,只是 Emacs 这边没法正常工作。

我的意思是看看你从 brew 装的 emacs 有沒有 link libgnutls。(我这个預编译的 MacPort 的 libgnutls 是 self contain 的)

有:

~ $ otool -L /usr/local/bin/emacs
/usr/local/bin/emacs:
	/usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0)
	/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
	/usr/local/opt/gnutls/lib/libgnutls.30.dylib (compatibility version 54.0.0, current version 54.2.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
~ $

我的疑问是为什么有些 HTTPS 可以而有些却不行?或许得要明白 HTTPS 是怎么工作。

应该是同一个问题。

1 个赞

这个 error message 已經够 self explanatory 了,应該是不知为何 Emacs 沒有发 https 请求而幾成了 http,而这些服务器的设置会阻止 http 连接 https 端口。Fix “The plain HTTP request was sent to HTTPS port” Error in Nginx

问題在为什么 emacs 会发 http 而不是 https。

为什么我用 gnutls-cli 以网站自己的证书也验证不通过?

➜  .doom.d gnutls-cli --x509cafile=github.crt www.github.com -p 443
|<1>| There was a non-CA certificate in the trusted list: C=US,ST=California,L=San Francisco,O=GitHub\, Inc.,CN=github.com.
Processed 1 CA certificate(s).
Resolving 'www.github.com:443'...
Connecting to '192.30.255.112:443'...
- Certificate type: X.509
- Got a certificate list of 2 certificates.
- Certificate[0] info:
 - subject `CN=github.com,O=GitHub\, Inc.,L=San Francisco,ST=California,C=US', issuer `CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US', serial 0x0557c80b282683a17b0a114493296b79, RSA key 2048 bits, signed using RSA-SHA256, activated `2020-05-05 00:00:00 UTC', expires `2022-05-10 12:00:00 UTC', pin-sha256="4PhpWPCTGkqmmjRFussirzvNSi4LjL7WWhUSAVFIXDc="
	Public Key ID:
		sha1:b255b18a964ca1367988026d549ef9ba71493bf3
		sha256:e0f86958f0931a4aa69a3445bacb22af3bcd4a2e0b8cbed65a15120151485c37
	Public Key PIN:
		pin-sha256:4PhpWPCTGkqmmjRFussirzvNSi4LjL7WWhUSAVFIXDc=

- Certificate[1] info:
 - subject `CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US', issuer `CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US', serial 0x04e1e7a4dc5cf2f36dc02b42b85d159f, RSA key 2048 bits, signed using RSA-SHA256, activated `2013-10-22 12:00:00 UTC', expires `2028-10-22 12:00:00 UTC', pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="
- Status: The certificate is NOT trusted. The certificate issuer is unknown.
*** PKI verification of server certificate failed...
*** Fatal error: Error in the certificate.