Skip to content
This repository

How to conditionally proxy request? #167

Closed
jch opened this Issue December 12, 2011 · 4 comments

4 participants

Jerry Cheung Ben Ben Buckman Christian Howe
Jerry Cheung

I'd like to proxy requests to an API backend if the Accept header matches a certain regex. If it doesn't match, no proxying is done and instead a static page is served with Connect's static middleware. I saw that createServer allows me to either pass in middleware, or to pass in a function to modify before proxying, but I don't see how to conditionally proxy based on request attributes.

How would one go about writing this? In pseudocode, I'd want something like:

httpProxy.createServer(function (req, res, proxy) {
  if req.headers['Accept'].match(/custom_api_accept/) {
    //... modify the request before sending it off to the target
    proxy.proxyRequest(req, res, {host: api.host, port: api.port});
    // respond with the target's response
  } else {
    // if Accept doesn't match, then we serve some static assets
    var connect = require('connect');
    var app = connect();
    app.use(connect.static(__dirname + '/public'));
  });
}).listen(8000);
Ben

I did something similar, but based on a url. First i tried it with the static middleware before using the proxy, but it didn't work out the way i wanted.

At the end i moved the static part to another connect server instance and proxied to it when my criterias matched. In your case i would do something like that:

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

httpProxy.createServer(function (req, res, proxy) {
  if req.headers['Accept'].match(/custom_api_accept/) {
    var options = {
      host: 'apiserver',
      port: 8080
    }
  } else {
    var options = {
      host: 'localhost',
      port: 8080
    }
  }

  proxy.proxyRequest(req, res, options);
}).listen(8000);

connect(
  connect.static(__dirname + '/public')
).listen(8080);

Didn't test it, but it should give you a hint :)

Ben Buckman

I'd like to use a URL approach also: handle requests to certain URLs with the primary app, but proxy certain URLs to a separate app. It seems from the examples that the components to do all this exist, but I can't get them to work together. Creating a 3rd server seems redundant... does anyone know another way? Thanks!

Christian Howe

@jch does your example not work for you? If you don't call next in your middleware, it won't pass it on to the default handler anyways (next is a function passed into the third parameter in the middleware).

Jerry Cheung
jch commented March 30, 2012

@CodeRarity I ended up with a different architecture, so I no longer needed to proxy requests. It was more trouble than it was worth, so now I have my API and static web endpoints mounted together at the same place.

Jerry Cheung jch closed this March 30, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.