这肯定是一个简单的问题,但是我对流的了解有限。
HTTP / 1 80到HTTP / 2 h2c代理
脚本(不起作用):
const net = require('net');
const http = require('http');
const http2 = require('http2');
const socketPath = `/tmp/socket.test.${Date.now()}`;
// front http 80 server.
http.createServer((req, res) => {
const socket = net.createConnection(socketPath)
req.pipe(socket).pipe(res);
}).listen(80);
// private http2 socket server.
http2.createServer(function(socket) {
socket.write(`Echo from http2 server\r\n`);
socket.pipe(socket);
}).listen(socketPath);
HTTP / 2 h2c到HTTP / 2 h2c代理
cli命令开始请求:
curl --http2-prior-knowledge -v http://localhost:3333/ --output -
脚本(不起作用):
const net = require('net');
const http = require('http');
const http2 = require('http2');
const socketPath = `/tmp/socket.test.${Date.now()}`;
const port = 3333;
const private = http2.createServer({allowHTTP1: true});
private.on('stream', (stream, headers) => {
console.log('private http2 request');
stream.end('HTTP/2');
});
private.listen(socketPath, () => console.log('private http2 server is listening', socketPath));
const public = http2.createServer({allowHTTP1: true});
public.on('stream', (stream, headers) => {
console.log('public http2 request');
const socket = net.connect(socketPath);
stream.pipe(socket).pipe(stream);
});
public.listen(port, () => console.log('public http2 server is listening port', port));
答案 0 :(得分:2)
最后,http2(h2c)到http2(h2c)(带有unix套接字)代理有效!
const net = require('net');
const http2 = require('http2');
const socketPath = `/tmp/socket.test.${Date.now()}`;
const port = 4444;
const priv = http2.createServer({});
priv.on('stream', (stream, headers) => {
console.log('private http2 request');
stream.end('HTTP/2');
});
priv.listen(socketPath, () => console.log('private http2 server is listening', socketPath));
const pub = http2.createServer({});
pub.on('stream', (stream, headers) => {
const clientSession = http2.connect('http://0.0.0.0', {
createConnection: () => net.connect({path: socketPath})
});
const req = clientSession.request({
':path': `/`,
});
req.pipe(stream).pipe(req);
});
pub.listen(port, () => console.log('public http2 server is listening port', port));
答案 1 :(得分:0)
我不是节点专家,我可能完全误解了您在这里要做什么,但是我真的很难理解这个问题...
如果您试图让Node充当HTTP / 2代理(因此客户端可以通过h2c连接到node并将其详细信息传递给另一台HTTP / 2感知的服务器),那么您的处理方式似乎……至少可以说很奇怪。
代理可以是4级代理(例如TCP代理),在其中创建两个TCP单独的连接(一个从客户端到代理,一个从代理到目标服务器),并在它们之间发送这些TCP数据包的连接除了TCP标头以外,没有真正检查或干扰它们。
替代代理可以是7级代理(例如HTTP代理),它在其中创建两个单独的HTTP连接(一个从客户端到代理,一个从代理到目标服务器),并在它们之间发送HTTP消息,将HTTP标头和它们之间的详细信息,有时会更改详细信息甚至添加更多标头(例如X-FORWARDED-FOR)。
您似乎正在尝试在这两种不同且不兼容的工作模式之间建立某种混合!您希望创建一个HTTP或HTTP / 2服务器,然后打开一个TCP套接字,并在它们之间传递这些TCP消息,并希望它能起作用?尽管这可能可以通过简单的协议(例如HTTP / 1)工作,但永远不会通过HTTP / 2进行工作!
对于您的第一个示例,HTTP / 1实例与HTTP / 2完全不同。因此,从一开始就设置这两个并期望它们能够工作是有缺陷的。如果您的一个朋友只讲德语,另一个朋友只讲西班牙语,并且您将所有德语信息逐字地,未经过滤地传递给了说西班牙语的人,那么您希望说西班牙语的人能够神奇地理解它们吗?当然不是!因此,您无法在套接字级别连接HTTP / 1和HTTP / 2-它们是完全不同的协议。您需要您的代理充当他们之间的翻译者。
在您的第二个示例中,我更加困惑。我猜您正在尝试创建两个HTTP / 2服务器,并让客户端连接到一个,然后将请求代理到另一个?大概您会在某个阶段在其中添加一些逻辑,这样只有某些请求才能通过,否则这将毫无意义。无论如何,这几乎肯定是行不通的。 HTTP / 2是一个复杂的协议,在许多方面都类似于TCP。因此,需要为每个数据包指定唯一的流ID,并且需要在两个端点之间协商许多其他设置。因此,假设一个HTTP / 2消息将无缝转换为另一个HTTP / 2连接上的相同HTTP / 2消息是非常幼稚的!回到语言的比喻,将德语信息原样复制到另一位德语听众,他可能听不清但坐在您身边,可能最初可以工作,但是一旦听不清,说方言稍有不同,或要求您重复他们错过的事情,整个节目就倒塌了。
我建议您要么将其设置为4级代理(因此忽略HTTP和HTTP / 2,仅使用套接字),要么将其作为HTTP代理(在这种情况下,请提取每条HTTP消息,然后阅读它,并在下游连接上发送类似的HTTP消息)。不能同时拥有。
我还要质疑为什么以及是否需要这样做? HTTP / 2不被普遍支持,它在客户端和边缘服务器(在本例中为代理)之间获得了大部分收益,那么为什么您会觉得需要一直使用HTTP / 2?有关此问题的更多详细信息,请参见此问题:HTTP/2 behind reverse proxy
如果我完全误解了您的问题或意图,希望能对您有所帮助并道歉!