From 77f008b5bbca9914811b785385fe2ea4b95f2d54 Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 16:46:33 -0400 Subject: [PATCH 1/7] update context tests --- pom.xml | 14 ++++ src/test/java/ContextUtilTests.java | 111 ++++++++++++++++++---------- 2 files changed, 87 insertions(+), 38 deletions(-) diff --git a/pom.xml b/pom.xml index c76fc30..a3da54d 100644 --- a/pom.xml +++ b/pom.xml @@ -79,8 +79,22 @@ + + + jitpack.io + https://jitpack.io + + + + + com.kttdevelopment.core + test-util + 076417be59 + test + + junit junit diff --git a/src/test/java/ContextUtilTests.java b/src/test/java/ContextUtilTests.java index 9067900..83a6c24 100644 --- a/src/test/java/ContextUtilTests.java +++ b/src/test/java/ContextUtilTests.java @@ -2,56 +2,91 @@ import org.junit.Assert; import org.junit.Test; -public class ContextUtilTests { +import java.util.Arrays; + +public final class ContextUtilTests { + + private static final class test{ + + private final String expected, context; + private final boolean leadingSlash, trailingSlash; + + public test(final String expected, final String context, final boolean leadingSlash, final boolean trailingSlash){ + this.expected = expected; + this.context = context; + this.leadingSlash = leadingSlash; + this.trailingSlash = trailingSlash; + } - @Test - public void testContexts(){ - Assert.assertEquals("Failed test on blank (leading slash)" ,"/", ContextUtil.getContext("",true,false)); - Assert.assertEquals("Failed test on blank (trailing slash)" ,"/", ContextUtil.getContext("",false,true)); - Assert.assertEquals("Failed test on blank (both slashes)" ,"/", ContextUtil.getContext("",true,true)); - - Assert.assertEquals("Failed test on single (leading slash)" ,"/a" , ContextUtil.getContext("a",true,false)); - Assert.assertEquals("Failed test on single (trailing slash)" ,"a/" , ContextUtil.getContext("a",false,true)); - Assert.assertEquals("Failed test on single (both slashes)" ,"/a/", ContextUtil.getContext("a",true,true)); - - Assert.assertEquals("/testLeading" , ContextUtil.getContext("testLeading",true,false)); - Assert.assertEquals("testTrailing/" , ContextUtil.getContext("testTrailing",false,true)); - Assert.assertEquals("testNone" , ContextUtil.getContext("/testNone/",false,false)); - Assert.assertEquals("/testBoth/" , ContextUtil.getContext("testBoth",true,true)); - - Assert.assertEquals("testBackSlash/" , ContextUtil.getContext("testBackSlash\\",false,true)); - Assert.assertEquals("testConsBackSlash/", ContextUtil.getContext("testConsBackSlash\\\\",false,true)); - Assert.assertEquals("testConsFwdSlash/" , ContextUtil.getContext("testConsFwdSlash//",false,true)); } @Test - public void testJoin(){ - Assert.assertEquals("Failed test on last blank join" ,"a" ,ContextUtil.joinContexts(false,false,"a","")); - Assert.assertEquals("Failed test on last blank join+","/a/",ContextUtil.joinContexts(true,true,"a","")); + public final void testContexts(){ + final test[] tests = { + new test("" , "/" , false , false), + new test("/" , "" , true , false), + new test("/" , "" , false , true ), + new test("/" , "" , true , true ), + new test("a" , "a" , false , false), + new test("/a" , "a" , true , false), + new test("a/" , "a" , false , true ), + new test("/a/" , "a" , true , true ), + new test("testNone" , "/testNone/" , false , false), + new test("/testLeading" , "testLeading" , true , false), + new test("testTrailing/" , "testTrailing" , false , true ), + new test("/testBoth/" , "testBoth" , true , true ), + new test("testNoneBackSlash" , "\\testNoneBackSlash\\" , false , false), + new test("/testBackSlash/" , "\\testBackSlash\\" , true , true ), + new test("/testConsecutiveBackSlash/" , "\\\\testConsecutiveBackSlash\\\\", true , true ), + new test("/testConsecutiveForwardSlash/" , "//testConsecutiveForwardSlash//" , true , true ) + }; - Assert.assertEquals("Failed test on first blank join" ,"a" ,ContextUtil.joinContexts(false,false,"","a")); - Assert.assertEquals("Failed test on first blank join+","/a/",ContextUtil.joinContexts(true,true,"","a")); + for(final test test : tests) + Assert.assertEquals(String.format("Incorrect context for #(\"%s\", %s, %s)", test.context,test.leadingSlash,test.trailingSlash),test.expected,ContextUtil.getContext(test.context,test.leadingSlash,test.trailingSlash)); + } - Assert.assertEquals("Failed test on both blank join" ,"" ,ContextUtil.joinContexts(false,false,"","")); - Assert.assertEquals("Failed test on both blank join+","/",ContextUtil.joinContexts(true,true,"","")); + // - Assert.assertEquals("trailing/slash" ,ContextUtil.joinContexts(false,false,"trailing/","slash/")); - Assert.assertEquals("/trailing/slash+/" ,ContextUtil.joinContexts(true,true,"trailing/","slash+/")); + private static final class testJoin { - Assert.assertEquals("leading/slash" ,ContextUtil.joinContexts(false,false,"/leading","/slash")); - Assert.assertEquals("/leading/slash+/" ,ContextUtil.joinContexts(true,true,"/leading","/slash+")); + private final String expected; + private final String[] contexts; + private final boolean leadingSlash, trailingSlash; - Assert.assertEquals("double/slash" ,ContextUtil.joinContexts(false,false,"/double/","/slash/")); - Assert.assertEquals("/double/slash+/" ,ContextUtil.joinContexts(true,true,"/double/","/slash+/")); + public testJoin(final String expected, final boolean leadingSlash, final boolean trailingSlash, final String... contexts){ + this.expected = expected; + this.leadingSlash = leadingSlash; + this.trailingSlash = trailingSlash; + this.contexts = contexts; + } - Assert.assertEquals("no/slash" ,ContextUtil.joinContexts(false,false,"no","slash")); - Assert.assertEquals("/no/slash+/" ,ContextUtil.joinContexts(true,true,"no","slash+")); + } - Assert.assertEquals("cons/slash" ,ContextUtil.joinContexts(false,false,"/cons/","/slash/")); - Assert.assertEquals("/cons/slash+/" ,ContextUtil.joinContexts(true,true,"/cons/","/slash+/")); + @Test + public final void testJoin(){ + final testJoin[] tests = { + new testJoin("testBlank" ,false ,false ,"testBlank",""), + new testJoin("/testBlank/" ,true ,true ,"testBlank",""), + new testJoin("testBlank" ,false ,false ,"","testBlank"), + new testJoin("/testBlank/" ,true ,true ,"","testBlank"), + new testJoin("" ,false ,false ,"",""), + new testJoin("/" ,true ,true ,"",""), + new testJoin("trailing/slash" , false , false ,"trailing/","slash/"), + new testJoin("/trailing/slash/" , true , true ,"trailing/","slash/"), + new testJoin("leading/slash" , false , false ,"leading/","slash/"), + new testJoin("/leading/slash/" , true , true ,"leading/","slash/"), + new testJoin("double/slash" , false , false ,"/double/","/slash/"), + new testJoin("/double/slash/" , true , true ,"/double/","/slash/"), + new testJoin("no/slash" , false , false ,"no","slash"), + new testJoin("/no/slash/" , true , true ,"no","slash"), + new testJoin("consecutive/slash" , false , false ,"//consecutive//","//slash//"), + new testJoin("/consecutive/slash/" , true , true ,"//consecutive//","//slash//"), + new testJoin("mixed/slash" , false , false ,"\\mixed\\","//slash//"), + new testJoin("/mixed/slash/" , true , true ,"\\mixed\\","//slash//"), + }; - Assert.assertEquals("mix/slash" ,ContextUtil.joinContexts(false,false,"\\mix\\","/slash/")); - Assert.assertEquals("/mix/slash+/" ,ContextUtil.joinContexts(true,true,"\\mix\\","/slash+/")); + for(final testJoin test : tests) + Assert.assertEquals(String.format("Incorrect context for #(%s, %s, %s)", test.leadingSlash, test.trailingSlash, Arrays.toString(test.contexts)), test.expected, ContextUtil.joinContexts(test.leadingSlash, test.trailingSlash, test.contexts)); } } From f5c2aefc397f8806a441fc9b1f9cc19b3906941e Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 17:06:19 -0400 Subject: [PATCH 2/7] server tests --- .../SimpleHttpServerContextTests.java | 51 +++++++++---------- ...sts.java => SimpleHttpServerGetTests.java} | 6 +-- .../SimpleHttpServerInitTests.java | 47 ----------------- .../SimpleHttpServerBindOccupiedTests.java | 30 +++++++++++ .../SimpleHttpServerBindRangeTest.java} | 33 +++--------- .../create/SimpleHttpServerCreateTest.java | 29 +++++++++++ .../create/SimpleHttpsServerCreateTest.java | 29 +++++++++++ 7 files changed, 122 insertions(+), 103 deletions(-) rename src/test/java/simplehttpserver/{SimpleHttpServerReadTests.java => SimpleHttpServerGetTests.java} (88%) delete mode 100644 src/test/java/simplehttpserver/SimpleHttpServerInitTests.java create mode 100644 src/test/java/simplehttpserver/bind/SimpleHttpServerBindOccupiedTests.java rename src/test/java/simplehttpserver/{SimpleHttpServerBindTests.java => bind/SimpleHttpServerBindRangeTest.java} (53%) create mode 100644 src/test/java/simplehttpserver/create/SimpleHttpServerCreateTest.java create mode 100644 src/test/java/simplehttpserver/create/SimpleHttpsServerCreateTest.java diff --git a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java index c88cc7d..d207c07 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java +++ b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java @@ -2,15 +2,16 @@ import com.kttdevelopment.simplehttpserver.*; import com.kttdevelopment.simplehttpserver.handler.RootHandler; +import com.sun.net.httpserver.HttpExchange; import org.junit.Assert; import org.junit.Test; import java.io.IOException; -public class SimpleHttpServerContextTests { +public final class SimpleHttpServerContextTests { @Test - public void randContext() throws IOException{ + public final void randContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); final String initContext = server.getRandomContext(); @@ -21,7 +22,7 @@ public void randContext() throws IOException{ } @Test - public void randContextHead() throws IOException{ + public final void randContextHead() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); final String head = "/head"; @@ -34,23 +35,22 @@ public void randContextHead() throws IOException{ } @Test - public void removeNullContext() throws IOException{ + public final void removeNullContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); - Exception exception = null; - try{ server.removeContext((String) null); - }catch(final NullPointerException e){ exception = e; } - Assert.assertNotNull("Null string context should throw NPE", exception); + try{ + server.removeContext((String) null); + Assert.fail("Null string context should throw NPE"); + }catch(final NullPointerException ignored){ } - String context = ""; - exception = null; - try{ server.removeContext(context); - }catch(final IllegalArgumentException e){ exception = e; } - Assert.assertNotNull("Server should throw IllegalArgumentException when removing a context that doesn't exist", exception); + try{ + server.removeContext(""); + Assert.fail("Server should throw IllegalArgumentException when removing a context that doesn't exist"); + }catch(final IllegalArgumentException ignored){ } } @Test - public void removeContext() throws IOException{ + public final void removeContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); final String context = ""; @@ -67,7 +67,7 @@ public void removeContext() throws IOException{ } @Test - public void removeNativeContext() throws IOException{ + public final void removeNativeContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); String context = "/"; @@ -105,30 +105,27 @@ public void createContext() throws IOException{ } @Test - public void createRootContext() throws IOException{ - final SimpleHttpServer server = SimpleHttpServer.create(); - final RootHandler handler = new RootHandler((SimpleHttpHandler) SimpleHttpExchange::close, (SimpleHttpHandler) SimpleHttpExchange::close); + public final void createRootContext() throws IOException{ + final SimpleHttpServer server = SimpleHttpServer.create(); + final RootHandler handler = new RootHandler(HttpExchange::close,HttpExchange::close); String context = server.getRandomContext(); - Exception exception = null; try{ server.createContext(context,handler); - }catch(final IllegalArgumentException e){ exception = e; } - Assert.assertNotNull("Server should throw IllegalArgumentException when adding RootHandler to non-root context",exception); + Assert.fail("Server should throw IllegalArgumentException when adding RootHandler to non-root context"); + }catch(final IllegalArgumentException ignored){ } final String[] testRoots = {"/","\\",""}; - for(final String testRoot : testRoots){ - try{ - server.removeContext(server.createContext(testRoot, handler)); - }catch(final IllegalArgumentException e){ + for(final String testRoot : testRoots) + try{ server.removeContext(server.createContext(testRoot, handler)); + }catch(final IllegalArgumentException ignored){ Assert.fail("Server threw IllegalArgumentException for allowed context [" + testRoot + "] for RootHandler"); } - } } @Test - public void createSlashedContext() throws IOException{ + public final void createSlashedContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); final String[] roots = {"/","\\",""}; diff --git a/src/test/java/simplehttpserver/SimpleHttpServerReadTests.java b/src/test/java/simplehttpserver/SimpleHttpServerGetTests.java similarity index 88% rename from src/test/java/simplehttpserver/SimpleHttpServerReadTests.java rename to src/test/java/simplehttpserver/SimpleHttpServerGetTests.java index 6f37da1..9e83b32 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerReadTests.java +++ b/src/test/java/simplehttpserver/SimpleHttpServerGetTests.java @@ -6,12 +6,12 @@ import java.io.IOException; -public class SimpleHttpServerReadTests { +public final class SimpleHttpServerGetTests { @SuppressWarnings("SpellCheckingInspection") @Test - public void get() throws IOException{ - final int port = 10005; + public final void get() throws IOException{ + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(); Assert.assertNotNull("#getHttpServer() should not be null", server.getHttpServer()); diff --git a/src/test/java/simplehttpserver/SimpleHttpServerInitTests.java b/src/test/java/simplehttpserver/SimpleHttpServerInitTests.java deleted file mode 100644 index ed4512d..0000000 --- a/src/test/java/simplehttpserver/SimpleHttpServerInitTests.java +++ /dev/null @@ -1,47 +0,0 @@ -package simplehttpserver; - -import com.kttdevelopment.simplehttpserver.SimpleHttpServer; -import com.kttdevelopment.simplehttpserver.SimpleHttpsServer; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; - -public class SimpleHttpServerInitTests { - - - @Test - public void create() throws IOException{ - final int port = 10003; - SimpleHttpServer server = SimpleHttpServer.create(); - Exception exception = null; - try{ - server.start(); - }catch(final IllegalStateException e){ - exception = e; - } - Assert.assertNotNull("Start server with no port should throw an exception", exception); - - server.bind(port); - server.start(); - server.stop(); - } - - @Test - public void createHTTPS() throws IOException{ - final int port = 10004; - SimpleHttpsServer server = SimpleHttpsServer.create(); - Exception exception = null; - try{ - server.start(); - }catch(final IllegalStateException e){ - exception = e; - } - Assert.assertNotNull("Start server with no port should throw an exception", exception); - - server.bind(port); - server.start(); - server.stop(); - } - -} diff --git a/src/test/java/simplehttpserver/bind/SimpleHttpServerBindOccupiedTests.java b/src/test/java/simplehttpserver/bind/SimpleHttpServerBindOccupiedTests.java new file mode 100644 index 0000000..395a7ef --- /dev/null +++ b/src/test/java/simplehttpserver/bind/SimpleHttpServerBindOccupiedTests.java @@ -0,0 +1,30 @@ +package simplehttpserver.bind; + +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import org.junit.*; + +import java.io.IOException; +import java.net.BindException; + +public final class SimpleHttpServerBindOccupiedTests { + + @Test + public final void testOccupiedPortBind() throws IOException{ + final int port = 8080; + final SimpleHttpServer s1 = SimpleHttpServer.create(port); + s1.start(); + + Exception exception = null; + try{ SimpleHttpServer.create(port); + }catch(final BindException e){ exception = e; } + + Assert.assertNotNull("Bind server to occupied port should throw an exception",exception); + + s1.stop(); + exception = null; + try{ SimpleHttpServer.create(port); + }catch(final BindException e){ exception = e; } + Assert.assertNull("Bind server to now unoccupied port should not throw an exception",exception); + } + +} diff --git a/src/test/java/simplehttpserver/SimpleHttpServerBindTests.java b/src/test/java/simplehttpserver/bind/SimpleHttpServerBindRangeTest.java similarity index 53% rename from src/test/java/simplehttpserver/SimpleHttpServerBindTests.java rename to src/test/java/simplehttpserver/bind/SimpleHttpServerBindRangeTest.java index 2c8be37..595cfeb 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerBindTests.java +++ b/src/test/java/simplehttpserver/bind/SimpleHttpServerBindRangeTest.java @@ -1,28 +1,28 @@ -package simplehttpserver; +package simplehttpserver.bind; import com.kttdevelopment.simplehttpserver.SimpleHttpServer; -import org.junit.*; +import org.junit.Assert; +import org.junit.Test; import java.io.IOException; -import java.net.BindException; -public class SimpleHttpServerBindTests { +public final class SimpleHttpServerBindRangeTest { @Test public void testPortRange() throws IOException{ - final int port = 10001; + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(); Exception exception = null; try{ server.bind(-1); }catch(final IllegalArgumentException | IOException e){ exception = e; } - Assert.assertTrue("Bind server to bad port (-1) should throw an exception", exception instanceof IllegalArgumentException); + Assert.assertTrue("Bind server to bad port (-1) should throw an exception", exception instanceof IllegalArgumentException); exception = null; try{ server.bind(65536); }catch(final IllegalArgumentException | IOException e){ exception = e; } - Assert.assertTrue("Bind server to bad port (65536) should throw an exception", exception instanceof IllegalArgumentException); + Assert.assertTrue("Bind server to bad port (65536) should throw an exception", exception instanceof IllegalArgumentException); exception = null; try{ server.bind(port); @@ -33,23 +33,4 @@ public void testPortRange() throws IOException{ Assert.assertEquals("Server bind port should equal address port",port,server.getAddress().getPort()); } - @Test - public void testOccupiedPortBind() throws IOException{ - final int port = 10002; - final SimpleHttpServer s1 = SimpleHttpServer.create(port); - s1.start(); - - Exception exception = null; - try{ SimpleHttpServer.create(port); - }catch(final BindException e){ exception = e; } - s1.stop(); - - Assert.assertNotNull("Bind server to occupied port should throw an exception",exception); - - exception = null; - try{ SimpleHttpServer.create(port); - }catch(final BindException e){ exception = e; } - Assert.assertNull("Bind server to now unoccupied port should not throw an exception",exception); - } - } diff --git a/src/test/java/simplehttpserver/create/SimpleHttpServerCreateTest.java b/src/test/java/simplehttpserver/create/SimpleHttpServerCreateTest.java new file mode 100644 index 0000000..f8be57d --- /dev/null +++ b/src/test/java/simplehttpserver/create/SimpleHttpServerCreateTest.java @@ -0,0 +1,29 @@ +package simplehttpserver.create; + +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public final class SimpleHttpServerCreateTest { + + @Test + public final void create() throws IOException{ + final int port = 8080; + SimpleHttpServer server = SimpleHttpServer.create(); + try{ + server.start(); + Assert.fail("Start server with no port should throw an exception"); + }catch(final IllegalStateException ignored){ } + + server.bind(port); + try{ + server.stop(); + server.stop(); + }catch(final IllegalStateException ignored){ + Assert.fail("Start server with valid port should not throw an exception"); + } + } + +} diff --git a/src/test/java/simplehttpserver/create/SimpleHttpsServerCreateTest.java b/src/test/java/simplehttpserver/create/SimpleHttpsServerCreateTest.java new file mode 100644 index 0000000..cc99bdc --- /dev/null +++ b/src/test/java/simplehttpserver/create/SimpleHttpsServerCreateTest.java @@ -0,0 +1,29 @@ +package simplehttpserver.create; + +import com.kttdevelopment.simplehttpserver.SimpleHttpsServer; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public final class SimpleHttpsServerCreateTest { + + @Test + public final void create() throws IOException{ + final int port = 8080; + SimpleHttpsServer server = SimpleHttpsServer.create(); + try{ + server.start(); + Assert.fail("Start server with no port should throw an exception"); + }catch(final IllegalStateException ignored){ } + + server.bind(port); + try{ + server.stop(); + server.stop(); + }catch(final IllegalStateException ignored){ + Assert.fail("Start server with valid port should not throw an exception"); + } + } + +} From 16b5abe1f839f47d25a3663578e4286d6f4e6b8f Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 17:14:19 -0400 Subject: [PATCH 3/7] Fix #86 --- .../simplehttpserver/SimpleHttpServerImpl.java | 11 +++++++++-- .../SimpleHttpServerContextTests.java | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java index 403dce3..5611ae6 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java @@ -7,6 +7,7 @@ import java.net.InetSocketAddress; import java.util.*; import java.util.concurrent.Executor; +import java.util.function.BiConsumer; /** * Implementation for {@link SimpleHttpServer}. Applications do not use this class. @@ -147,7 +148,8 @@ public synchronized final HttpContext createContext(final String context, final @Override public synchronized final HttpContext createContext(final String context, final HttpHandler handler, final Authenticator authenticator){ - if(!ContextUtil.getContext(context,true,false).equals("/") && handler instanceof RootHandler) + final String ct = ContextUtil.getContext(context,true,false); + if(!ct.equals("/") && handler instanceof RootHandler) throw new IllegalArgumentException("RootHandler can only be used at the root '/' context"); final HttpHandler wrapper = exchange -> { @@ -155,7 +157,12 @@ public synchronized final HttpContext createContext(final String context, final handler.handle(exchange); }; - final HttpContext hc = server.createContext(ContextUtil.getContext(context,true,false),wrapper); + + for(final HttpContext httpContext : contexts.keySet()) + if(httpContext.getPath().equals(ct)) + throw new IllegalArgumentException("The context '" + ct + "' is already occupied"); + + final HttpContext hc = server.createContext(ct,wrapper); contexts.put(hc,handler); if(authenticator != null) diff --git a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java index d207c07..4867ee9 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java +++ b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java @@ -3,6 +3,7 @@ import com.kttdevelopment.simplehttpserver.*; import com.kttdevelopment.simplehttpserver.handler.RootHandler; import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; import org.junit.Assert; import org.junit.Test; @@ -133,4 +134,14 @@ public final void createSlashedContext() throws IOException{ Assert.assertEquals("Context [" + root + "] should correct to \"/\"","/",server.createContext(root).getPath()); } + + @Test(expected = IllegalArgumentException.class) + public final void createDuplicateContext() throws IOException{ + final SimpleHttpServer server = SimpleHttpServer.create(); + final String context = server.getRandomContext(); + + server.createContext(context); + server.createContext(context,HttpExchange::close); + } + } From 226f8c6802f45df86ec46fdfc63aa469b9ad38cd Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 17:27:35 -0400 Subject: [PATCH 4/7] Unfixed #86 This is an issue with sun http server, not simplehttpserver --- .../simplehttpserver/SimpleHttpServerImpl.java | 7 ++----- .../simplehttpserver/SimpleHttpServerContextTests.java | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java index 5611ae6..3a5760d 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java @@ -157,12 +157,9 @@ public synchronized final HttpContext createContext(final String context, final handler.handle(exchange); }; + final HttpContext hc = server.createContext(ct); - for(final HttpContext httpContext : contexts.keySet()) - if(httpContext.getPath().equals(ct)) - throw new IllegalArgumentException("The context '" + ct + "' is already occupied"); - - final HttpContext hc = server.createContext(ct,wrapper); + hc.setHandler(wrapper); contexts.put(hc,handler); if(authenticator != null) diff --git a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java index 4867ee9..eb36ad7 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java +++ b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java @@ -135,10 +135,10 @@ public final void createSlashedContext() throws IOException{ } - @Test(expected = IllegalArgumentException.class) + @Test// (expected = IllegalArgumentException.class) public final void createDuplicateContext() throws IOException{ final SimpleHttpServer server = SimpleHttpServer.create(); - final String context = server.getRandomContext(); + final String context = "duplicate"; server.createContext(context); server.createContext(context,HttpExchange::close); From 59a17e12e09fd8016c52b755a7d608e39a84bb1f Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 17:35:09 -0400 Subject: [PATCH 5/7] SimpleHttpExchange tests --- .../SimpleHttpExchangeCookieSessionTests.java | 7 +- .../SimpleHttpExchangeGetPostTests.java | 153 ------------------ .../SimpleHttpExchangeReadTests.java | 6 +- .../io/SimpleHttpExchangeGetTest.java | 56 +++++++ .../SimpleHttpExchangeMultipartFormTest.java | 75 +++++++++ .../io/SimpleHttpExchangePostTest.java | 56 +++++++ 6 files changed, 193 insertions(+), 160 deletions(-) delete mode 100644 src/test/java/simplehttpexchange/SimpleHttpExchangeGetPostTests.java create mode 100644 src/test/java/simplehttpexchange/io/SimpleHttpExchangeGetTest.java create mode 100644 src/test/java/simplehttpexchange/io/SimpleHttpExchangeMultipartFormTest.java create mode 100644 src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java diff --git a/src/test/java/simplehttpexchange/SimpleHttpExchangeCookieSessionTests.java b/src/test/java/simplehttpexchange/SimpleHttpExchangeCookieSessionTests.java index 8fee267..71e821a 100644 --- a/src/test/java/simplehttpexchange/SimpleHttpExchangeCookieSessionTests.java +++ b/src/test/java/simplehttpexchange/SimpleHttpExchangeCookieSessionTests.java @@ -12,11 +12,11 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; -public class SimpleHttpExchangeCookieSessionTests { +public final class SimpleHttpExchangeCookieSessionTests { @Test - public void testSession() throws IOException, ExecutionException, InterruptedException{ - final int port = 20004; + public final void testSession() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); final AtomicReference exchangeRef = new AtomicReference<>(); @@ -48,7 +48,6 @@ public void testSession() throws IOException, ExecutionException, InterruptedExc client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body).get(); - // exchange final SimpleHttpExchange exchange = exchangeRef.get(); diff --git a/src/test/java/simplehttpexchange/SimpleHttpExchangeGetPostTests.java b/src/test/java/simplehttpexchange/SimpleHttpExchangeGetPostTests.java deleted file mode 100644 index fee5aa7..0000000 --- a/src/test/java/simplehttpexchange/SimpleHttpExchangeGetPostTests.java +++ /dev/null @@ -1,153 +0,0 @@ -package simplehttpexchange; - -import com.kttdevelopment.simplehttpserver.*; -import com.kttdevelopment.simplehttpserver.var.RequestMethod; -import com.sun.net.httpserver.HttpContext; -import org.junit.*; - -import java.io.IOException; -import java.net.URI; -import java.net.http.*; -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicReference; - -public class SimpleHttpExchangeGetPostTests { - - @Test - public void get() throws IOException, ExecutionException, InterruptedException{ - final int port = 20002; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - final AtomicReference exchangeRef = new AtomicReference<>(); - final AtomicReference exchangeResponse = new AtomicReference<>(); - final SimpleHttpHandler handler = exchange -> { - exchangeRef.set(exchange); - exchangeResponse.set(exchange.toString()); - exchange.send(exchange.toString()); - }; - - final String context = ""; - final AtomicReference contextRef = new AtomicReference<>(); - contextRef.set(server.createContext(context,handler)); - server.start(); - - String queryKey = "test", queryValue = "value"; - String url = "http://localhost:" + port + context + '?' + queryKey + '=' + queryValue; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Response body did not match response sent", exchangeResponse.get(), response); - - // exchange - final SimpleHttpExchange exchange = exchangeRef.get(); - - Assert.assertEquals("Client request method did not match exchange request method (GET)", RequestMethod.GET,exchange.getRequestMethod()); - Assert.assertTrue("Exchange was missing client GET map", exchange.hasGet()); - Assert.assertEquals("Exchange GET did not match client GET", queryValue, exchange.getGetMap().get(queryKey)); - } - - @Test - public void postSimple() throws IOException, ExecutionException, InterruptedException{ - final int port = 20003; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - final AtomicReference exchangeRef = new AtomicReference<>(); - final AtomicReference exchangeResponse = new AtomicReference<>(); - final SimpleHttpHandler handler = exchange -> { - exchangeRef.set(exchange); - exchangeResponse.set(exchange.toString()); - exchange.send(exchange.toString()); - }; - - final String context = ""; - final AtomicReference contextRef = new AtomicReference<>(); - contextRef.set(server.createContext(context,handler)); - server.start(); - - String queryKey = "test", queryValue = "value"; - String url = "http://localhost:" + port + context ; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .POST(HttpRequest.BodyPublishers.ofString(queryKey + '=' + queryValue)) - .build(); - - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - // exchange - final SimpleHttpExchange exchange = exchangeRef.get(); - - Assert.assertEquals("Client request method did not match exchange request method (POST)", RequestMethod.POST,exchange.getRequestMethod()); - Assert.assertTrue("Exchange was missing client POST map", exchange.hasPost()); - Assert.assertEquals("Exchange POST did not match client POST", queryValue, exchange.getPostMap().get(queryKey)); - - server.stop(); - } - - @SuppressWarnings({"rawtypes", "StringBufferReplaceableByString"}) - @Test - public void postMultipartFormData() throws IOException, ExecutionException, InterruptedException{ - final int port = 20005; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - final AtomicReference exchangeRef = new AtomicReference<>(); - final AtomicReference exchangeResponse = new AtomicReference<>(); - final SimpleHttpHandler handler = exchange -> { - exchangeRef.set(exchange); - exchangeResponse.set(exchange.toString()); - exchange.send(exchange.toString()); - }; - - final String context = ""; - server.createContext(context,handler); - server.start(); - - String boundary = "d74496d66958873e"; - - String url = "http://localhost:" + port + context ; - - String key = "key", value = "value"; - String fkey = "fileKey", filename = "fileName.txt", fvalue = "fileValue"; - - StringBuilder OUT = new StringBuilder(); - OUT.append("--------------------------").append(boundary).append("\r\n"); - OUT.append("Content-Disposition: ").append("form-data; ").append("name=\"").append(key).append('\"').append("\r\n\r\n"); - OUT.append(value).append("\r\n"); - OUT.append("--------------------------").append(boundary).append("\r\n"); - OUT.append("Content-Disposition: ").append("form-data; ").append("name=\"").append(fkey).append("\"; "); - OUT.append("filename=\"").append(filename).append('\"').append('\n'); - OUT.append("Content-Type: ").append("text/plain").append("\r\n\r\n"); - OUT.append(fvalue).append("\r\n"); - OUT.append("--------------------------").append(boundary).append("--"); - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-type","multipart/form-data; boundary=" + boundary) - .POST(HttpRequest.BodyPublishers.ofString(OUT.toString())) - .build(); - - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - // exchange - final SimpleHttpExchange exchange = exchangeRef.get(); - - Assert.assertEquals("Client request method did not match exchange request method (POST)", RequestMethod.POST,exchange.getRequestMethod()); - Assert.assertTrue("Exchange was missing client POST map", exchange.hasPost()); - - Assert.assertEquals("Client form value did not match server value",value, ((Map) exchange.getPostMap().get(key)).get("value")); - Assert.assertEquals("Client file name did not match server value",filename, ((Map) ((Map) ((Map) ((Map) exchange.getPostMap().get(fkey)).get("headers")).get("Content-Disposition")).get("parameters")).get("filename")); - Assert.assertEquals("Client file value did not match server value",fvalue, ((Map) exchange.getPostMap().get(fkey)).get("value")); - - server.stop(); - } - -} diff --git a/src/test/java/simplehttpexchange/SimpleHttpExchangeReadTests.java b/src/test/java/simplehttpexchange/SimpleHttpExchangeReadTests.java index 697364d..c2f23f4 100644 --- a/src/test/java/simplehttpexchange/SimpleHttpExchangeReadTests.java +++ b/src/test/java/simplehttpexchange/SimpleHttpExchangeReadTests.java @@ -12,11 +12,11 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; -public class SimpleHttpExchangeReadTests { +public final class SimpleHttpExchangeReadTests { @Test - public void read() throws IOException, InterruptedException, ExecutionException{ - final int port = 20001; + public final void read() throws IOException, InterruptedException, ExecutionException{ + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); final AtomicReference exchangeRef = new AtomicReference<>(); diff --git a/src/test/java/simplehttpexchange/io/SimpleHttpExchangeGetTest.java b/src/test/java/simplehttpexchange/io/SimpleHttpExchangeGetTest.java new file mode 100644 index 0000000..2bd174d --- /dev/null +++ b/src/test/java/simplehttpexchange/io/SimpleHttpExchangeGetTest.java @@ -0,0 +1,56 @@ +package simplehttpexchange.io; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.var.RequestMethod; +import com.sun.net.httpserver.HttpContext; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +public final class SimpleHttpExchangeGetTest { + + @Test + public final void get() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final AtomicReference exchangeRef = new AtomicReference<>(); + final AtomicReference exchangeResponse = new AtomicReference<>(); + final SimpleHttpHandler handler = exchange -> { + exchangeRef.set(exchange); + exchangeResponse.set(exchange.toString()); + exchange.send(exchange.toString()); + }; + + final String context = ""; + final AtomicReference contextRef = new AtomicReference<>(); + contextRef.set(server.createContext(context,handler)); + server.start(); + + final String queryKey = "test", queryValue = "value"; + final String url = "http://localhost:" + port + context + '?' + queryKey + '=' + queryValue; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Response body did not match response sent", exchangeResponse.get(), response); + + // exchange + final SimpleHttpExchange exchange = exchangeRef.get(); + + Assert.assertEquals("Client request method did not match exchange request method (GET)", RequestMethod.GET, exchange.getRequestMethod()); + Assert.assertTrue("Exchange was missing client GET map", exchange.hasGet()); + Assert.assertEquals("Exchange GET did not match client GET", queryValue, exchange.getGetMap().get(queryKey)); + } + +} diff --git a/src/test/java/simplehttpexchange/io/SimpleHttpExchangeMultipartFormTest.java b/src/test/java/simplehttpexchange/io/SimpleHttpExchangeMultipartFormTest.java new file mode 100644 index 0000000..6c1c8fd --- /dev/null +++ b/src/test/java/simplehttpexchange/io/SimpleHttpExchangeMultipartFormTest.java @@ -0,0 +1,75 @@ +package simplehttpexchange.io; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.var.RequestMethod; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +public final class SimpleHttpExchangeMultipartFormTest { + + @SuppressWarnings({"rawtypes", "StringBufferReplaceableByString", "SpellCheckingInspection"}) + @Test + public final void postMultipartFormData() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final AtomicReference exchangeRef = new AtomicReference<>(); + final AtomicReference exchangeResponse = new AtomicReference<>(); + final SimpleHttpHandler handler = exchange -> { + exchangeRef.set(exchange); + exchangeResponse.set(exchange.toString()); + exchange.send(exchange.toString()); + }; + + final String context = ""; + server.createContext(context,handler); + server.start(); + + final String boundary = "d74496d66958873e"; + + final String url = "http://localhost:" + port + context ; + + final String key = "key", value = "value"; + final String fkey = "fileKey", filename = "fileName.txt", fvalue = "fileValue"; + + final StringBuilder OUT = new StringBuilder(); + OUT.append("--------------------------").append(boundary).append("\r\n"); + OUT.append("Content-Disposition: ").append("form-data; ").append("name=\"").append(key).append('\"').append("\r\n\r\n"); + OUT.append(value).append("\r\n"); + OUT.append("--------------------------").append(boundary).append("\r\n"); + OUT.append("Content-Disposition: ").append("form-data; ").append("name=\"").append(fkey).append("\"; "); + OUT.append("filename=\"").append(filename).append('\"').append('\n'); + OUT.append("Content-Type: ").append("text/plain").append("\r\n\r\n"); + OUT.append(fvalue).append("\r\n"); + OUT.append("--------------------------").append(boundary).append("--"); + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-type","multipart/form-data; boundary=" + boundary) + .POST(HttpRequest.BodyPublishers.ofString(OUT.toString())) + .build(); + + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + // exchange + final SimpleHttpExchange exchange = exchangeRef.get(); + + Assert.assertEquals("Client request method did not match exchange request method (POST)", RequestMethod.POST,exchange.getRequestMethod()); + Assert.assertTrue("Exchange was missing client POST map", exchange.hasPost()); + + Assert.assertEquals("Client form value did not match server value",value, ((Map) exchange.getPostMap().get(key)).get("value")); + Assert.assertEquals("Client file name did not match server value",filename, ((Map) ((Map) ((Map) ((Map) exchange.getPostMap().get(fkey)).get("headers")).get("Content-Disposition")).get("parameters")).get("filename")); + Assert.assertEquals("Client file value did not match server value",fvalue, ((Map) exchange.getPostMap().get(fkey)).get("value")); + + server.stop(); + } + +} diff --git a/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java b/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java new file mode 100644 index 0000000..d209840 --- /dev/null +++ b/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java @@ -0,0 +1,56 @@ +package simplehttpexchange.io; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.var.RequestMethod; +import com.sun.net.httpserver.HttpContext; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +public final class SimpleHttpExchangePostTest { + + @Test + public void postSimple() throws IOException, ExecutionException, InterruptedException{ + final int port = 20003; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final AtomicReference exchangeRef = new AtomicReference<>(); + final AtomicReference exchangeResponse = new AtomicReference<>(); + final SimpleHttpHandler handler = exchange -> { + exchangeRef.set(exchange); + exchangeResponse.set(exchange.toString()); + exchange.send(exchange.toString()); + }; + + final String context = ""; + final AtomicReference contextRef = new AtomicReference<>(); + contextRef.set(server.createContext(context,handler)); + server.start(); + + final String queryKey = "test", queryValue = "value"; + final String url = "http://localhost:" + port + context ; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .POST(HttpRequest.BodyPublishers.ofString(queryKey + '=' + queryValue)) + .build(); + + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + // exchange + final SimpleHttpExchange exchange = exchangeRef.get(); + + Assert.assertEquals("Client request method did not match exchange request method (POST)", RequestMethod.POST, exchange.getRequestMethod()); + Assert.assertTrue("Exchange was missing client POST map", exchange.hasPost()); + Assert.assertEquals("Exchange POST did not match client POST", queryValue, exchange.getPostMap().get(queryKey)); + + server.stop(); + } + +} From 4530812bbbfbf226c11cbc55e9200162fbb7d3ce Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 18:01:03 -0400 Subject: [PATCH 6/7] All handlers except file --- pom.xml | 2 +- .../simplehttpserver/SimpleHttpCookie.java | 3 +- .../simplehttpserver/SimpleHttpServer.java | 19 +- .../SimpleHttpServerImpl.java | 3 +- .../SimpleHttpsServerImpl.java | 13 +- .../handler/DirectoryEntry.java | 1 + .../simplehttpserver/var/HttpCode.java | 2 +- .../simplehttpserver/var/RequestMethod.java | 1 - src/test/java/handlers/FileHandlerTests.java | 1 + .../java/handlers/PredicateHandlerTests.java | 51 +--- .../java/handlers/RedirectHandlerTests.java | 18 +- src/test/java/handlers/SSEHandlerTests.java | 25 +- .../java/handlers/TemporaryHandlerTests.java | 69 ------ .../java/handlers/ThrottledHandlerTests.java | 224 ------------------ .../handlers/predicate/RootHandlerTest.java | 50 ++++ .../temporary/TemporaryFirstTest.java | 42 ++++ .../handlers/temporary/TemporaryTimeTest.java | 44 ++++ .../throttler/ExchangeThrottlerTest.java | 71 ++++++ .../ServerExchangeThrottlerTest.java | 67 ++++++ .../throttler/ServerSessionThrottlerTest.java | 72 ++++++ .../throttler/SessionThrottlerTest.java | 72 ++++++ .../io/SimpleHttpExchangePostTest.java | 2 +- .../SimpleHttpServerContextTests.java | 1 - 23 files changed, 477 insertions(+), 376 deletions(-) delete mode 100644 src/test/java/handlers/TemporaryHandlerTests.java delete mode 100644 src/test/java/handlers/ThrottledHandlerTests.java create mode 100644 src/test/java/handlers/predicate/RootHandlerTest.java create mode 100644 src/test/java/handlers/temporary/TemporaryFirstTest.java create mode 100644 src/test/java/handlers/temporary/TemporaryTimeTest.java create mode 100644 src/test/java/handlers/throttler/ExchangeThrottlerTest.java create mode 100644 src/test/java/handlers/throttler/ServerExchangeThrottlerTest.java create mode 100644 src/test/java/handlers/throttler/ServerSessionThrottlerTest.java create mode 100644 src/test/java/handlers/throttler/SessionThrottlerTest.java diff --git a/pom.xml b/pom.xml index a3da54d..3b2505a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.kttdevelopment simplehttpserver - 03.05.07 + 03.05.08 jar https://github.com/Ktt-Development/simplehttpserver diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpCookie.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpCookie.java index 290466d..7ecb5a3 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpCookie.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpCookie.java @@ -9,7 +9,7 @@ * @see SimpleHttpExchange * @see Builder * @since 02.00.00 - * @version 03.05.00 + * @version 03.05.08 * @author Ktt Development */ public class SimpleHttpCookie { @@ -61,7 +61,6 @@ private SimpleHttpCookie(final String name, final String value, final String dom this.httpOnly = httpOnly; } - @SuppressWarnings("SpellCheckingInspection") private final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); /** diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServer.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServer.java index 01e1c0c..0d16fd8 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServer.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServer.java @@ -17,7 +17,7 @@ * @see SimpleHttpsServer * @see SimpleHttpHandler * @since 02.00.00 - * @version 03.05.02 + * @version 03.05.08 * @author Ktt Development */ @SuppressWarnings("SpellCheckingInspection") @@ -270,12 +270,15 @@ public static SimpleHttpServer create(final int port, final int backlog) throws /** * Creates an empty context. + *
+ * * {@link HttpServer} often does not throw an exception for duplicate contexts. #86 * * @param context the context * @return the http context associated with the context - * @throws IllegalArgumentException if the context is invalid or taken + * @throws IllegalArgumentException if the context is invalid or taken* * @throws NullPointerException if the context is null * + * * @see HttpContext * @see #createContext(String, HttpHandler) * @see #removeContext(String) @@ -287,11 +290,13 @@ public static SimpleHttpServer create(final int port, final int backlog) throws /** * Creates a context mapped to a specified {@link HttpHandler}. + *
+ * * {@link HttpServer} often does not throw an exception for duplicate contexts. #86 * * @param context the context * @param handler the handler * @return the http context associated with the context - * @throws IllegalArgumentException if the context is invalid or taken + * @throws IllegalArgumentException if the context is invalid or taken* * @throws NullPointerException if the context is null * * @see HttpContext @@ -308,11 +313,13 @@ public static SimpleHttpServer create(final int port, final int backlog) throws /** * Creates a context mapped to a specific {@link HttpContext} with an {@link Authenticator}. + *
+ * * {@link HttpServer} often does not throw an exception for duplicate contexts. #86 * * @param context the context * @param authenticator authenticator * @return the http context associated with the context - * @throws IllegalArgumentException if the context is invalid or taken + * @throws IllegalArgumentException if the context is invalid or taken* * @throws NullPointerException if the context is null * * @see HttpContext @@ -327,12 +334,14 @@ public static SimpleHttpServer create(final int port, final int backlog) throws /** * Creates a context mapped to a specific {@link HttpContext} with an {@link Authenticator}. + *
+ * * {@link HttpServer} often does not throw an exception for duplicate contexts. #86 * * @param context the context * @param handler the handler * @param authenticator authenticator * @return the http context associated with the context - * @throws IllegalArgumentException if the context is invalid or taken + * @throws IllegalArgumentException if the context is invalid or taken* * @throws NullPointerException if the context is null * * @see HttpContext diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java index 3a5760d..e8c0110 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java @@ -7,14 +7,13 @@ import java.net.InetSocketAddress; import java.util.*; import java.util.concurrent.Executor; -import java.util.function.BiConsumer; /** * Implementation for {@link SimpleHttpServer}. Applications do not use this class. * * @see SimpleHttpServer * @since 02.00.00 - * @version 03.05.03 + * @version 03.05.08 * @author Ktt Development */ @SuppressWarnings("SpellCheckingInspection") diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpsServerImpl.java b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpsServerImpl.java index 66b9853..4aad723 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpsServerImpl.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpsServerImpl.java @@ -13,7 +13,7 @@ * * @see SimpleHttpsServer * @since 03.04.00 - * @version 03.05.03 + * @version 03.05.08 * @author Ktt Development */ @SuppressWarnings("SpellCheckingInspection") @@ -73,7 +73,7 @@ public final HttpsConfigurator getHttpsConfigurator(){ return server.getHttpsConfigurator(); } - // region copySimpleHttpServerImpl +// region copy @Override public synchronized final InetSocketAddress bind(final int port) throws IOException{ @@ -159,7 +159,8 @@ public synchronized final HttpContext createContext(final String context, final @Override public synchronized final HttpContext createContext(final String context, final HttpHandler handler, final Authenticator authenticator){ - if(!ContextUtil.getContext(context,true,false).equals("/") && handler instanceof RootHandler) + final String ct = ContextUtil.getContext(context,true,false); + if(!ct.equals("/") && handler instanceof RootHandler) throw new IllegalArgumentException("RootHandler can only be used at the root '/' context"); final HttpHandler wrapper = exchange -> { @@ -167,7 +168,9 @@ public synchronized final HttpContext createContext(final String context, final handler.handle(exchange); }; - final HttpContext hc = server.createContext(ContextUtil.getContext(context,true,false),wrapper); + final HttpContext hc = server.createContext(ct); + + hc.setHandler(wrapper); contexts.put(hc,handler); if(authenticator != null) @@ -264,7 +267,7 @@ public synchronized final void stop(final int delay){ } } - // endregion +// endregion copy @Override public String toString(){ diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/handler/DirectoryEntry.java b/src/main/java/com/kttdevelopment/simplehttpserver/handler/DirectoryEntry.java index d7f472a..0a43adf 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/handler/DirectoryEntry.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/handler/DirectoryEntry.java @@ -21,6 +21,7 @@ * @version 03.05.06 * @author Ktt Development */ +@SuppressWarnings("SpellCheckingInspection") class DirectoryEntry { private final File directory; diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/var/HttpCode.java b/src/main/java/com/kttdevelopment/simplehttpserver/var/HttpCode.java index d066284..49a8bdd 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/var/HttpCode.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/var/HttpCode.java @@ -7,7 +7,7 @@ * @version 01.00.00 * @author Ktt Development */ -@SuppressWarnings({"unused", "SpellCheckingInspection"}) +@SuppressWarnings({"unused", "SpellCheckingInspection", "RedundantSuppression"}) public abstract class HttpCode { public static final int HTTP_Continue = 100; diff --git a/src/main/java/com/kttdevelopment/simplehttpserver/var/RequestMethod.java b/src/main/java/com/kttdevelopment/simplehttpserver/var/RequestMethod.java index a6487e2..07001e1 100644 --- a/src/main/java/com/kttdevelopment/simplehttpserver/var/RequestMethod.java +++ b/src/main/java/com/kttdevelopment/simplehttpserver/var/RequestMethod.java @@ -7,7 +7,6 @@ * @version 01.00.00 * @author Ktt Development */ -@SuppressWarnings("SpellCheckingInspection") public enum RequestMethod { GET, HEAD, diff --git a/src/test/java/handlers/FileHandlerTests.java b/src/test/java/handlers/FileHandlerTests.java index 1019668..e2ff39d 100644 --- a/src/test/java/handlers/FileHandlerTests.java +++ b/src/test/java/handlers/FileHandlerTests.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; +@SuppressWarnings("SpellCheckingInspection") public class FileHandlerTests { @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/src/test/java/handlers/PredicateHandlerTests.java b/src/test/java/handlers/PredicateHandlerTests.java index 6088693..6c513d6 100644 --- a/src/test/java/handlers/PredicateHandlerTests.java +++ b/src/test/java/handlers/PredicateHandlerTests.java @@ -3,7 +3,6 @@ import com.kttdevelopment.simplehttpserver.SimpleHttpHandler; import com.kttdevelopment.simplehttpserver.SimpleHttpServer; import com.kttdevelopment.simplehttpserver.handler.PredicateHandler; -import com.kttdevelopment.simplehttpserver.handler.RootHandler; import org.junit.Assert; import org.junit.Test; @@ -12,11 +11,11 @@ import java.net.http.*; import java.util.concurrent.ExecutionException; -public class PredicateHandlerTests { +public final class PredicateHandlerTests { @Test public void predicate() throws IOException, ExecutionException, InterruptedException{ - final int port = 30004; + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); @@ -28,52 +27,18 @@ public void predicate() throws IOException, ExecutionException, InterruptedExcep Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); - String url = "http://localhost:" + port + context; + final String url = "http://localhost:" + port + context; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); Assert.assertEquals("Server response did not match client response", condition ? "A" : "B", response); server.stop(); } - @Test - public void root() throws IOException, ExecutionException, InterruptedException{ - final int port = 30005; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - String context = ""; - server.createContext(context,new RootHandler((SimpleHttpHandler) exchange -> exchange.send("A"), (SimpleHttpHandler) exchange -> exchange.send("B"))); - server.start(); - - Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); - - String url = "http://localhost:" + port; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Server root response did not match client root response","A",response); - - request = HttpRequest.newBuilder() - .uri(URI.create(url + server.getRandomContext())) - .build(); - - response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Server else response did not match client else response","B",response); - - server.stop(); - } - } diff --git a/src/test/java/handlers/RedirectHandlerTests.java b/src/test/java/handlers/RedirectHandlerTests.java index 21fe758..a730881 100644 --- a/src/test/java/handlers/RedirectHandlerTests.java +++ b/src/test/java/handlers/RedirectHandlerTests.java @@ -11,11 +11,11 @@ import java.net.http.*; import java.util.concurrent.ExecutionException; -public class RedirectHandlerTests { +public final class RedirectHandlerTests { @Test - public void redirectToGoogle() throws IOException, ExecutionException, InterruptedException{ - final int port = 30003; + public final void redirectToGoogle() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); @@ -25,16 +25,16 @@ public void redirectToGoogle() throws IOException, ExecutionException, Interrupt Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); - String url = "http://localhost:" + port + context; + final String url = "http://localhost:" + port + context; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); final HttpClient client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build(); - int response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); + final int response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); Assert.assertEquals("Client responded with redirect code (302 HTTP FOUND) not 200 HTTP OK",HttpCode.HTTP_OK, response); diff --git a/src/test/java/handlers/SSEHandlerTests.java b/src/test/java/handlers/SSEHandlerTests.java index 0ef0347..08cfca6 100644 --- a/src/test/java/handlers/SSEHandlerTests.java +++ b/src/test/java/handlers/SSEHandlerTests.java @@ -10,12 +10,12 @@ import java.time.Duration; import java.util.concurrent.*; -public class SSEHandlerTests { +public final class SSEHandlerTests { @SuppressWarnings({"unchecked", "Convert2Lambda", "rawtypes"}) @Test - public void test() throws IOException, ExecutionException, InterruptedException{ - final int port = 30006; + public final void test() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); String context = ""; @@ -25,9 +25,9 @@ public void test() throws IOException, ExecutionException, InterruptedException{ server.start(); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://localhost:" + port)) - .timeout(Duration.ofSeconds(2)) - .build(); + .uri(URI.create("http://localhost:" + port)) + .timeout(Duration.ofSeconds(2)) + .build(); final HttpClient client = HttpClient.newHttpClient(); HttpResponse response = client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).get(); @@ -35,18 +35,18 @@ public void test() throws IOException, ExecutionException, InterruptedException{ final String result = "result"; handler.push(result); - BufferedReader IN = new BufferedReader(new InputStreamReader(response.body())); - StringBuilder OUT = new StringBuilder(); + final BufferedReader IN = new BufferedReader(new InputStreamReader(response.body())); + final StringBuilder OUT = new StringBuilder(); final Duration dur = Duration.ofSeconds(2); final ExecutorService executor = Executors.newSingleThreadExecutor(); final Future future = executor.submit(new Callable() { @Override - public String call(){ + public final String call(){ String ln; try{ while((ln = IN.readLine()) != null) - OUT.append(ln).append('\n'); + OUT.append(ln).append('\n'); }catch(final IOException ignored){ Assert.fail("Unable to read input stream from client"); } @@ -54,9 +54,10 @@ public String call(){ } }); - try { + try{ future.get(dur.toMillis(), TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { + }catch(final TimeoutException ignored){ + }finally{ future.cancel(true); } diff --git a/src/test/java/handlers/TemporaryHandlerTests.java b/src/test/java/handlers/TemporaryHandlerTests.java deleted file mode 100644 index 2a12474..0000000 --- a/src/test/java/handlers/TemporaryHandlerTests.java +++ /dev/null @@ -1,69 +0,0 @@ -package handlers; - -import com.kttdevelopment.simplehttpserver.*; -import com.kttdevelopment.simplehttpserver.handler.TemporaryHandler; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.net.URI; -import java.net.http.*; -import java.util.concurrent.ExecutionException; - -public class TemporaryHandlerTests { - - @Test - public void testTime() throws IOException, InterruptedException, ExecutionException{ - final int port = 30001; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - - final String context = ""; - server.createContext(context,new TemporaryHandler(server,(SimpleHttpHandler) SimpleHttpExchange::close, 1000)); - server.start(); - - Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); - - Thread.sleep(2000); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - - Assert.assertTrue("Server did not remove temporary context", server.getContexts().isEmpty()); - - server.stop(); - } - - @Test - public void testFirstConn() throws ExecutionException, InterruptedException, IOException{ - final int port = 30002; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - - final String context = ""; - server.createContext(context,new TemporaryHandler(server,(SimpleHttpHandler) SimpleHttpExchange::close)); - server.start(); - - Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - - Assert.assertTrue("Server did not remove temporary context", server.getContexts().isEmpty()); - - server.stop(); - } - -} diff --git a/src/test/java/handlers/ThrottledHandlerTests.java b/src/test/java/handlers/ThrottledHandlerTests.java deleted file mode 100644 index 010d0b7..0000000 --- a/src/test/java/handlers/ThrottledHandlerTests.java +++ /dev/null @@ -1,224 +0,0 @@ -package handlers; - -import com.kttdevelopment.simplehttpserver.*; -import com.kttdevelopment.simplehttpserver.handler.*; -import com.sun.net.httpserver.HttpExchange; -import org.junit.*; - -import java.io.IOException; -import java.net.URI; -import java.net.http.*; -import java.time.Duration; -import java.util.concurrent.*; - -public class ThrottledHandlerTests { - - @Test - public void sessionThrottler() throws IOException{ - final int port = 30010; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - final HttpSessionHandler sessionHandler = new HttpSessionHandler(); - server.setHttpSessionHandler(sessionHandler); - - final String context = ""; - server.createContext( - context, - new ThrottledHandler( - (SimpleHttpHandler) exchange -> { - try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); - }catch(final InterruptedException ignored){ } - exchange.send(exchange.toString()); - }, - new SessionThrottler(sessionHandler){ - @Override - public int getMaxConnections(final HttpSession session, final HttpExchange exchange){ - return 1; - } - } - ) - ); - server.start(); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .timeout(Duration.ofSeconds(1)) - .build(); - - new Thread(() -> { - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException ignored){ } - }).start(); - - Exception exception = null; - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch - exception = e; - } - Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)",exception instanceof ExecutionException); - - server.stop(); - } - - @Test - public void serverSessionThrottler() throws IOException{ - final int port = 30015; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - final HttpSessionHandler sessionHandler = new HttpSessionHandler(); - server.setHttpSessionHandler(sessionHandler); - - final String context = ""; - server.createContext( - context, - new ThrottledHandler( - (SimpleHttpHandler) exchange -> { - try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); - }catch(final InterruptedException ignored){ } - exchange.send(exchange.toString()); - }, - new ServerSessionThrottler(sessionHandler){ - @Override - public int getMaxConnections(final HttpSession session, final HttpExchange exchange){ - return 1; - } - } - ) - ); - server.start(); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .timeout(Duration.ofSeconds(1)) - .build(); - - new Thread(() -> { - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException ignored){ } - }).start(); - - Exception exception = null; - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch - exception = e; - } - Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)",exception instanceof ExecutionException); - - server.stop(); - } - - @Test - public void exchangeThrottler() throws IOException{ - final int port = 30012; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - - final String context = ""; - server.createContext( - context, - new ThrottledHandler( - (SimpleHttpHandler) exchange -> { - try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); - }catch(final InterruptedException ignored){ } - exchange.send(exchange.toString()); - }, - new ExchangeThrottler(){ - @Override - public int getMaxConnections(final HttpExchange exchange){ - return 1; - } - } - ) - ); - server.start(); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .timeout(Duration.ofSeconds(1)) - .build(); - - new Thread(() -> { - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException ignored){ } - }).start(); - - Exception exception = null; - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch - exception = e; - } - Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)",exception instanceof ExecutionException); - - server.stop(); - } - - @Test - public void serverExchangeThrottler() throws IOException{ - final int port = 30013; - - final SimpleHttpServer server = SimpleHttpServer.create(port); - - final String context = ""; - server.createContext( - context, - new ThrottledHandler( - (SimpleHttpHandler) exchange -> { - try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); - }catch(final InterruptedException ignored){ } - exchange.send(exchange.toString()); - }, - new ServerExchangeThrottler(){ - @Override - public int getMaxConnections(final HttpExchange exchange){ - return 1; - } - } - ) - ); - server.start(); - - String url = "http://localhost:" + port + context; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .timeout(Duration.ofSeconds(1)) - .build(); - - new Thread(() -> { - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException ignored){ } - }).start(); - - Exception exception = null; - try{ - HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::statusCode).get(); - }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch - exception = e; - } - Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)",exception instanceof ExecutionException); - - server.stop(); - } - -} diff --git a/src/test/java/handlers/predicate/RootHandlerTest.java b/src/test/java/handlers/predicate/RootHandlerTest.java new file mode 100644 index 0000000..e62c053 --- /dev/null +++ b/src/test/java/handlers/predicate/RootHandlerTest.java @@ -0,0 +1,50 @@ +package handlers.predicate; + +import com.kttdevelopment.simplehttpserver.SimpleHttpHandler; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.RootHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public final class RootHandlerTest { + + @Test + public final void root() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final String context = ""; + server.createContext(context,new RootHandler((SimpleHttpHandler) exchange -> exchange.send("A"), (SimpleHttpHandler) exchange -> exchange.send("B"))); + server.start(); + + Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); + + final String url = "http://localhost:" + port; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Server root response did not match client root response","A",response); + + request = HttpRequest.newBuilder() + .uri(URI.create(url + server.getRandomContext())) + .build(); + + response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Server else response did not match client else response","B",response); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/temporary/TemporaryFirstTest.java b/src/test/java/handlers/temporary/TemporaryFirstTest.java new file mode 100644 index 0000000..9046919 --- /dev/null +++ b/src/test/java/handlers/temporary/TemporaryFirstTest.java @@ -0,0 +1,42 @@ +package handlers.temporary; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.handler.TemporaryHandler; +import com.sun.net.httpserver.HttpExchange; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public class TemporaryFirstTest { + + @Test + public void testFirstConn() throws ExecutionException, InterruptedException, IOException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + + final String context = ""; + server.createContext(context,new TemporaryHandler(server, HttpExchange::close)); + server.start(); + + Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + + Assert.assertTrue("Server did not remove temporary context", server.getContexts().isEmpty()); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/temporary/TemporaryTimeTest.java b/src/test/java/handlers/temporary/TemporaryTimeTest.java new file mode 100644 index 0000000..b5a57fc --- /dev/null +++ b/src/test/java/handlers/temporary/TemporaryTimeTest.java @@ -0,0 +1,44 @@ +package handlers.temporary; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.handler.TemporaryHandler; +import com.sun.net.httpserver.HttpExchange; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public final class TemporaryTimeTest { + + @Test + public final void testTime() throws IOException, InterruptedException, ExecutionException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + + final String context = ""; + server.createContext(context,new TemporaryHandler(server, HttpExchange::close, 1000)); + server.start(); + + Assert.assertFalse("Server did not contain a temporary context", server.getContexts().isEmpty()); + + Thread.sleep(2000); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + + Assert.assertTrue("Server did not remove temporary context", server.getContexts().isEmpty()); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/throttler/ExchangeThrottlerTest.java b/src/test/java/handlers/throttler/ExchangeThrottlerTest.java new file mode 100644 index 0000000..670d9ac --- /dev/null +++ b/src/test/java/handlers/throttler/ExchangeThrottlerTest.java @@ -0,0 +1,71 @@ +package handlers.throttler; + +import com.kttdevelopment.simplehttpserver.SimpleHttpHandler; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.ExchangeThrottler; +import com.kttdevelopment.simplehttpserver.handler.ThrottledHandler; +import com.sun.net.httpserver.HttpExchange; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.time.Duration; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public final class ExchangeThrottlerTest { + + @Test + public void exchangeThrottler() throws IOException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + + final String context = ""; + server.createContext( + context, + new ThrottledHandler( + (SimpleHttpHandler) exchange -> { + try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + }catch(final InterruptedException ignored){ } + exchange.send(exchange.toString()); + }, + new ExchangeThrottler(){ + @Override + public final int getMaxConnections(final HttpExchange exchange){ + return 1; + } + } + ) + ); + server.start(); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(Duration.ofSeconds(1)) + .build(); + + new Thread(() -> { + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException ignored){ } + }).start(); + + Exception exception = null; + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch + exception = e; + } + Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)", exception instanceof ExecutionException); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/throttler/ServerExchangeThrottlerTest.java b/src/test/java/handlers/throttler/ServerExchangeThrottlerTest.java new file mode 100644 index 0000000..0bee099 --- /dev/null +++ b/src/test/java/handlers/throttler/ServerExchangeThrottlerTest.java @@ -0,0 +1,67 @@ +package handlers.throttler; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.handler.*; +import com.sun.net.httpserver.HttpExchange; +import org.junit.*; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.time.Duration; +import java.util.concurrent.*; + +public final class ServerExchangeThrottlerTest { + + @Test + public final void serverExchangeThrottler() throws IOException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + + final String context = ""; + server.createContext( + context, + new ThrottledHandler( + (SimpleHttpHandler) exchange -> { + try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + }catch(final InterruptedException ignored){ } + exchange.send(exchange.toString()); + }, + new ServerExchangeThrottler(){ + @Override + public final int getMaxConnections(final HttpExchange exchange){ + return 1; + } + } + ) + ); + server.start(); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(Duration.ofSeconds(1)) + .build(); + + new Thread(() -> { + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException ignored){ } + }).start(); + + Exception exception = null; + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch + exception = e; + } + Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)",exception instanceof ExecutionException); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/throttler/ServerSessionThrottlerTest.java b/src/test/java/handlers/throttler/ServerSessionThrottlerTest.java new file mode 100644 index 0000000..06b3de4 --- /dev/null +++ b/src/test/java/handlers/throttler/ServerSessionThrottlerTest.java @@ -0,0 +1,72 @@ +package handlers.throttler; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.handler.ServerSessionThrottler; +import com.kttdevelopment.simplehttpserver.handler.ThrottledHandler; +import com.sun.net.httpserver.HttpExchange; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.time.Duration; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public final class ServerSessionThrottlerTest { + + @Test + public final void serverSessionThrottler() throws IOException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final HttpSessionHandler sessionHandler = new HttpSessionHandler(); + server.setHttpSessionHandler(sessionHandler); + + final String context = ""; + server.createContext( + context, + new ThrottledHandler( + (SimpleHttpHandler) exchange -> { + try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + }catch(final InterruptedException ignored){ } + exchange.send(exchange.toString()); + }, + new ServerSessionThrottler(sessionHandler){ + @Override + public final int getMaxConnections(final HttpSession session, final HttpExchange exchange){ + return 1; + } + } + ) + ); + server.start(); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(Duration.ofSeconds(1)) + .build(); + + new Thread(() -> { + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException ignored){ } + }).start(); + + Exception exception = null; + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch + exception = e; + } + Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)", exception instanceof ExecutionException); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/throttler/SessionThrottlerTest.java b/src/test/java/handlers/throttler/SessionThrottlerTest.java new file mode 100644 index 0000000..83e5e63 --- /dev/null +++ b/src/test/java/handlers/throttler/SessionThrottlerTest.java @@ -0,0 +1,72 @@ +package handlers.throttler; + +import com.kttdevelopment.simplehttpserver.*; +import com.kttdevelopment.simplehttpserver.handler.SessionThrottler; +import com.kttdevelopment.simplehttpserver.handler.ThrottledHandler; +import com.sun.net.httpserver.HttpExchange; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.time.Duration; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public final class SessionThrottlerTest { + + @Test + public final void sessionThrottler() throws IOException{ + final int port = 8080; + + final SimpleHttpServer server = SimpleHttpServer.create(port); + final HttpSessionHandler sessionHandler = new HttpSessionHandler(); + server.setHttpSessionHandler(sessionHandler); + + final String context = ""; + server.createContext( + context, + new ThrottledHandler( + (SimpleHttpHandler) exchange -> { + try{ Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + }catch(final InterruptedException ignored){ } + exchange.send(exchange.toString()); + }, + new SessionThrottler(sessionHandler){ + @Override + public final int getMaxConnections(final HttpSession session, final HttpExchange exchange){ + return 1; + } + } + ) + ); + server.start(); + + final String url = "http://localhost:" + port + context; + + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(Duration.ofSeconds(1)) + .build(); + + new Thread(() -> { + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException ignored){ } + }).start(); + + Exception exception = null; + try{ + HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::statusCode).get(); + }catch(final InterruptedException | ExecutionException e){ // JDK failure to recognize HttpTimeoutException as valid catch + exception = e; + } + Assert.assertTrue("Second request returned a result for a throttled thread (connection not allowed)", exception instanceof ExecutionException); + + server.stop(); + } + +} diff --git a/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java b/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java index d209840..afb9074 100644 --- a/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java +++ b/src/test/java/simplehttpexchange/io/SimpleHttpExchangePostTest.java @@ -15,7 +15,7 @@ public final class SimpleHttpExchangePostTest { @Test - public void postSimple() throws IOException, ExecutionException, InterruptedException{ + public final void postSimple() throws IOException, ExecutionException, InterruptedException{ final int port = 20003; final SimpleHttpServer server = SimpleHttpServer.create(port); diff --git a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java index eb36ad7..f9f77c3 100644 --- a/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java +++ b/src/test/java/simplehttpserver/SimpleHttpServerContextTests.java @@ -3,7 +3,6 @@ import com.kttdevelopment.simplehttpserver.*; import com.kttdevelopment.simplehttpserver.handler.RootHandler; import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpServer; import org.junit.Assert; import org.junit.Test; From 9685b3d4faa3b4e233646f41415cf7317f0b7812 Mon Sep 17 00:00:00 2001 From: Katsute <58778985+Katsute@users.noreply.github.com> Date: Thu, 27 Aug 2020 20:32:53 -0400 Subject: [PATCH 7/7] File tests --- src/test/java/handlers/FileHandlerTests.java | 381 ------------------ .../handlers/file/FileHandlerAddDirTest.java | 96 +++++ .../file/FileHandlerAddFilesTest.java | 80 ++++ .../handlers/file/FileHandlerAddTest.java | 81 ++++ .../handlers/file/FileHandlerNoWalkTest.java | 108 +++++ .../handlers/file/FileHandlerWalkTest.java | 87 ++++ .../temporary/TemporaryFirstTest.java | 4 +- .../nowalk/dirnoread/innerNoRead.txt | 1 - src/test/resources/directory/nowalk/test.txt | 1 - src/test/resources/files/test.txt | 1 - src/test/resources/files/test2.txt | 1 - 11 files changed, 454 insertions(+), 387 deletions(-) delete mode 100644 src/test/java/handlers/FileHandlerTests.java create mode 100644 src/test/java/handlers/file/FileHandlerAddDirTest.java create mode 100644 src/test/java/handlers/file/FileHandlerAddFilesTest.java create mode 100644 src/test/java/handlers/file/FileHandlerAddTest.java create mode 100644 src/test/java/handlers/file/FileHandlerNoWalkTest.java create mode 100644 src/test/java/handlers/file/FileHandlerWalkTest.java delete mode 100644 src/test/resources/directory/nowalk/dirnoread/innerNoRead.txt delete mode 100644 src/test/resources/directory/nowalk/test.txt delete mode 100644 src/test/resources/files/test.txt delete mode 100644 src/test/resources/files/test2.txt diff --git a/src/test/java/handlers/FileHandlerTests.java b/src/test/java/handlers/FileHandlerTests.java deleted file mode 100644 index e2ff39d..0000000 --- a/src/test/java/handlers/FileHandlerTests.java +++ /dev/null @@ -1,381 +0,0 @@ -package handlers; - -import com.kttdevelopment.simplehttpserver.SimpleHttpServer; -import com.kttdevelopment.simplehttpserver.handler.*; -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.http.*; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -@SuppressWarnings("SpellCheckingInspection") -public class FileHandlerTests { - - @SuppressWarnings("ResultOfMethodCallIgnored") - @Test - public void addFileTests() throws IOException{ - final int port = 25001; - final SimpleHttpServer server = SimpleHttpServer.create(port); - final FileHandler handler = new FileHandler(); - final String context = ""; - - final File dir = new File("src/test/resources/file"); - - final Map files = new HashMap<>(); - for(final ByteLoadingOption blop : ByteLoadingOption.values()) - files.put(new File(dir.getPath() + '/' + blop.name() + ".txt"),blop); - - // initial write - final String init = String.valueOf(System.currentTimeMillis()); - files.forEach((file, loadingOption) -> { - if(!file.exists() || file.delete()){ - try{ - if((file.getParentFile().mkdirs() || file.getParentFile().isDirectory()) && file.createNewFile()) - Files.write(file.toPath(), init.getBytes()); - else - Assert.fail("Failed to create new file for testing: " + file.getPath()); - }catch(final Exception ignored){ - Assert.fail("Failed to create new file for testing: " + file.getPath()); - } - - handler.addFile(file, loadingOption); - }else{ - Assert.fail("Failed to clear file for testing: " + file.getPath()); - } - }); - - server.createContext(context,handler); - server.start(); - - files.forEach((file, loadingOption) -> { - final String url = "http://localhost:" + port + context + '/' + file.getName(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Client data did not match server data for " + file.getName(),init,response); - }catch(final InterruptedException | ExecutionException ignored){ - Assert.fail("Failed to read context of " + file.getName()); - } - - // second write - - final String after = String.valueOf(System.currentTimeMillis()); - try{ - Files.write(file.toPath(), after.getBytes()); - }catch(final Exception ignored){ - Assert.fail("Failed to second write file " + file.getPath()); - } - - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Client data did not match server data for " + file.getName(),loadingOption == ByteLoadingOption.PRELOAD ? init : after,response); - }catch(final InterruptedException | ExecutionException ignored){ - Assert.fail("Failed to read context " + file.getName()); - } - }); - - files.forEach((file, loadingOption) -> file.delete()); - - server.stop(); - } - - @Test - public void addFilesTests() throws IOException, ExecutionException, InterruptedException{ // run adapter tests here - final int port = 25002; - final SimpleHttpServer server = SimpleHttpServer.create(port); - final String override = "override"; - final String context = "", altContext = "/alt"; - final FileHandlerAdapter adapter = new FileHandlerAdapter() { - @Override - public byte[] getBytes(final File file, final byte[] bytes){ - return override.getBytes(); - } - - @Override - public String getName(final File file){ - return file.getName().substring(0,file.getName().lastIndexOf('.')); - } - }; - final FileHandler handler = new FileHandler(adapter); - - final File[] files = new File[]{ - new File("src/test/resources/files/test.txt"), - new File("src/test/resources/files/test2.txt") - }; - - handler.addFiles(files); - handler.addFiles(altContext,files); - - server.createContext(context,handler); - - server.start(); - - for(final File file : files){ - String url = "http://localhost:" + port + context; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url + "/" + file.getName().substring(0,file.getName().lastIndexOf('.')))) - .build(); - - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Adapter bytes did not match client received bytes",override,response); - - // alt - - String altUrl = "http://localhost:" + port + altContext; - request = HttpRequest.newBuilder() - .uri(URI.create(altUrl + "/" + file.getName().substring(0,file.getName().lastIndexOf('.')))) - .build(); - - response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertEquals("Adapter alt context bytes did not match client received bytes",override,response); - } - - server.stop(); - - } - - @Test - public void addDirectoryTestsNoWalk() throws IOException, InterruptedException{ - final int port = 25003; - final SimpleHttpServer server = SimpleHttpServer.create(port); - final FileHandler handler = new FileHandler(); - final String contextNoName = "alt"; - final String contextWName = "altn"; - final String dirNewName = "dirName"; - - final String testRealFile = "test.txt", testFileContent = "readme"; - final String noReadDir = "dirnoread"; - final String noReadFile = "innerNoRead.txt"; - - final File noWalk = new File("src/test/resources/directory/nowalk"); - - final String context = ""; - - handler.addDirectory(noWalk); // test file & directory read - handler.addDirectory(contextNoName,noWalk); - handler.addDirectory(noWalk,dirNewName); - handler.addDirectory(contextWName,noWalk,dirNewName); - - server.createContext(context,handler); - server.start(); - - final String[] validPathsToTest = { // valid reads - noWalk.getName() + '/' + testRealFile, - contextNoName + '/' + noWalk.getName() + '/' + testRealFile, - dirNewName + '/' + testRealFile, - contextWName + '/' + dirNewName + '/' + testRealFile - }; - - for(final String path : validPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNotNull("Client did not find data for " + path,response); - Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); - }catch(final ExecutionException ignored){ - Assert.fail("Client did not find data for " + path); - } - } - - final String[] invalidPathsToTest = { - noWalk.getName() + '/' + noReadDir, - noWalk.getName() + '/' + noReadDir + '/' + noReadFile - }; - - for(final String path : invalidPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - Exception exception = null; - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNull("Client found data for blocked path " + path,response); - }catch(final ExecutionException e){ - exception = e; - } - Assert.assertNotNull("Client found data for blocked path",exception); - } - - server.stop(); - } - - @Test - public void addDirectoryTestsNoWalkAdapter() throws IOException, InterruptedException{ - final int port = 25022; - final SimpleHttpServer server = SimpleHttpServer.create(port); - final FileHandlerAdapter adapter = new FileHandlerAdapter() { - @Override - public byte[] getBytes(final File file, final byte[] bytes){ - return bytes; - } - - @Override - public String getName(final File file){ - return file.getName().substring(0,file.getName().lastIndexOf('.')); - } - }; - final FileHandler handler = new FileHandler(adapter); - final String contextNoName = "alt"; - final String contextWName = "altn"; - final String dirNewName = "dirName"; - - final String testRealFile = "test", testFileContent = "readme"; - final String noReadDir = "dirnoread"; - final String noReadFile = "innerNoRead"; - - final File noWalk = new File("src/test/resources/directory/nowalk"); - - final String context = ""; - - handler.addDirectory(noWalk); // test file & directory read - handler.addDirectory(contextNoName,noWalk); - handler.addDirectory(noWalk,dirNewName); - handler.addDirectory(contextWName,noWalk,dirNewName); - - server.createContext(context,handler); - server.start(); - - final String[] validPathsToTest = { // valid reads - noWalk.getName() + '/' + testRealFile, - contextNoName + '/' + noWalk.getName() + '/' + testRealFile, - dirNewName + '/' + testRealFile, - contextWName + '/' + dirNewName + '/' + testRealFile - }; - - for(final String path : validPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNotNull("Client did not find data for " + path,response); - Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); - }catch(final ExecutionException ignored){ - Assert.fail("Client did not find data for " + path); - } - } - - final String[] invalidPathsToTest = { - noWalk.getName() + '/' + noReadDir, - noWalk.getName() + '/' + noReadDir + '/' + noReadFile - }; - - for(final String path : invalidPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - Exception exception = null; - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNull("Client found data for blocked path " + path,response); - }catch(final ExecutionException e){ - exception = e; - } - Assert.assertNotNull("Client found data for blocked path",exception); - } - - server.stop(); - } - - @Test - public void addDirectoryTestsWalk() throws IOException, InterruptedException{ - final int port = 25004; - final SimpleHttpServer server = SimpleHttpServer.create(port); - final FileHandler handler = new FileHandler(); - - final String testRealFile = "test.txt", testFileContent = "readme"; - final String readDir = "dirnoread"; - final String innerFile = "innerNoRead.txt"; - - final File noWalk = new File("src/test/resources/directory/nowalk"); - - final String context = ""; - - handler.addDirectory(noWalk,true); - - server.createContext(context,handler); - server.start(); - - final String[] validPathsToTest = { // valid reads - noWalk.getName() + '/' + testRealFile, - noWalk.getName() + '/' + readDir + '/' + innerFile - }; - - for(final String path : validPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNotNull("Client did not find data for " + path,response); - Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); - }catch(final ExecutionException ignored){ - Assert.fail("Client did not find data for " + path); - } - } - - final String[] invalidPathsToTest = { - noWalk.getName() + '/' + readDir - }; - - for(final String path : invalidPathsToTest){ - String url = "http://localhost:" + port + '/' + path; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); - - Exception exception = null; - try{ - String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body).get(); - - Assert.assertNull("Client found data for blocked path " + path,response); - }catch(final ExecutionException e){ - exception = e; - } - Assert.assertNotNull("Client found data for blocked path",exception); - } - - server.stop(); - } - -} diff --git a/src/test/java/handlers/file/FileHandlerAddDirTest.java b/src/test/java/handlers/file/FileHandlerAddDirTest.java new file mode 100644 index 0000000..34b9ca7 --- /dev/null +++ b/src/test/java/handlers/file/FileHandlerAddDirTest.java @@ -0,0 +1,96 @@ +package handlers.file; + +import com.kttdevelopment.core.tests.TestUtil; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.FileHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public final class FileHandlerAddDirTest { + + @SuppressWarnings("SpellCheckingInspection") + @Test + public final void addDirectoryTestsNoWalk() throws IOException, InterruptedException{ + final int port = 8080; + final SimpleHttpServer server = SimpleHttpServer.create(port); + final FileHandler handler = new FileHandler(); + final String contextNoName = "alt"; + final String contextWName = "altn"; + final String dirNewName = "dirName"; + + final String testRealFile = "test.txt", testFileContent = "readme"; + final String noReadDir = "dirnoread"; + final String noReadFile = "innerNoRead.txt"; + + final File noWalk = new File("src/test/resources/directory/nowalk"); + + TestUtil.createTestFile(new File(noWalk,testRealFile),testFileContent); + TestUtil.createTestFile(new File(new File(noWalk,noReadDir),noReadFile),testFileContent); + + final String context = ""; + + handler.addDirectory(noWalk); // test file & directory read + handler.addDirectory(contextNoName,noWalk); + handler.addDirectory(noWalk,dirNewName); + handler.addDirectory(contextWName,noWalk,dirNewName); + + server.createContext(context,handler); + server.start(); + + final String[] validPathsToTest = { // valid reads + noWalk.getName() + '/' + testRealFile, + contextNoName + '/' + noWalk.getName() + '/' + testRealFile, + dirNewName + '/' + testRealFile, + contextWName + '/' + dirNewName + '/' + testRealFile + }; + + for(final String path : validPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNotNull("Client did not find data for " + path, response); + Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); + }catch(final ExecutionException ignored){ + Assert.fail("Client did not find data for " + path); + } + } + + final String[] invalidPathsToTest = { + noWalk.getName() + '/' + noReadDir, + noWalk.getName() + '/' + noReadDir + '/' + noReadFile + }; + + for(final String path : invalidPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + Exception exception = null; + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNull("Client found data for blocked path " + path,response); + }catch(final ExecutionException e){ + exception = e; + } + Assert.assertNotNull("Client found data for blocked path",exception); + } + + server.stop(); + } + +} diff --git a/src/test/java/handlers/file/FileHandlerAddFilesTest.java b/src/test/java/handlers/file/FileHandlerAddFilesTest.java new file mode 100644 index 0000000..c4589db --- /dev/null +++ b/src/test/java/handlers/file/FileHandlerAddFilesTest.java @@ -0,0 +1,80 @@ +package handlers.file; + +import com.kttdevelopment.core.tests.TestUtil; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.FileHandler; +import com.kttdevelopment.simplehttpserver.handler.FileHandlerAdapter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public final class FileHandlerAddFilesTest { + + @Test + public final void addFilesTests() throws IOException, ExecutionException, InterruptedException{ + final int port = 8080; + final SimpleHttpServer server = SimpleHttpServer.create(port); + final String override = "override"; + final String context = "", altContext = "/alt"; + final FileHandlerAdapter adapter = new FileHandlerAdapter() { + @Override + public final byte[] getBytes(final File file, final byte[] bytes){ + return override.getBytes(); + } + + @Override + public final String getName(final File file){ + return file.getName().substring(0,file.getName().lastIndexOf('.')); + } + }; + final FileHandler handler = new FileHandler(adapter); + + final File[] files = new File[]{ + new File("src/test/resources/files/test.txt"), + new File("src/test/resources/files/test2.txt") + }; + + for(final File file : files) + TestUtil.createTestFile(file); + + handler.addFiles(files); + handler.addFiles(altContext,files); + + server.createContext(context,handler); + + server.start(); + + for(final File file : files){ + final String url = "http://localhost:" + port + context; + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url + "/" + file.getName().substring(0, file.getName().lastIndexOf('.')))) + .build(); + + String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Adapter bytes did not match client received bytes", override, response); + + // alt + + final String altUrl = "http://localhost:" + port + altContext; + request = HttpRequest.newBuilder() + .uri(URI.create(altUrl + "/" + file.getName().substring(0,file.getName().lastIndexOf('.')))) + .build(); + + response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Adapter alt context bytes did not match client received bytes",override,response); + } + + server.stop(); + + } + +} diff --git a/src/test/java/handlers/file/FileHandlerAddTest.java b/src/test/java/handlers/file/FileHandlerAddTest.java new file mode 100644 index 0000000..45c4837 --- /dev/null +++ b/src/test/java/handlers/file/FileHandlerAddTest.java @@ -0,0 +1,81 @@ +package handlers.file; + +import com.kttdevelopment.core.tests.TestUtil; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.ByteLoadingOption; +import com.kttdevelopment.simplehttpserver.handler.FileHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +public final class FileHandlerAddTest { + + @SuppressWarnings("SpellCheckingInspection") + @Test + public final void addFileTests() throws IOException{ + final int port = 8080; + final SimpleHttpServer server = SimpleHttpServer.create(port); + final FileHandler handler = new FileHandler(); + final String context = ""; + + final File dir = new File("src/test/resources/file"); + + final Map files = new HashMap<>(); + for(final ByteLoadingOption blop : ByteLoadingOption.values()) + files.put(new File(dir, blop.name() + ".txt"),blop); + + // initial write + final String init = String.valueOf(System.currentTimeMillis()); + files.forEach((file, loadingOption) -> { + TestUtil.createTestFile(file,init); + handler.addFile(file, loadingOption); + }); + + server.createContext(context,handler); + server.start(); + + files.forEach((file, loadingOption) -> { + final String url = "http://localhost:" + port + context + '/' + file.getName(); + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + Assert.assertEquals("Client data did not match server data for " + file.getName(),init,response); + }catch(final InterruptedException | ExecutionException ignored){ + Assert.fail("Failed to read context of " + file.getName()); + } + + // second write + + final String after = String.valueOf(System.currentTimeMillis()); + try{ + Files.write(file.toPath(), after.getBytes()); + }catch(final Throwable ignored){ + Assert.fail("Failed to second write file " + file.getPath()); + } + + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertEquals("Client data did not match server data for " + file.getName(),loadingOption == ByteLoadingOption.PRELOAD ? init : after,response); + }catch(final InterruptedException | ExecutionException ignored){ + Assert.fail("Failed to read context " + file.getName()); + } + }); + + server.stop(); + } + +} diff --git a/src/test/java/handlers/file/FileHandlerNoWalkTest.java b/src/test/java/handlers/file/FileHandlerNoWalkTest.java new file mode 100644 index 0000000..d5ab237 --- /dev/null +++ b/src/test/java/handlers/file/FileHandlerNoWalkTest.java @@ -0,0 +1,108 @@ +package handlers.file; + +import com.kttdevelopment.core.tests.TestUtil; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.FileHandler; +import com.kttdevelopment.simplehttpserver.handler.FileHandlerAdapter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +public final class FileHandlerNoWalkTest { + + @SuppressWarnings("SpellCheckingInspection") + @Test + public final void addDirectoryTestsNoWalkAdapter() throws IOException, InterruptedException{ + final int port = 8080; + final SimpleHttpServer server = SimpleHttpServer.create(port); + final FileHandlerAdapter adapter = new FileHandlerAdapter() { + @Override + public final byte[] getBytes(final File file, final byte[] bytes){ + return bytes; + } + + @Override + public final String getName(final File file){ + return file.getName().substring(0,file.getName().lastIndexOf('.')); + } + }; + final FileHandler handler = new FileHandler(adapter); + final String contextNoName = "alt"; + final String contextWName = "altn"; + final String dirNewName = "dirName"; + + final String testRealFile = "test", testFileContent = "readme"; + final String noReadDir = "dirnoread"; + final String noReadFile = "innerNoRead"; + + final File noWalk = new File("src/test/resources/directory/nowalk"); + + TestUtil.createTestFile(new File(noWalk, testRealFile + ".txt"), testFileContent); + TestUtil.createTestFile(new File(new File(noWalk,noReadDir),noReadFile + ".txt"),testFileContent); + + final String context = ""; + + handler.addDirectory(noWalk); // test file & directory read + handler.addDirectory(contextNoName,noWalk); + handler.addDirectory(noWalk,dirNewName); + handler.addDirectory(contextWName,noWalk,dirNewName); + + server.createContext(context,handler); + server.start(); + + final String[] validPathsToTest = { // valid reads + noWalk.getName() + '/' + testRealFile, + contextNoName + '/' + noWalk.getName() + '/' + testRealFile, + dirNewName + '/' + testRealFile, + contextWName + '/' + dirNewName + '/' + testRealFile + }; + + for(final String path : validPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNotNull("Client did not find data for " + path, response); + Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); + }catch(final ExecutionException ignored){ + Assert.fail("Client did not find data for " + path); + } + } + + final String[] invalidPathsToTest = { + noWalk.getName() + '/' + noReadDir, + noWalk.getName() + '/' + noReadDir + '/' + noReadFile + }; + + for(final String path : invalidPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + Exception exception = null; + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNull("Client found data for blocked path " + path,response); + }catch(final ExecutionException e){ + exception = e; + } + Assert.assertNotNull("Client found data for blocked path",exception); + } + + server.stop(); + } + +} diff --git a/src/test/java/handlers/file/FileHandlerWalkTest.java b/src/test/java/handlers/file/FileHandlerWalkTest.java new file mode 100644 index 0000000..b4d89c8 --- /dev/null +++ b/src/test/java/handlers/file/FileHandlerWalkTest.java @@ -0,0 +1,87 @@ +package handlers.file; + +import com.kttdevelopment.core.tests.TestUtil; +import com.kttdevelopment.simplehttpserver.SimpleHttpServer; +import com.kttdevelopment.simplehttpserver.handler.FileHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.*; +import java.util.concurrent.ExecutionException; + +@SuppressWarnings("SpellCheckingInspection") +public final class FileHandlerWalkTest { + + @Test + public final void addDirectoryTestsWalk() throws IOException, InterruptedException{ + final int port = 8080; + final SimpleHttpServer server = SimpleHttpServer.create(port); + final FileHandler handler = new FileHandler(); + + final String testRealFile = "test.txt", testFileContent = "readme"; + final String readDir = "dirnoread"; + final String innerFile = "innerNoRead.txt"; + + final File noWalk = new File("src/test/resources/directory/nowalk"); + + TestUtil.createTestFile(new File(noWalk, testRealFile), testFileContent); + TestUtil.createTestFile(new File(new File(noWalk,readDir),innerFile),testFileContent); + + final String context = ""; + + handler.addDirectory(noWalk,true); + + server.createContext(context,handler); + server.start(); + + final String[] validPathsToTest = { // valid reads + noWalk.getName() + '/' + testRealFile, + noWalk.getName() + '/' + readDir + '/' + innerFile + }; + + for(final String path : validPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + try{ + final String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNotNull("Client did not find data for " + path,response); + Assert.assertEquals("Client data did not match server data for " + path,testFileContent,response); + }catch(final ExecutionException ignored){ + Assert.fail("Client did not find data for " + path); + } + } + + final String[] invalidPathsToTest = { + noWalk.getName() + '/' + readDir + }; + + for(final String path : invalidPathsToTest){ + final String url = "http://localhost:" + port + '/' + path; + final HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + + Exception exception = null; + try{ + String response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body).get(); + + Assert.assertNull("Client found data for blocked path " + path,response); + }catch(final ExecutionException e){ + exception = e; + } + Assert.assertNotNull("Client found data for blocked path",exception); + } + + server.stop(); + } + +} diff --git a/src/test/java/handlers/temporary/TemporaryFirstTest.java b/src/test/java/handlers/temporary/TemporaryFirstTest.java index 9046919..ad0082a 100644 --- a/src/test/java/handlers/temporary/TemporaryFirstTest.java +++ b/src/test/java/handlers/temporary/TemporaryFirstTest.java @@ -11,10 +11,10 @@ import java.net.http.*; import java.util.concurrent.ExecutionException; -public class TemporaryFirstTest { +public final class TemporaryFirstTest { @Test - public void testFirstConn() throws ExecutionException, InterruptedException, IOException{ + public final void testFirstConn() throws ExecutionException, InterruptedException, IOException{ final int port = 8080; final SimpleHttpServer server = SimpleHttpServer.create(port); diff --git a/src/test/resources/directory/nowalk/dirnoread/innerNoRead.txt b/src/test/resources/directory/nowalk/dirnoread/innerNoRead.txt deleted file mode 100644 index ea786ff..0000000 --- a/src/test/resources/directory/nowalk/dirnoread/innerNoRead.txt +++ /dev/null @@ -1 +0,0 @@ -readme \ No newline at end of file diff --git a/src/test/resources/directory/nowalk/test.txt b/src/test/resources/directory/nowalk/test.txt deleted file mode 100644 index ea786ff..0000000 --- a/src/test/resources/directory/nowalk/test.txt +++ /dev/null @@ -1 +0,0 @@ -readme \ No newline at end of file diff --git a/src/test/resources/files/test.txt b/src/test/resources/files/test.txt deleted file mode 100644 index c96117c..0000000 --- a/src/test/resources/files/test.txt +++ /dev/null @@ -1 +0,0 @@ -random content that shouldn't be read \ No newline at end of file diff --git a/src/test/resources/files/test2.txt b/src/test/resources/files/test2.txt deleted file mode 100644 index 9f72578..0000000 --- a/src/test/resources/files/test2.txt +++ /dev/null @@ -1 +0,0 @@ -make sure 2x files work \ No newline at end of file