Hi,

I'm upgrading dependencies in a JAX-RS project, and have reached the point
where I need to upgrade Jersey, which (via transitive dependencies)
involves upgrading Jetty from 9.2.x to 9.4.x.

One of our regression tests verifies that in the case of a request timeout
we are sending an HTTP 408 error back to the client. Ignoring all of the
JAX-RS layers, the code basically expects that the request handler is able
to catch an IOException with getCause() instanceof TimeoutException (see
code below for a minimal test case). This was the behavior in Jetty 9.2.x.

This appears to have changed in Jetty 9.3.0 and all subsequent 9.3.x and
9.4.x releases: no IOException is thrown in the request handler when the
request timeout expires. Connections and so on seem to be cleaned up on the
server side correctly, but we no longer have a hook to send the 408
response back to the client.

What is the best practice in Jetty 9.4.x for hooking into the request
timeout mechanism in order to customize the response that is sent back to
the client in case of timeouts?

Thanks!!

Daniel



[code sample]

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.concurrent.TimeoutException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

public class JettyTimeoutTest {

    public static void main(String... args) throws Exception {

        int port = 8181;
        Server jetty = new Server(port);
        jetty.setHandler(new TestHandler());
        jetty.start();

        try (Socket s = new Socket(InetAddress.getByName("localhost"),
port)) {

            String body = "abcdefghijklmnopqrstuvwxyz";

            OutputStreamWriter sw = new
OutputStreamWriter(s.getOutputStream(), UTF_8);
            sw.write("POST /foo HTTP/1.0\r\n");
            sw.write("Content-Length: " + body.length() + "\r\n");
            sw.write("Content-Type: application/x-www-form-urlencoded\r\n");
            sw.write("\r\n");
            sw.flush();
            sw.write(body.substring(0, 10));
            Thread.sleep(40_000); // a little longer than the server
timeout, which is 30 seconds
            sw.write(body.substring(10));
            sw.flush();

            String response = IOUtils.toString(s.getInputStream(), UTF_8);
            System.out.println("Response:");
            System.out.println(response); // 408 response in Jetty <=
9.2.23, empty response in Jetty >= 9.3.0

        } finally {
            jetty.stop();
        }
    }

    private static class TestHandler extends AbstractHandler {

        @Override
        public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
            throws IOException {

            int status;
            String body;

            try {
                status = HttpServletResponse.SC_OK;
                body = IOUtils.toString(request.getInputStream(), UTF_8);
// tries to read the entire POST body
            } catch (IOException e) {
                if (e.getCause() instanceof TimeoutException) {
                    status = HttpServletResponse.SC_REQUEST_TIMEOUT;
                    body = "HTTP ERROR 408";
                } else {
                    status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                    body = "HTTP ERROR 500";
                }
            }

            response.setContentType("text/plain");
            response.setStatus(status);
            response.getWriter().write(body);
            baseRequest.setHandled(true);
        }
    }
}
_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to