Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Sending HTTP 408 (Request Timeout) response

Actually, never mind I will open the issue.

stand by...


On 28 December 2017 at 10:53, Greg Wilkins <gregw@xxxxxxxxxxx> wrote:
Daniel,

well that looks wrong!  I can confirm your test fails for me!

I find it hard to believe we don't have a test for this... but we have changed some close handling recently so obviously we have stuffed up somehow.  investigating....

Please open this as an issue.

regards




On 28 December 2017 at 01:41, Daniel Gredler <djgredler@xxxxxxxxx> wrote:
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
jetty-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users



--



--

Back to the top