Re: Suspected ambiguity in H1 around Expect: 100-continue

Actually this specific gotcha did come up a while ago with hyper and curl.
As I read our comments again, we identified the same ambiguity.
Specifically how a client should retry without the header, but skipping
sending the body, on the same connection.
https://github.com/hyperium/hyper/issues/2791

hyper still decided that as long as there was a content-length header, the
payload is either expected or a conn should be closed. (In my mind, it
could be request smuggling to treat it as a new request.)

I don't know if curl treats it differently.

But yes, the confusion has happened before.

On Wed, Aug 6, 2025, 6:32 PM Willy Tarreau <w@1wt.eu> wrote:

> On Wed, Aug 06, 2025 at 05:58:13PM -0400, Glenn Strauss wrote:
> > On Wed, Aug 06, 2025 at 11:39:14PM +0200, Willy Tarreau wrote:
> > > Hi,
> > >
> > > while we were discussing with Kazuho and Martin last week around a
> > > possible use of Expect for incremental requests, I came up with a doubt
> > > on a particular point of Expect: 100-continue, which is whether or not
> > > in HTTP/1 it's still permitted to reuse the connection when the request
> > > got a final response before uploading the contents.
> > >
> > > It turns out that I'm not seeing anything in the spec about this,
> leading
> > > me to suspect that it's permitted to reuse the connection. But at the
> same
> > > time it's encouraged that the client doesn't wait forever. So for me
> this
> > > means that there could be an ambiguity about what follows on the wire
> after
> > > an immediate response:
> > >
> > >    client                                              server
> > >
> > >    POST / HTTP/1.1
> > >    host: foo
> > >    content-length: 1000
> > >    expect: 100-continue
> > >        ....
> > >      <wait>
> > >                                     ...  <---  HTTP/1.1 403 forbidden
> > >    finally send body ---> ...
> > >                      <--- ... 403
> > >                                     ...  --->  BODY
> > >
> > > If the body contains what looks like a new request, the server will
> > > happily take it as the next one. Of course we don't have this problem
> > > with H2/H3, but I've looked at RFC9112 and didn't find anything special
> > > regarding reuse of the connection in this case. Did I miss anything ?
> > >
> > > I think that any final response to a request holding an Expect header
> > > should always be emitted with a connection: close header in H1 to avoid
> > > such issues. It might not always be great of course (e.g.
> re-authenticate)
> > > but I'm not seeing a non-ambiguous sequence without this.
> > >
> > > Thanks,
> > > Willy
> >
> > In HTTP/1.1, the request body is delimited by Content-Length or by
> > Transfer-Encoding: chunked.  Regardless of when the final response is
> > sent by the server (before receiving body, during receiving body, or
> > after receiving body), the server must receive (and possibly discard)
> > the entire body *before* looking to process any subsequent (keep-alive)
> > request.  To avoid sending/receiving the request body which was promised
> > in the request headers, the client or server must close the HTTP/1.1
> > connection to abort the request.
>
> I definitely agree with all these points.
>
> > The above is true whether or not the client request included
> >   expect: 100-continue
>
> This is the part that I don't find clear in the spec. For example I
> fear that an upload attempt resulting in 401 requesting authentication
> could mistakenly be done by the client over the same connection,
> considering that the server's response marks the end of the exchange
> (i.e. the client didn't intend to send and got the final response).
>
> But maybe all clients do it well and I'm worrying for no reason.
>
> Cheers,
> Willy
>
>

Received on Wednesday, 6 August 2025 23:27:04 UTC