Hi Tristan, Thanks for the *excellent* reply. Indeed, the map based solution can work for H1, however, our reason to migrate to HAproxy is adding gRPC compliance to the stack, so H2 support is a must. Thanks for the workarounds, indeed interesting, I'll check them out.
>trigger the GOAWAY H2 frames (which isn't possible at the moment, as far as I can tell) *Is this a valid feature request for HAProxy?* Maybe, we can provide "setting CLO mode" via the "http-request" directive? H1: https://sourcegraph.com/github.com/haproxy/haproxy/-/blob/src/mux_h1.c?L1185 H2: https://sourcegraph.com/github.com/haproxy/haproxy/-/blob/src/mux_h2.c?L4041 QUIC: https://sourcegraph.com/github.com/haproxy/haproxy/-/blob/src/mux_quic.c?L2181 It appears that there isn't a lot going on when we set a specific connection for CLO mode. Although, I definitely lack a holistic view of HAproxy around HTX. Excited to hear responses about this, thanks! Cheers, Abhijeet On Fri, May 5, 2023 at 7:06 AM Tristan <[email protected]> wrote: > > Hi Abhijeet, > > > Problem statement is, how do you drain a node [...] L7 constructs like > > "Connection: close" or "GOAWAY > > h2 frames" > > [...] > * For any map (L4 client IP lookup) based solution, I was unable to > > find any http-request operation that sets "drain mode". > > Indeed the managed drain mode is an all-or-nothing at the moment. The > "only" missing feature to fully replicate it with http-request rules > would be a way to trigger the GOAWAY H2 frames (which isn't possible at > the moment, as far as I can tell). > > But in the meantime, the following might do the job: > > frontend foo > # tcp-request connection sees the "real" src in accept-proxy > listeners, according to 7.3.3#src > tcp-request connection set-var(txn.src_l4_ip) src > > # assuming a stick-table here, but should work just fine with > maps/lists too > http-after-response set-header Connection close if { > var(txn.src_l4_ip),in_table(draining-clients) } > > At that point we have the HTTP/1.1 part handled but that was easy > enough... Now for H2 there's no good way that I can see. > > But I can think of a few hacky solutions that might work (ie would need > to test them in practice): > 1. Returning an HTTP 421, which H2 clients should interpret as being > instructed to use a different connection to issue the request, which > should also be automatically retried in browsers > 2. Adding an Alt-Svc to those responses advertising http/1.1 explicitly, > which clients should pick up and prefer (then they either land on > another LB while establishing the new connection, or get Connection-close'd) > 3. Returning an HTTP 426, instructing the client to "upgrade" to > http/1.1 (not sure how that interacts with ALPN but the spec seems to > suggest that the client would give the upgrade request priority), which > ends up with the same outcome as the Alt-Svc solution if it works > > Of course it'd be many times better to be able to just trigger a GOAWAY > instead, but it was fun to think about more "creative" options, so here > they are. > > Tristan > -- Cheers, Abhijeet (https://abhi.host)

