atomic_ice
atomic_ice

Reputation: 83

100 Continue with Jersey2+ with Jetty9+

I am seeing my jersey+jetty server to respond to a 100 continue header before the request is passed on to my handler. I do not want to send a 100-Continue and rather send a 3xx response based on the URI/Headers of the request.

This is the class org.glassfish.jersey.servlet.WebComponent which calls into request.getInputStream()

 public Value<Integer> service(
        final URI baseUri,
        final URI requestUri,
        final HttpServletRequest servletRequest,
        final HttpServletResponse servletResponse) throws ServletException, IOException {

    ContainerRequest requestContext = new ContainerRequest(baseUri, requestUri,
            servletRequest.getMethod(), getSecurityContext(servletRequest), new ServletPropertiesDelegate(servletRequest));
    requestContext.setEntityStream(servletRequest.getInputStream());
    addRequestHeaders(servletRequest, requestContext);

and Jetty sends the 100 Continue header when the input stream on the request is asked for. From org.eclipse.jetty.server.Request

@Override
public ServletInputStream getInputStream() throws IOException
{
    if (_inputState != __NONE && _inputState != _STREAM)
        throw new IllegalStateException("READER");
    _inputState = _STREAM;

    if (_channel.isExpecting100Continue())
        _channel.continue100(_input.available());

    return _input;
}

it calls into the HttpChannel to send the 100 Continue header

 /**
 * If the associated response has the Expect header set to 100 Continue,
 * then accessing the input stream indicates that the handler/servlet
 * is ready for the request body and thus a 100 Continue response is sent.
 *
 * @throws IOException if the InputStream cannot be created
 */
public void continue100(int available) throws IOException
{
    // If the client is expecting 100 CONTINUE, then send it now.
    // TODO: consider using an AtomicBoolean ?
    if (isExpecting100Continue())
    {
        _expect100Continue = false;

        // is content missing?
        if (available == 0)
        {
            if (_response.isCommitted())
                throw new IOException("Committed before 100 Continues");

            // TODO: break this dependency with HttpGenerator
            boolean committed = sendResponse(HttpGenerator.CONTINUE_100_INFO, null, false);
            if (!committed)
                throw new IOException("Concurrent commit while trying to send 100-Continue");
        }
    }
}

How do I prevent jersey+jetty from sending back the 100 continue till the request reaches the jersey tagged URI path methods?

Upvotes: 1

Views: 1480

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49462

With Expect: 100-Continue processing..

If you want to respond that part of the request, then:

  • Don't attempt access to the request parameters (this needs to read the input stream to process all possible parameter sources)
  • Don't attempt access to the request input stream (this means you are accepting the 100-Continue Expectation and are ready to receive the actual request body content)
  • Don't attempt access to the request reader (this opens the request input stream too)
  • Don't attempt to use the servlet Async I/O layer (this opens the request inputstream and response outputstreams)
  • Do use the HttpServletResponse to send your alternate status code and/or response body content.

This is all standard Servlet / Jetty behavior.

Upvotes: 2

Related Questions