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

Custom resolver, host and url rewriting #61

Open
ArnaudParant opened this issue Aug 2, 2016 · 6 comments
Open

Custom resolver, host and url rewriting #61

ArnaudParant opened this issue Aug 2, 2016 · 6 comments

Comments

@ArnaudParant
Copy link

ArnaudParant commented Aug 2, 2016

Hello,

I would like to defined a custom resolver to wildcard domain routing and do some redirection.

Configuration

{
    "proxy": {
        "redirections": [
            {"from":"/foo","to":"something:9100"},
            {"from":"/bar","to":"anotherapi:9102"},
        ]
    }
}

Code

function custom_resolver(host, url)
{
  var redirections = conf.proxy.redirections

  for (var i in redirections)
  {
    var red = redirections[i];
    var start = new RegExp("^"+ red.from)
    if (start.test(url))
    {
      var rhost = "http://"+ red.to;
      var rurl = url.replace(start, "")
      return rhost + rurl;
    }
  }

};

But custom revoler only return host i guess ? So I can not "rewrite" the url.
The above code does not work as expected:
10.0.0.42/foo/folder -> http://something:9100/folder/foo/folder
Because I it return http://something:9100/folder and the original url is added at the end /foo/folder

However it is possible to "rewrite" the url with proxy.register, but not the host.
proxy.register("10.0.0.42/foo", "http://something:9100")
It do the url "rewriting" but only works when we access to 10.0.0.42, if there is another ip to connect the server, like 172.17.0.5, it does not works.

Is there any way to do this ? Did I miss something ? May be I have to return from custom_resolver another type, like an object, (an array does not works) ? Is there a maner to combine the both solution ?

King regards,
Arnaud

@manast
Copy link
Member

manast commented Aug 2, 2016

Did you try to return an object with url (the target host), and path 'folder' ?

@ArnaudParant
Copy link
Author

Hi, Actually, no, I didn't.

original return rhost + rurl
new return {url:rhost, path:rurl}

request url 10.0.0.60/foo/collections
resolved url (by my custom resolver)
host http://something:9100
url /collections

I getting the following message from the proxy

{"name":"redbird","hostname":"38b1c9cc8e81","pid":1,"level":40,"src":"10.0.0.60","url":"/foo/collections","msg":"no valid route found for given source","time":"2016-08-04T13:42:11.543Z","v":0}
  • I m not sure if the url field (the target host), must start with protocol, such "http://". I tried with and without, it changed nothing.
  • Same for the path, I tried, starting by / and not, it changed nothing as well.

@ArnaudParant
Copy link
Author

ArnaudParant commented Aug 4, 2016

After a quick look to the code: https://github.com/OptimalBits/redbird/blob/master/lib/proxy.js

The error came from _getTarget, line 448:
this.log && this.log.warn({src: src, url: req.url}, 'no valid route found for given source');

Which is due, I think, of the return condition from resolve, line 401:
startsWith(url, route.path)
I don't really understand this condition, the request url must start with the routing path ?

There is also in line 472 and 475 from _getTarget function:

// Fix request url if targetname specified.
req.url = path.join(target.pathname, req.url);

Which I think, does not allow to do what I want any way, rewrite the url and the path in the same time ?

@manast
Copy link
Member

manast commented Aug 5, 2016

I will have to look deeper into it, but if it is not possible to do it then we need to rethink the custom resolvers design.

@guilhermeaiolfi
Copy link

Is this limitation still valid? I'm evaluating reverse proxies and that's something I would need. Overall, GREAT project!

@backrunner
Copy link

backrunner@7ae14a9
↑ I just made this commit in my fork.

In the _getTarget method, req.url will always be added after target.pathname when req.url exists, so if you want to rewrite a URL, you can add a specific flag to the route object (i.e. the object returned in the buildRoute method) like my modification.

In my modification, if the custom resolver return a object that contains a property named rewriteTo, in the buildRoute method, the value will be passed to route.url, and a flag named isRewrite will be added to the routeObject. Then in the _getTarget method, when the flag exists, I use the target.pathname directly. The modification can perform a URL Rewriting well.

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

4 participants