Как прокси-запрос к h2c HTTP / 2 серверу с сокетами? - PullRequest
0 голосов
/ 05 июля 2018

Это должно быть простой проблемой, но мои знания о потоках ограничены.

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));

Ответы [ 2 ]

0 голосов
/ 11 июля 2018

Наконец-то , прокси от 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));
0 голосов
/ 10 июля 2018

Я не эксперт по узлам, и я, возможно, совершенно не понял, что вы пытаетесь сделать здесь, но я действительно изо всех сил пытаюсь разобраться в этом вопросе ...

Если вы пытаетесь заставить Node выступать в качестве прокси-сервера HTTP / 2 (чтобы клиент мог подключиться через h2c к узлу и передавал эти данные другому серверу, поддерживающему 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. Таким образом, каждому пакету должен быть присвоен уникальный идентификатор потока, и многие другие параметры должны быть согласованы между двумя конечными точками. Поэтому предположить, что одно сообщение HTTP / 2 будет беспрепятственно преобразовано в идентичное сообщение HTTP / 2 в другом соединении HTTP / 2, крайне наивно! Возвращаясь к аналогии с языком, копирование немецких сообщений дословно другому носителю немецкого языка, который, возможно, плохо слышит, но сидит ближе к вам, может сработать изначально, но как только один конец не успевает, говорит на несколько ином диалекте или просит вас Повторите что-то, что они пропустили, все шоу рушится.

Я бы посоветовал вам либо сделать этот прокси-сервер уровня 4 (поэтому игнорируйте HTTP и HTTP / 2 и просто использовать сокеты), либо вы хотите, чтобы это был прокси-сервер HTTP (в этом случае принимайте каждое сообщение HTTP, читайте его, и отправьте аналогичное сообщение HTTP по нисходящему соединению). Вы не можете иметь оба.

Я бы также спросил, почему и если вам нужно это сделать? HTTP / 2 не поддерживается повсеместно и получает большую часть своей выгоды между клиентом и пограничным сервером (в данном случае прокси), так почему вы чувствуете необходимость говорить по HTTP / 2 все время? См. Этот вопрос для более подробной информации: HTTP / 2 за обратным прокси

Надеюсь, это поможет и принесет извинения, если я полностью неправильно понял ваш вопрос или ваше намерение!

...