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 是怎么工作。

https://www.reddit.com/r/emacs/comments/8sykl1/emacs_tls_defaults_are_downright_dangerous/

应该是同一个问题。

1 个赞

这个 error message 已經够 self explanatory 了,应該是不知为何 Emacs 沒有发 https 请求而幾成了 http,而这些服务器的设置会阻止 http 连接 https 端口。https://www.tecmint.com/fix-400-bad-request-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.