Node Http Proxy - basic reverse proxy doesn't work (404s)
Asked Answered
O

2

5

I'm trying to get a very simple proxy working with node-http-proxy which I would expect to just return the contents of google:

const http = require('http');
const httpProxy = require('http-proxy');

const targetUrl = 'http://www.google.co.uk';

const proxy = httpProxy.createProxyServer({
    target: targetUrl
});

http.createServer(function (req, res) {

    proxy.web(req, res);

}).listen(6622);

For example I would expect http://localhost:6622/images/nav_logo242.png to proxy to http://www.google.co.uk/images/nav_logo242.png instead of returning a 404 not found.

Thanks.

Olvera answered 19/2, 2016 at 15:39 Comment(0)
G
7

You need to set the Host header of your request

const http = require('http');
const httpProxy = require('http-proxy');

const targetHost = 'www.google.co.uk';

const proxy = httpProxy.createProxyServer({
    target: 'http://' + targetHost
});

http.createServer(function (req, res) {
    proxy.web(req, res);

}).listen(6622);

proxy.on('proxyReq', function(proxyReq, req, res, options) {
    proxyReq.setHeader('Host', targetHost);
});

Inside an express app it's probably easier to use express-http-proxy when proxying some of the requests.

const proxy = require('express-http-proxy');
app.use('*', proxy('www.google.co.uk', {
  forwardPath: function(req, res) {
    return url.parse(req.originalUrl).path;
  }
}));
Guildsman answered 19/2, 2016 at 20:16 Comment(4)
This does looks a lot easier thanks - I want https and possibly even websockets down the line though so I'll keep investigatingOlvera
Note that in your example you sat up a local proxy. Connect to it and send GET http://www.google.co.uk/images/nav_logo242.png HTTP/1.0, and it returns the correct file. So your setup was not right for a reverse proxy as you wanted to set up.Guildsman
Yeah good point, I reduced it even more and it doesn't work. Posted an issue on their github to see if I can expedite an answerOlvera
GENIUS! I had tried the Host header but thoughtlessly had http:// on it - thanks!Olvera
P
8

Set http-proxy option changeOrigin to true and it will set the host header in the requests automatically.

Vhosted sites rely on this host header to work correctly.

const proxy = httpProxy.createProxyServer({
    target: targetUrl,
    changeOrigin: true
});

As an alternative to express-http-proxy, you could try http-proxy-middleware. It has support for https and websockets.

const proxy = require('http-proxy-middleware');

app.use('*', proxy({
   target: 'http://www.google.co.uk',
   changeOrigin: true,
   ws: true
}));
Patron answered 24/4, 2016 at 17:43 Comment(0)
G
7

You need to set the Host header of your request

const http = require('http');
const httpProxy = require('http-proxy');

const targetHost = 'www.google.co.uk';

const proxy = httpProxy.createProxyServer({
    target: 'http://' + targetHost
});

http.createServer(function (req, res) {
    proxy.web(req, res);

}).listen(6622);

proxy.on('proxyReq', function(proxyReq, req, res, options) {
    proxyReq.setHeader('Host', targetHost);
});

Inside an express app it's probably easier to use express-http-proxy when proxying some of the requests.

const proxy = require('express-http-proxy');
app.use('*', proxy('www.google.co.uk', {
  forwardPath: function(req, res) {
    return url.parse(req.originalUrl).path;
  }
}));
Guildsman answered 19/2, 2016 at 20:16 Comment(4)
This does looks a lot easier thanks - I want https and possibly even websockets down the line though so I'll keep investigatingOlvera
Note that in your example you sat up a local proxy. Connect to it and send GET http://www.google.co.uk/images/nav_logo242.png HTTP/1.0, and it returns the correct file. So your setup was not right for a reverse proxy as you wanted to set up.Guildsman
Yeah good point, I reduced it even more and it doesn't work. Posted an issue on their github to see if I can expedite an answerOlvera
GENIUS! I had tried the Host header but thoughtlessly had http:// on it - thanks!Olvera

© 2022 - 2024 — McMap. All rights reserved.