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
