Skip to content

100 (Continue) HTTP response should be handled gracefully regardless of whether it was requested/expected #3628

@stephentalley

Description

@stephentalley

I'm using OkHttp 3.8.1 on Android to POST to a poorly-behaved server.

Even though the request does not include an "Expect: 100-continue" header, the web server returns a 100 Continue response. Rather than continuing to send the request body (or just ignoring the 100 response since the body had already been sent), then getting the actual (200) response, OkHttp stops there and sends back the 100 Continue response in my okhttp.Callback.

The w3c definition of the 100 status code states:

The client SHOULD continue by sending the remainder of the request or, if the request has already been completed, ignore this response.

and:

A client MUST be prepared to accept one or more 1xx status responses prior to a regular response, even if the client does not expect a 100 Continue status message.

I have verified the correct behavior on three other HTTP clients (iOS, Windows, and curl(1)), who correctly ignore/continue when receiving an unexpected 100 Continue response.

In contrast, it looks like OkHttp only handles the 100 response iff it was explicitly requested via an "Expect: 100-continue" header. From CallServerInterceptor.java:

// If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100
// Continue" response before transmitting the request body. If we don't get that, return
// what we did get (such as a 4xx response) without ever transmitting the request body.
if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
    httpCodec.flushRequest();
    realChain.eventListener().responseHeadersStart(realChain.call());
    responseBuilder = httpCodec.readResponseHeaders(true);
}

Incidentally, the obvious workaround (including "Expect: 100-continue" in the request to trigger OkHttp's logic) didn't work for me because this particular server is further broken in that it complains about a mangled Expect: header. 😑 It doesn't appear any other workaround is possible, though I'd love to be proven wrong.

See: https://stackoverflow.com/a/46382361/920849

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug in existing code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions