1 package fi.iki.elonen; 2 3 /* 4 * #%L 5 * NanoHttpd-Webserver 6 * %% 7 * Copyright (C) 2012 - 2015 nanohttpd 8 * %% 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, this 13 * list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the nanohttpd nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 * OF THE POSSIBILITY OF SUCH DAMAGE. 33 * #L% 34 */ 35 36 import java.io.ByteArrayOutputStream; 37 import java.io.FileInputStream; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.io.PipedInputStream; 41 import java.io.PipedOutputStream; 42 43 import org.apache.http.HttpEntity; 44 import org.apache.http.client.methods.CloseableHttpResponse; 45 import org.apache.http.client.methods.HttpGet; 46 import org.apache.http.client.methods.HttpOptions; 47 import org.apache.http.impl.client.CloseableHttpClient; 48 import org.apache.http.impl.client.HttpClients; 49 import org.junit.AfterClass; 50 import org.junit.Assert; 51 import org.junit.BeforeClass; 52 import org.junit.Test; 53 54 /** 55 * @author Matthieu Brouillard [matthieu (at) brouillard.fr] 56 */ 57 public class TestCorsHttpServer extends AbstractTestHttpServer { 58 59 private static PipedOutputStream stdIn; 60 61 private static Thread serverStartThread; 62 63 @BeforeClass 64 public static void setUp() throws Exception { 65 stdIn = new PipedOutputStream(); 66 System.setIn(new PipedInputStream(stdIn)); 67 serverStartThread = new Thread(new Runnable() { 68 69 @Override 70 public void run() { 71 String[] args = { 72 "--host", 73 "localhost", 74 "--port", 75 "9090", 76 "--dir", 77 "src/test/resources", 78 "--cors" 79 }; 80 SimpleWebServer.main(args); 81 } 82 }); 83 serverStartThread.start(); 84 // give the server some tine to start. 85 Thread.sleep(100); 86 } 87 88 @AfterClass 89 public static void tearDown() throws Exception { 90 stdIn.write("\n\n".getBytes()); 91 serverStartThread.join(2000); 92 Assert.assertFalse(serverStartThread.isAlive()); 93 } 94 95 @Test 96 public void doTestOption() throws Exception { 97 CloseableHttpClient httpclient = HttpClients.createDefault(); 98 HttpOptions httpOption = new HttpOptions("http://localhost:9090/xxx/yyy.html"); 99 CloseableHttpResponse response = httpclient.execute(httpOption); 100 Assert.assertEquals(200, response.getStatusLine().getStatusCode()); 101 Assert.assertNotNull("Cors should have added a header: Access-Control-Allow-Origin", response.getLastHeader("Access-Control-Allow-Origin")); 102 Assert.assertEquals("Cors should have added a header: Access-Control-Allow-Origin: *", "*", response.getLastHeader("Access-Control-Allow-Origin").getValue()); 103 response.close(); 104 } 105 106 @Test 107 public void doSomeBasicTest() throws Exception { 108 CloseableHttpClient httpclient = HttpClients.createDefault(); 109 HttpGet httpget = new HttpGet("http://localhost:9090/testdir/test.html"); 110 CloseableHttpResponse response = httpclient.execute(httpget); 111 HttpEntity entity = response.getEntity(); 112 String string = new String(readContents(entity), "UTF-8"); 113 114 Assert.assertNotNull("Cors should have added a header: Access-Control-Allow-Origin", response.getLastHeader("Access-Control-Allow-Origin")); 115 Assert.assertEquals("Cors should have added a header: Access-Control-Allow-Origin: *", "*", response.getLastHeader("Access-Control-Allow-Origin").getValue()); 116 Assert.assertEquals("<html>\n<head>\n<title>dummy</title>\n</head>\n<body>\n\t<h1>it works</h1>\n</body>\n</html>", string); 117 response.close(); 118 } 119 120 @Test 121 public void testAccessControlAllowHeaderUsesDefaultsWithoutSystemProperty() throws Exception { 122 Assert.assertNull("no System " + SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME + " shoudl be set", 123 System.getProperty(SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME)); 124 125 CloseableHttpClient httpclient = HttpClients.createDefault(); 126 HttpOptions httpOption = new HttpOptions("http://localhost:9090/xxx/yyy.html"); 127 CloseableHttpResponse response = httpclient.execute(httpOption); 128 Assert.assertEquals(200, response.getStatusLine().getStatusCode()); 129 Assert.assertEquals("Cors should have added a header: Access-Control-Allow-Headers: " + SimpleWebServer.DEFAULT_ALLOWED_HEADERS, 130 SimpleWebServer.DEFAULT_ALLOWED_HEADERS, response.getLastHeader("Access-Control-Allow-Headers").getValue()); 131 response.close(); 132 } 133 134 @Test 135 public void testAccessControlAllowHeaderUsesSystemPropertyWhenSet() throws Exception { 136 Assert.assertNull("no System " + SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME + " shoudl be set", 137 System.getProperty(SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME)); 138 139 final String expectedValue = "origin"; 140 System.setProperty(SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME, expectedValue); 141 142 try { 143 CloseableHttpClient httpclient = HttpClients.createDefault(); 144 HttpOptions httpOption = new HttpOptions("http://localhost:9090/xxx/yyy.html"); 145 CloseableHttpResponse response = httpclient.execute(httpOption); 146 Assert.assertEquals(200, response.getStatusLine().getStatusCode()); 147 Assert.assertEquals("Cors should have added a header: Access-Control-Allow-Headers: " + expectedValue, expectedValue, 148 response.getLastHeader("Access-Control-Allow-Headers").getValue()); 149 response.close(); 150 } finally { 151 System.clearProperty(SimpleWebServer.ACCESS_CONTROL_ALLOW_HEADER_PROPERTY_NAME); 152 } 153 } 154 } 155