Hello,

What you want to do is a forward proxy.
HAProxy is not able to do this and the coming DNS feature won't allow
it as well.

Why you want to switch from ATS to HAProxy since ATS can do this
easily out of the box?

If you know in advance the server IP address, then there is something
we can do using faked cookie persistence and a map.
It is much simpler than a lot of if/then/else in LUA.

Baptiste


On Tue, Jun 2, 2015 at 3:59 AM, Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote:
> Hello,
>
> Thanks for all your help. Any rough estimate on when the patch for doing DNS
> resolutions during runtime with asynchronous methods might be out?
>
> -Mrunmayi
>
>
>
> On Saturday, May 30, 2015 2:47 AM, Thierry FOURNIER <tfourn...@haproxy.com>
> wrote:
>
>
> On Sat, 30 May 2015 00:25:59 +0000 (UTC)
> Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote:
>
>> Hello Thierry,
>> This seems to be what we are looking for, however it doesn't seem to work
>> as expected. When we use your example as is, it seems to fail with a 500
>> error. When we switch to using a IP address, it works, so it seems like DNS
>> resolution is a problem?
>
>
> Yes, haproxy can not execute DNS résolutions while is running. It does
> DNS resolution only during the configuration parsing. Its because the
> standard DNS resolution are a synchronous process, and the HAProxy
> architecture does not accept synchronous processes.
>
> Note that a patch is currently in development for doing DNS resolutions
> during the runtime with asynchronous methods.
>
>
> As per this doc -
> http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#4-option%20http_proxy
>  http-proxy mode does not accept hostname, instead it only accepts IP.
>> The below example works:
>>   core.register_fetches("choose_backend", function(txn)     if
>> txn.sf.req_fhdr(Host) == 'example.test.com' and        txn.sf.req_path ==
>> '/test' then        return "1.1.1.1"     else if     [...]     end
>> return "default_backend"  end);
>> In the haproxy configuration file, you must load the lua file, and usethe
>> new declared fetch in your frontend:
>>   global     [...]     lua-load your-lua-file.lua     [...]
>>   listen your_frt     [...]      option http_proxy     http-request
>> set-uri http://%[lua.choose_backend]%[url]
>> We don’t want to have to specify the IP as that means that we will have to
>> perform some sort of dns resolution in lua. Can you suggest an alternative?
>
>
> Actually, you can use maps to do this. A map is a file containing a
> name and his correspondance. You can put a hostname and the associated
> ip.
>
> This map can be updated throught the HAProxy's socket (without
> restarting HAProxy). This is not a real DNS Resolution, you must kown
> the full list of your domains.
>
>
> Thierry
>
>
>>   Thanks!
>> -Mrunmayi
>>
>>
>>      On Wednesday, May 27, 2015 1:50 AM, Thierry FOURNIER
>> <tfourn...@haproxy.com> wrote:
>>
>>
>>  On Tue, 26 May 2015 21:39:23 +0000 (UTC)
>> Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote:
>>
>> > Thanks for your detailed reply Thierry. While this approach would solve
>> > the aspect of choosing the backend dynamically we still need to explicitly
>> > define each backend server separately in the haproxy config file. Our
>> > use-case involves having 100+ backends and we would prefer not to 
>> > complicate
>> > the config file by defining each backend server as it is not easy to
>> > maintain. We  prefer to set it based on incoming http request information
>> > like path or host header and keep haproxy config file simple with just
>> > listen and FE  directives and of course single default backend server
>>
>>
>> Hi,
>>
>> HAProxy does not permit to choose the destination IP and PORT.
>>
>> But, maybe I have an ugly solution to your problem.
>>
>> You can try to deal with the option "option http_proxy". This option
>> understand the base proxy requests.
>>
>> You create a "listen" section which use Lua for rewriting the path of
>> the HTTP request like this:
>>
>>    core.register_fetches("choose_backend", function(txn)
>>       if txn.sf.req_fhdr(Host) == 'example.test.com' and
>>         txn.sf.req_path == '/test' then
>>         return "test1. example.com:8081"
>>       else if
>>       [...]
>>       end
>>       return "default_backend"
>>    end);
>>
>> In the haproxy configuration file, you must load the lua file, and use
>> the new declared fetch inyour frontend:
>>
>>    global
>>       [...]
>>       lua-load your-lua-file.lua
>>       [...]
>>
>>    listen your_frt
>>       [...]
>>       option http_proxy
>>       http-request set-uri http://%[lua.choose_backend]%[url]
>>       [...]
>>
>> Thierry
>>
>>
>> > if (Host == aaa.example.com’ and path == ‘/test’) thenbackend server ==
>> > test1. example.com:8081  (Origin  port changed) elsif (Host ==
>> > aaa.example.com’ and path == ‘/test2’) backend server == test2.
>> > example.com:8080 (Origin  port changed) elsif (Host == aaa.example.com’ and
>> > path == ‘/test3’) backend server == xxx.example.com:9999 ((Origin  host and
>> > port changed)
>> >
>> > looking for something like the Traffic server lua api -
>> > https://docs.trafficserver.apache.org/en/latest/reference/plugins/ts_lua.en.html#ts-client-request-set-url-host
>> > Thanks,
>> > Mrunmayi
>> >
>> >
>> >
>> >      On Tuesday, May 26, 2015 3:15 AM, Thierry FOURNIER
>> > <tfourn...@haproxy.com> wrote:
>> >
>> >
>> >  On Fri, 22 May 2015 19:06:59 +0000 (UTC)
>> > Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote:
>> >
>> > > Hello,
>> > > I am using haproxy-1.6 with Lua. I have a use-case where I want to set
>> > > the destination (backend server) very dynamically, based on certain 
>> > > layer 7
>> > > information (I am trying to avoid updating haproxy configuration and 
>> > > make it
>> > > complicated with a ~100 domain names and their corresponding backend 
>> > > server
>> > > name and do a map lookup,  I want lua to do it  )
>> > > eg:  from lua, based on certain layer 7 information I want to change
>> > > the backend server (set destination) it should connect to..
>> > >  if Host is ‘example.test.com’; then backend is test1.server.com
>> > > elsif Host is ‘example2.test.com; then backend is test2.server.com    I 
>> > > want
>> > > to keep the haproxy config simple and have only the Listen directive 
>> > > listed
>> > > and take more control of the request flow from the LUA code.
>> > > The ATS traffic server does provide such functionality through the LUA
>> > > API hook to override backend server dynamically from Lua end
>> > >  if ts.client_request.header[Host] == 'example.test.com' then
>> > > ts.client_request.set_url_host(
>> > > test1.server.comts.client_request.set_url_port(80)elsif
>> > > ts.client_request.header[Host] == 'example2.test.com' then
>> > > ts.client_request.set_url_host( test2.server.com  )
>> > > ts.client_request.set_url_port(80)end
>> > > Is it possible to do the same using Haproxy and Lua?
>> >
>> >
>> > Hi,
>> >
>> > Yes, you can, but the way is a little bit different.
>> >
>> > You must create a new sample fetch in Lua. This fetch executes the
>> > analysis of your HTTP resuest and returns the backend name. The
>> > following code (untested) must set in a lua file:
>> >
>> >   core.register_fetches("choose_backend", function(txn)
>> >       if txn.sf.req_fhdr(Host) == 'example.test.com' then
>> >         return "backend1"
>> >       else if txn.sf.req_fhdr(Host) == 'other.domain.com' then
>> >         return "backend2"
>> >       [...]
>> >       end
>> >       return "default_backend"
>> >   end);
>> >
>> > In the haproxy configuration file, you must load the lua file, and use
>> > the new declared fetch inyour frontend:
>> >
>> >   global
>> >       [...]
>> >       lua-load your-lua-file.lua
>> >       [...]
>> >
>> >   frontend your_frt
>> >       [...]
>> >       use_backend %[lua.choose_backend]
>> >       [...]
>> >
>> > Note that your example code seem to choose a backend regarding only the
>> > header "host". In this case, the lua is useless, you can use the "maps"
>> > to choose your backend. The configuration looks like this:
>> >
>> >   frontend yur_frt
>> >       [...]
>> >       use_backend %[req.fhdr(host),tolower,map(host_to_bck.map,default)]
>> >       [...]
>> >
>> > The "default" argument is the name of the default backend. And the file
>> > "host_to_bck.map" contains a mapping between the hostnames (in lower
>> > case) and the backend names:
>> >
>> >   example.test.com  backend1
>> >   other.domain.com  backend2
>> >
>> >   etc...
>> >
>> > Thierry
>> >
>> >
>> > >
>> > > Thank you,
>> > > Mrunmayi
>> >
>> >
>>
>>
>>
>>
>
>
>

Reply via email to