Skip to content

Race in ESI sub-request failure mitigation #3865

@bsdphk

Description

@bsdphk

The s390 vtester exposed a race in handling of failing sub-requests, if the request fails fast enough, we send the response, for instance a 503, to the client.

On the s390, different thread scheduling makes the if (req->objcore->flags & OC_F_FAILED) test in cnt_fetch() true, sends the request to vcl_error, and esi_deliver.c just spits out that 503.

But it seems that the problem is deeper than that, as shown by this VTC, a variation of e00035 where the errors are generated internal to Varnish instead of by the backend:

varnishtest "ESI fragment fetch fail"

server s1 {
        rxreq
        expect req.url == "/abort"
        txresp -hdr {surrogate-control: content="ESI/1.0"} \
            -body {before <esi:include src="/fail"/> after}

} -start

varnish v1 -cliok "param.set feature +esi_disable_xml_check"
varnish v1 -cliok "param.set feature +esi_include_onerror"
varnish v1 -vcl+backend {
        sub vcl_backend_fetch {
                if (bereq.url == "/fail") {
                        return (error(503));
                }
        }
        sub vcl_backend_response {
                set beresp.do_esi = beresp.http.surrogate-control ~ "ESI/1.0";
                unset beresp.http.surrogate-control;
        }
} -start

client c1 {
        txreq -url "/abort"
        non_fatal
        rxresp
        expect resp.body == "before "
} -run

server s1 -wait

server s1 {
        rxreq
        expect req.url == "/continue"
        txresp -hdr {surrogate-control: content="ESI/1.0"} \
            -body {before <esi:include src="/fail" onerror="continue"/> after}

} -start

client c1 {
        fatal
        txreq -url "/continue"
        rxresp
        expect resp.body == "before  after"
} -run

It guess esi_deliver needs to scrutinize resp->status and only accept 200 ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions