TLS 套接字发送 HTTP/2 请求时出错"/>
使用现有 TLS 套接字发送 HTTP/2 请求时出错
我写了一个脚本来建立到目标网站的 TCP 连接,用 TLS 连接包装它,然后使用该 TLS 连接打开 HTTP/2 会话。它对所有网站都正常工作,但是当我向 m.twitch.tv 发出 HTTP/2 请求时,脚本显示此错误:
node:events:491
throw er; // Unhandled 'error' event
^
Error: Client network socket disconnected before secure TLS connection was established
at connResetException (node:internal/errors:717:14)
at TLSSocket.onConnectEnd (node:_tls_wrap:1595:19)
at TLSSocket.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Emitted 'error' event on TLSSocket instance at:
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'ECONNRESET',
path: undefined,
host: undefined,
port: undefined,
localAddress: undefined
}
这是我的剧本:
// Usage: node file.js m.twitch.tv 443
const net = require("net");
const tls = require("tls");
const http2 = require("http2");
const crypto = require("crypto");
const host = process.argv[2];
const port = ~~process.argv[3];
const headers = {};
headers[":authority"] = host;
headers[":method"] = "GET";
headers[":path"] = "/";
headers[":scheme"] = "https";
headers["accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
headers["accept-language"] = "en-US,en;q=0.9";
headers["dnt"] = "1";
headers["sec-ch-ua"] = '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"';
headers["sec-ch-ua-mobile"] = "?0";
headers["sec-ch-ua-platform"] = '"Windows"';
headers["sec-fetch-dest"] = "document";
headers["sec-fetch-mode"] = "navigate";
headers["sec-fetch-site"] = "none";
headers["sec-fetch-user"] = "?1";
headers["upgrade-insecure-requests"] = "1";
headers["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.7.7895.91 Safari/537.36";
const socket = net.connect(port, host);
const tlsOptions = {
ALPNProtocols: ["h2"],
servername: host,
socket: socket,
};
const tlsConn = tls.connect(tlsOptions);
tlsConn.on("secureConnect", () => {
const client = http2.connect("https://" + host, {
createConnection: () => tlsConn
});
client.on("connect", () => {
let responseCode = 0;
const request = client.request(headers);
request.on("response", response => {
responseCode = response[":status"];
});
request.on("data", data => {
console.log(data.toString(), "\nResponse status: " + responseCode);
client.close();
});
});
})
使用 www.google 效果很好。
$ node file.js www.google 443
...
events:none;position:fixed;right:0;top:-80px;transition:opacity 0.218s,box-shadow 0.218s}.s2wfp .permission-bar-gradient{box-shadow:0 1px 80px #4285f4;opacity:1;pointer-events:none;animation:allow-alert .75s 0 infinite;animation-direction:alternate;animation-timing-function:ease-out;transition:opacity 0.218s,box-shadow 0.218s}@-webkit-keyframes allow-alert {from{opacity:1}to{opacity:.35}}\x3c/style\x3e\x3cdiv class\x3d\x22permission-bar-gradient\x22\x3e\x3c/div\x3e\x3c/div\x3e\x3c/div\x3e');})();(function(){google.drty&&google.drty(undefined,true);})();});google.drty&&google.drty(undefined,true);</script></body></html>
Response status: 200
但是对于 m.twitch.tv,程序退出时出现此错误。
$ node file.js m.twitch.tv 443
node:events:491
throw er; // Unhandled 'error' event
^
Error: Client network socket disconnected before secure TLS connection was established
at connResetException (node:internal/errors:717:14)
at TLSSocket.onConnectEnd (node:_tls_wrap:1595:19)
at TLSSocket.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Emitted 'error' event on TLSSocket instance at:
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'ECONNRESET',
path: undefined,
host: undefined,
port: undefined,
localAddress: undefined
}
回答如下:
twitch.tv,在撰写本文时,不支持 HTTP2。你可以用 cURL 检查:
curl -v -o /dev/null --http2 https://m.twitch.tv
请注意在协商 (*) 后的输出中您如何获得 HTTP1.1 响应。
Twitch 确实支持 HTTP3,但该协议与 HTTP2 有很大不同。服务器可能支持 HTTP1、2 和 3,但他们选择不支持。他们的目标受众可能都在使用现代浏览器,他们只支持 1 和 3 就可以了。
(*) 如果运行命令,您将获得以下输出:
# curl indicates that it understands these two protocols:
* ALPN: offers h2
* ALPN: offers http/1.1
...
# The server picks from this list:
* ALPN: server accepted http/1.1
...
# Response:
< HTTP/1.1 200 OK
与以下内容相反(此示例使用 google):
* ALPN: offers h2
* ALPN: offers http/1.1
...
* ALPN: server accepted h2
...
< HTTP/2 200
更多推荐
使用现有 TLS 套接字发送 HTTP/2 请求时出错
发布评论