Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to do 301 Redirects #37

Closed
emotely opened this issue Apr 24, 2011 · 17 comments
Closed

How to do 301 Redirects #37

emotely opened this issue Apr 24, 2011 · 17 comments

Comments

@emotely
Copy link

emotely commented Apr 24, 2011

I'm trying to remove the www. requests to point them to the canonical non www. urls. This is the make sure copy pasted urls point to one domain and thus not divide up my Google Page Rank juice across the two domains.

@indexzero
Copy link
Contributor

node-http-proxy doesn't support 301 redirects yet, but I will leave this issue as this is something we want to address in future versions.

@emotely
Copy link
Author

emotely commented Apr 24, 2011

Thanks for the quick answer. I guess I could put the redirect logic into the actual server that the domain is served on. I'll post my solution to that when I get it working. It will help those that have the same issue.

@seflless
Copy link

For reference here's the solution I ended up using. Note: I'm using express so it's express specific code:

app.configure(function(){
  // Forward www.emotely.com to emotely.com
  app.use(function(req,res,next){
    if(req.headers.host=="www.emotely.com"){
      res.writeHead(301, {'Location':'http://emotely.com'+req.url, 'Expires': (new Date).toGMTString()});
      res.end();
    }
    else{
      next();
    }
  });
});

@yesidays
Copy link

But what happens if i don't know the URL redirect? thanks

@DaleLJefferson
Copy link

Now http-proxy supports connect middleware you can use no-www

var http = require('http'),
httpProxy = require('http-proxy');

var options = {
hostnameOnly: true,
router: {
'example.com': '127.0.0.1:8001'
}
}

var proxyServer = httpProxy.createServer(
require('connect-no-www')(false),
options
);

proxyServer.listen(80);

@konklone
Copy link

I got this working, here's my code, inserted in the middle of the boilerplate http+websockets example:
https://gist.github.com/konklone/5006662

@pajtai
Copy link

pajtai commented Jun 18, 2014

here's a generic one - modified from @francoislaberge example - I use as the first piece of middleware in my express app:

express.use(function(req,res,next){
        var host = req.get('host');
        if(/^www\./.test(host)){
            host = host.substring(4, host.length);
            res.writeHead(301, {'Location':req.protocol + '://' + host + req.originalUrl,
                'Expires': new Date().toGMTString()});
            res.end();
        } else {
            next();
        }
    });

You could reverse it just as easily making sure that host always starts with www.

@q2dg
Copy link

q2dg commented Aug 18, 2014

Http-proxy doesn't still support 301 Redirects??
So...this code won't redirect to Google, really??

var url = require("url")
var http = require("http")
var httpProxy = require("http-proxy")
var proxy = httpProxy.createProxyServer()
http.createServer(function(req, res) {
proxy.web(req, res, { target: "http://www.google.com", headers: { host: "www.google.com"} })
}).listen(4000)

I don't find very useful a proxy like this, sincerely.
But thanks for your work

@jcrugzz
Copy link
Contributor

jcrugzz commented Aug 18, 2014

@q2dg i think you are mistaking terminology. Your code correctly proxies any request to the server to google.com. This is not the same as redirecting to google as the traffic is still going through your server.

@q2dg
Copy link

q2dg commented Aug 18, 2014

Well, maybe I haven't stated the problem incorrectly, sorry.

If you try my above code (having configured proxy settings in a browser pointing to it) you will see it doesn't work: browser shows a "restarted connection" error. But if you change "www.google.com" by another URL which doesn't suffer from redirection (for instance, "www.linux.com"), it does work (withouth changing browser's direction bar, but it doesn't matter). At least, this is what happens in Spain, where "www.google.com" is automatically redirected to "www.google.es".

It's the only explanation I have: http-proxy doesn't handle 3xx responses, like official http.get() method either. But, of course, I can be wrong.

@jcrugzz
Copy link
Contributor

jcrugzz commented Aug 19, 2014

@q2dg ok well this does seem plausible. This is something that should be handled in some manner. If you can come up with a good failing test case (integrated into the actual tests) I can take a stab at implementing it

@q2dg
Copy link

q2dg commented Aug 21, 2014

Ok, I will try. Thanks!!

@kadishmal
Copy link

+1 to add redirection support. We could have the following simple format to indicate whether the request should be redirected to proxies.

proxy: {
    router: {
        // This is what http-proxy already supports, i.e. proxying.
        'domain.com': 'http://127.0.0.1:10088',
        // To support redirect we could provide an object:
        'domain2.com': {
            redirect_host: 'http://domain.com'
        }
    }
}

If the http-proxy notices the redirect_host property, then it will redirect instead of proxying.

@Rush
Copy link
Contributor

Rush commented Oct 30, 2014

I think this is scope of a different project. In fact http-master is a module which tries to do intelligent things around the http-proxy, including redirects and serving a static file directory.

@kadishmal
Copy link

I have just implemented the redirection as follows without changing a code in http-proxy.

proxy: {
    router: {
        // This is what http-proxy already supports, i.e. proxying.
        'domain.com': 'http://127.0.0.1:10088',
        // To support redirect we could provide an object:
        'domain2.com': {
            redirect_host: 'http://domain.com',
            // `307` status code indicates that the request
            // should be repeated using the same method and post data
            // and that the redirection is temporary. The future
            // requests should still use the original URI.
            // In contrast to how 302 was historically implemented,
            // the request method is not allowed to be changed when
            // reissuing the original request. For instance, a POST
            // request should be repeated using another POST request.
            // `308` status code indicates that the request
            // should be repeated using the same method and post data
            // and that the redirection is permanent unlike `307`.
            status: 308
        }
    }
}

Then in the app.js code I have the following:

server = http.createServer(function (req, res) {
    var host = req.headers.host,
            ix = host.indexOf(':' + conf.port);

    // In case hosts include the port as well like `:80`.
    ~ix && (host = host.substring(0, ix));

    if (proxy.router.hasOwnProperty(host)) {
        host = proxy.router[host];

        if (typeof host == 'object' && host.redirect_host) {
            res.writeHead(host.status || 308, {
                Location: host.redirect_host + req.url
            });

            res.end();
        } else {
            proxy.web(req, res, {
                target: host
            });
        }
    } else {
        res.writeHead(404, {
            'Content-Type': 'text/plain'
        });

        res.end('No server is listening for this domain.');
    }
});

Comments are welcome.

@jcrugzz
Copy link
Contributor

jcrugzz commented Oct 30, 2015

This should technically be supported with https://github.com/nodejitsu/node-http-proxy/blob/master/lib/http-proxy/passes/web-outgoing.js#L49-L70. If not please open a new issue.

@jcrugzz jcrugzz closed this as completed Oct 30, 2015
@SukantGujar
Copy link

How about support for autoProtocolRewrite, as the option protocolRewrite doesn't look at the request protocol to rewrite location returned from the target proxy. So if if I want to support both https and http on my entry site, the only option right now is to write a custom proxyRes handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests