Skip to content

Netty server never responds to requests with Expect: 100-continue #5503

Description

@adamw

Problem

A netty server never answers a request that carries Expect: 100-continue. The client gets the interim 100 Continue response, then the connection is closed. It never gets the real response, and no timeout fires either.

How to reproduce

Start any netty server (this uses NettyFutureServer, but the code path is shared by all netty backends) with a PUT endpoint that echoes a string body, then send a raw request:

PUT / HTTP/1.1
Host: localhost:<port>
Content-Type: text/plain
Content-Length: 4
Expect: 100-continue

wait a moment, then send test.

Response received:

HTTP/1.1 100 Continue
connection: close

and then EOF. Expected: 100 Continue, then 200 OK with the echoed body.

Why

NettyServerHandler.channelRead0 has this branch:

} else if (HttpUtil.is100ContinueExpected(request)) {
  ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE))
  ()
}

The route is never run, and the per-request IdleStateHandler (which produces the request timeout) is never installed. On top of that, the write goes through HttpStreamsServerHandler.unbufferedWrite while inFlight == 1 && continueExpected, which sets close = true, so the connection is closed once the 100 Continue is out.

The branch was added in #3337.

Suggested fix

Drop the branch and let the request fall through to runRoute. HttpStreamsServerHandler already handles Expect: 100-continue on its own: it sends the 100 Continue when the body publisher first asks for data, and closes the connection if a response is produced without the body ever being read. That would also give these requests a request timeout, like every other request.

Found while reviewing #5466, which documents the request timeout as starting when the request headers are received — which is not true for these requests.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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