The CONNECT method is used to allow an HTTP/2 server to be used as a proxy
for TCP/IP connections.
A simple TCP Server:
const net = require('net');const server = net.createServer((socket) => {let name = '';socket.setEncoding('utf8');socket.on('data', (chunk) => name += chunk);socket.on('end', () => socket.end(`hello ${name}`));});server.listen(8000);
An HTTP/2 CONNECT proxy:
const http2 = require('http2');const { NGHTTP2_REFUSED_STREAM } = http2.constants;const net = require('net');const proxy = http2.createServer();proxy.on('stream', (stream, headers) => {if (headers[':method'] !== 'CONNECT') {// Only accept CONNECT requestsstream.close(NGHTTP2_REFUSED_STREAM);return;}const auth = new URL(`tcp://${headers[':authority']}`);// It's a very good idea to verify that hostname and port are// things this proxy should be connecting to.const socket = net.connect(auth.port, auth.hostname, () => {stream.respond();socket.pipe(stream);stream.pipe(socket);});socket.on('error', (error) => {stream.close(http2.constants.NGHTTP2_CONNECT_ERROR);});});proxy.listen(8001);
An HTTP/2 CONNECT client:
const http2 = require('http2');const client = http2.connect('http://localhost:8001');// Must not specify the ':path' and ':scheme' headers// for CONNECT requests or an error will be thrown.const req = client.request({':method': 'CONNECT',':authority': `localhost:${port}`});req.on('response', (headers) => {console.log(headers[http2.constants.HTTP2_HEADER_STATUS]);});let data = '';req.setEncoding('utf8');req.on('data', (chunk) => data += chunk);req.on('end', () => {console.log(`The server says: ${data}`);client.close();});req.end('Jane');
