From 6c4c700c43a6f0ebe3096955ee9e00990786d6e9 Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 20 Oct 2022 19:17:06 -0400 Subject: [PATCH 1/5] timeout except tests --- .../simplehttpserver/SimpleHttpHandler.java | 1 + .../handler/TimeoutHandler.java | 110 ++++++++++++++++++ src/main/java9/module-info.java | 1 + .../handler/TimeoutTests.java | 84 +++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 src/main/java/dev/katsute/simplehttpserver/handler/TimeoutHandler.java create mode 100644 src/test/java/dev/katsute/simplehttpserver/handler/TimeoutTests.java diff --git a/src/main/java/dev/katsute/simplehttpserver/SimpleHttpHandler.java b/src/main/java/dev/katsute/simplehttpserver/SimpleHttpHandler.java index 8d7187a..42d78d2 100644 --- a/src/main/java/dev/katsute/simplehttpserver/SimpleHttpHandler.java +++ b/src/main/java/dev/katsute/simplehttpserver/SimpleHttpHandler.java @@ -37,6 +37,7 @@ * @see dev.katsute.simplehttpserver.handler.RootHandler * @see dev.katsute.simplehttpserver.handler.SSEHandler * @see dev.katsute.simplehttpserver.handler.TemporaryHandler + * @see dev.katsute.simplehttpserver.handler.TimeoutHandler * @see dev.katsute.simplehttpserver.handler.throttler.ThrottledHandler * @see dev.katsute.simplehttpserver.handler.file.FileHandler * @since 5.0.0 diff --git a/src/main/java/dev/katsute/simplehttpserver/handler/TimeoutHandler.java b/src/main/java/dev/katsute/simplehttpserver/handler/TimeoutHandler.java new file mode 100644 index 0000000..585a7ab --- /dev/null +++ b/src/main/java/dev/katsute/simplehttpserver/handler/TimeoutHandler.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2022 Katsute + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package dev.katsute.simplehttpserver.handler; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import dev.katsute.simplehttpserver.SimpleHttpExchange; +import dev.katsute.simplehttpserver.SimpleHttpHandler; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.util.Objects; +import java.util.concurrent.*; + +/** + * The timeout handler runs a handler and times out after a set time. + * + * @since 5.0.0 + * @version 5.0.0 + * @author Katsute + */ +public class TimeoutHandler implements SimpleHttpHandler { + + private final HttpHandler handler; + + private final TimeUnit unit; + private final double timeout; + + private final ExecutorService service = Executors.newCachedThreadPool(); + + /** + * Creates a timeout handler. + * + * @param handler handler + * @param timeout how long until timeout in seconds + * + * @since 5.0.0 + */ + public TimeoutHandler(final HttpHandler handler, final double timeout){ + this(handler, timeout, TimeUnit.SECONDS); + } + + /** + * Creates a timeout handler. + * + * @param handler handler + * @param timeout how long until timeout + * @param unit timeout units + * + * @see TimeUnit + * @since 5.0.0 + */ + public TimeoutHandler(final HttpHandler handler, final double timeout, final TimeUnit unit){ + this.handler = Objects.requireNonNull(handler); + this.timeout = timeout; + this.unit = Objects.requireNonNull(unit); + } + + @Override + public final void handle(final HttpExchange exchange) throws IOException{ + SimpleHttpHandler.super.handle(exchange); + } + + @Override + public final void handle(final SimpleHttpExchange exchange) throws IOException{ + final Future future = service.submit(() -> { + try{ + handler.handle(exchange); + }catch(final IOException e){ + throw new RuntimeException(e); + } + }); + try{ + future.get((long) timeout, unit); + }catch(final Throwable e){ + future.cancel(true); + exchange.send(HttpURLConnection.HTTP_CLIENT_TIMEOUT); + if(!(e instanceof TimeoutException)) + throw new RuntimeException(e); + }finally{ + exchange.close(); + } + } + + @Override + public String toString(){ + return "TimeoutHandler{" + + "handler=" + handler + + ", timeout=" + timeout + + ", unit=" + unit + + '}'; + } + +} diff --git a/src/main/java9/module-info.java b/src/main/java9/module-info.java index a09f82d..07b3b5d 100644 --- a/src/main/java9/module-info.java +++ b/src/main/java9/module-info.java @@ -39,6 +39,7 @@ *
  • {@link dev.katsute.simplehttpserver.handler.RootHandler}
  • *
  • {@link dev.katsute.simplehttpserver.handler.SSEHandler}
  • *
  • {@link dev.katsute.simplehttpserver.handler.TemporaryHandler}
  • + *
  • {@link dev.katsute.simplehttpserver.handler.TimeoutHandler}
  • *
  • * {@link dev.katsute.simplehttpserver.handler.file.FileHandler} *