Hi again,

I'm trying to see if I can fix this issue.

As I stated before changing the destination on the fly seems supported
at least in relay_match as it changes the con->table which is used to
select a destination host on relay_connect. But currently relay_connect
is not called after relay_match so relayd keep using the same
destination host.

Looking at relay_http.c it seems like a possible fix would be to force
close cre->dst from relay_match so that relay_connect is called again
within the relay_read_http.

Nevertheless it's clearly stated that relay_connect should be called
once per relay, but doing so would force to close the current relay and
so we would lose the current http connection.

Do you consider such a fix viable ?

Regards,


On Sun, Apr 03, 2016 at 05:31:29PM +0200, Paul Fariello wrote:
> Oops, seems like I fails something with sendbug. First time, sorry.
> Anyway I'm the author of the previous bug report.
> 
> I've already posted this on misc@ but since there was no response I
> follow reyk@ advice to post it here. Hope it's the right place.
> 
> >>Category:   system
> >>Environment:
> >     System      : OpenBSD 5.7
> >     Details     : OpenBSD 5.7 (GENERIC) #738: Sun Mar  8 10:59:31 MDT 2015
> >                      
> > [email protected]:/usr/src/sys/arch/i386/compile/GENERIC
> >
> >     Architecture: OpenBSD.i386
> >     Machine     : i386
> >>Description:
> >     I'm trying to relay an http connection to differents destination based
> >     on url filtering. It works great but since url used for filtering are on
> >     the same domain, browser tends to use a persistent connection:
> >     "Connection: keep-alive".
> >
> >     Relayd seems to keep using the first match destination even when
> >     http request match the second one.
> >>How-To-Repeat:
> >     Relayd conf:
> >
> >     table <srv1> { 127.0.0.1 }
> >     table <srv2> { 127.0.0.1 }
> >
> >     http protocol "httpfilter" {
> >             return error
> >             match url "localhost:8080/" forward to <srv1>
> >             match url "localhost:8080/api/" forward to <srv2>
> >     }
> >
> >     relay www {
> >             listen on 127.0.0.1 port 8080
> >             protocol httpfilter
> >
> >             forward to <srv1> port 8081 check tcp
> >             forward to <srv2> port 8082 check tcp
> >     }
> >
> >     httpd conf to really handle http request. Obviously in a real use case
> >     the goal is to serve part of the content with httpd and the rest with
> >     some other webserver.
> >
> >     server "localhost" {
> >             listen on 127.0.0.1 port 8081
> >
> >             root "/htdocs/localhost"
> >     }
> >
> >     server "localhost" {
> >             listen on 127.0.0.1 port 8082
> >
> >             root "/htdocs/localhost-api"
> >     }
> >
> >     Create some test file to serve:
> >     echo "localhost" > /var/www/htdocs/localhost/index.html
> >     echo "localhost api" > /var/www/htdocs/localhost-api/api/index.html
> >
> >     Finally reproduce with:
> >     $ curl http://localhost:8080/
> >     localhost
> >
> >     which produce:
> >     relay www, session 1 (1 active), 0, 127.0.0.1 -> 127.0.0.1:8081, done, 
> > GET
> >
> >     $ curl http://localhost:8080/api/
> >     localhost api
> >
> >     which produce:
> >     relay www, session 1 (1 active), 0, 127.0.0.1 -> 127.0.0.1:8082, done, 
> > GET
> >
> >     and finally:
> >     curl http://localhost:8080 http://localhost:8080/api/
> >     localhost
> >     <404 error from httpd>
> >
> >     which produce:
> >     relay www, session 2 (1 active), 0, 127.0.0.1 -> 127.0.0.1:8081, last 
> > write (done), GET GET
> >
> >>Fix:
> >     My current work around is to force connection close with:
> >     header set "Connection" value "close"
> >
> >     Giving a look at relayd source code I suppose that this scenario is
> >     known. In relay_http.c, int relay_match_actions(); relayd is changing
> >     the destination table with the one from the matched rule but it doesn't
> >     use the corresponding fd when relaying.
> 
> -- 
> Paul Fariello
> 

-- 
Paul Fariello

Reply via email to