nxtedition/node-http2-proxy

Adding "http2 to http2" proxy functions for proxy servers is now much easier.

masx200 opened this issue · 8 comments

Adding "http2 to http2" proxy functions for proxy servers is now much easier.

The following modules that support http2 can be used.

https://github.com/hisco/http2-client

https://github.com/spdy-http2/node-spdy

https://github.com/grantila/fetch-h2

https://github.com/szmarczak/http2-wrapper

ronag commented

fixed in e0b9324

const http = require('http');
const proxy = require('http2-proxy');
const http2 = require('http2-wrapper');

const server = http.createServer();

const defaultWebHandler = (error, request, response) => {
	if (error) {
		console.error(error);

		response.statusCode = 500;
		response.end(error.stack);
	}
};

server.listen(8000, error => {
	if (error) {
		throw error;
	}

	server.on('request', (req, res) => {
		proxy.web(req, res, {
			hostname: 'example.com',
			port: 443,
			onReq: (request, options) => {
				return http2.request(options, response => {
					const {headers} = response;

					// `http2-proxy` doesn't automatically remove pseudo-headers
					for (const name in headers) {
						if (name.startsWith(':')) {
							delete headers[name];
						}
					}
				});
			}
		}, defaultWebHandler);
	});

	console.log(`Listening on port ${server.address().port}`);
});

It doesn't work unless you add .end() to http2.request(...). Is this on purpose?

ronag commented

It doesn't work unless you add .end() to http2.request(...). Is this on purpose?

No. end() is called inside onProxyConnect. It might be that http2.request doesn't implement the flow:

req.'socket' => socket.'connect' => onProxyConnect.

You're right. There's no connect event on the socket. I think I know how to fix this. Thanks for pointing out :)

There's no connect event because it's already connected. I think that http2-proxy doesn't cover this edge-case. Hmm, it does.

Wait... For some reason it doesn't emit the socket event at all. Welp.

Oh, it doesn't emit the socket event because the wrapper waits for the first write / end.

ronag commented

Oh, it doesn't emit the socket event because it waits for the first write / end.

The whole purpose here is that we don't read/write until we know we have successfully connected, so that we can safely retry requests that contain a stream body.