1 package fi.iki.elonen.router; 2 3 /* 4 * #%L 5 * NanoHttpd nano application server 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.IOException; 38 import java.io.InputStream; 39 import java.io.PipedInputStream; 40 import java.io.PipedOutputStream; 41 import java.util.regex.Matcher; 42 import java.util.regex.Pattern; 43 44 import org.apache.http.HttpEntity; 45 import org.apache.http.client.methods.CloseableHttpResponse; 46 import org.apache.http.client.methods.HttpDelete; 47 import org.apache.http.client.methods.HttpGet; 48 import org.apache.http.client.methods.HttpPost; 49 import org.apache.http.client.methods.HttpPut; 50 import org.apache.http.client.methods.HttpTrace; 51 import org.apache.http.impl.client.CloseableHttpClient; 52 import org.apache.http.impl.client.HttpClients; 53 import org.junit.AfterClass; 54 import org.junit.Assert; 55 import org.junit.BeforeClass; 56 import org.junit.Test; 57 58 import fi.iki.elonen.NanoHTTPD; 59 import fi.iki.elonen.router.RouterNanoHTTPD.GeneralHandler; 60 import fi.iki.elonen.router.RouterNanoHTTPD.UriResource; 61 62 public class TestNanolets { 63 64 private static PipedOutputStream stdIn; 65 66 private static Thread serverStartThread; 67 68 @BeforeClass setUp()69 public static void setUp() throws Exception { 70 stdIn = new PipedOutputStream(); 71 System.setIn(new PipedInputStream(stdIn)); 72 serverStartThread = new Thread(new Runnable() { 73 74 @Override 75 public void run() { 76 String[] args = {}; 77 AppNanolets.main(args); 78 } 79 }); 80 serverStartThread.start(); 81 // give the server some tine to start. 82 Thread.sleep(200); 83 } 84 main(String[] args)85 public static void main(String[] args) { 86 { 87 String uri = "def"; 88 Pattern.compile("([A-Za-z0-9\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]+)"); 89 Pattern URI_PATTERN = Pattern.compile("([A-Za-z0-9\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]+)"); 90 System.out.println(URI_PATTERN.matcher(uri).matches()); 91 } 92 93 String uri = "photos/abc/def"; 94 Pattern URI_PATTERN = Pattern.compile("photos/([A-Za-z0-9\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]+)/([A-Za-z0-9\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]+)"); 95 Matcher matcher = URI_PATTERN.matcher(uri); 96 System.out.println("--------------->" + "/" + uri); 97 while (matcher.matches()) { 98 99 System.out.println(matcher.group()); 100 } 101 // for (int index = 0; index < matcher.groupCount(); index++) { 102 // System.out.println(matcher.group()); 103 // } 104 } 105 106 @Test doSomeBasicMethodTest()107 public void doSomeBasicMethodTest() throws Exception { 108 CloseableHttpClient httpclient = HttpClients.createDefault(); 109 110 HttpGet httpget = new HttpGet("http://localhost:9090/user/blabla"); 111 CloseableHttpResponse response = httpclient.execute(httpget); 112 HttpEntity entity = response.getEntity(); 113 String string = new String(readContents(entity), "UTF-8"); 114 Assert.assertEquals( 115 "<html><body>User handler. Method: GET<br><h1>Uri parameters:</h1><div> Param: id Value: blabla</div><h1>Query parameters:</h1></body></html>", string); 116 response.close(); 117 118 HttpPost httppost = new HttpPost("http://localhost:9090/user/blabla"); 119 response = httpclient.execute(httppost); 120 entity = response.getEntity(); 121 string = new String(readContents(entity), "UTF-8"); 122 Assert.assertEquals( 123 "<html><body>User handler. Method: POST<br><h1>Uri parameters:</h1><div> Param: id Value: blabla</div><h1>Query parameters:</h1></body></html>", string); 124 response.close(); 125 126 HttpPut httpgput = new HttpPut("http://localhost:9090/user/blabla"); 127 response = httpclient.execute(httpgput); 128 entity = response.getEntity(); 129 string = new String(readContents(entity), "UTF-8"); 130 Assert.assertEquals( 131 "<html><body>User handler. Method: PUT<br><h1>Uri parameters:</h1><div> Param: id Value: blabla</div><h1>Query parameters:</h1></body></html>", string); 132 response.close(); 133 134 HttpDelete httpdelete = new HttpDelete("http://localhost:9090/user/blabla"); 135 response = httpclient.execute(httpdelete); 136 entity = response.getEntity(); 137 string = new String(readContents(entity), "UTF-8"); 138 Assert.assertEquals( 139 "<html><body>User handler. Method: DELETE<br><h1>Uri parameters:</h1><div> Param: id Value: blabla</div><h1>Query parameters:</h1></body></html>", string); 140 response.close(); 141 } 142 143 @Test doNonRouterRequest()144 public void doNonRouterRequest() throws Exception { 145 CloseableHttpClient httpclient = HttpClients.createDefault(); 146 147 HttpGet httpget = new HttpGet("http://localhost:9090/test"); 148 CloseableHttpResponse response = httpclient.execute(httpget); 149 HttpEntity entity = response.getEntity(); 150 String string = new String(readContents(entity), "UTF-8"); 151 Assert.assertEquals("Return: java.lang.String.toString() -> ", string); 152 response.close(); 153 } 154 155 @Test doExceptionRequest()156 public void doExceptionRequest() throws Exception { 157 CloseableHttpClient httpclient = HttpClients.createDefault(); 158 159 HttpGet httpget = new HttpGet("http://localhost:9090/interface"); 160 CloseableHttpResponse response = httpclient.execute(httpget); 161 HttpEntity entity = response.getEntity(); 162 String string = new String(readContents(entity), "UTF-8"); 163 Assert.assertEquals("Error: java.lang.InstantiationException : fi.iki.elonen.router.RouterNanoHTTPD$UriResponder", string); 164 response.close(); 165 } 166 167 @Test doDeletedRoute()168 public void doDeletedRoute() throws Exception { 169 CloseableHttpClient httpclient = HttpClients.createDefault(); 170 171 HttpGet httpget = new HttpGet("http://localhost:9090/toBeDeleted"); 172 CloseableHttpResponse response = httpclient.execute(httpget); 173 HttpEntity entity = response.getEntity(); 174 String string = new String(readContents(entity), "UTF-8"); 175 Assert.assertEquals("<html><body><h3>Error 404: the requested page doesn't exist.</h3></body></html>", string); 176 response.close(); 177 } 178 179 @Test doUriSelection1()180 public void doUriSelection1() throws Exception { 181 CloseableHttpClient httpclient = HttpClients.createDefault(); 182 183 HttpGet httpget = new HttpGet("http://localhost:9090/user/help"); 184 CloseableHttpResponse response = httpclient.execute(httpget); 185 HttpEntity entity = response.getEntity(); 186 String string = new String(readContents(entity), "UTF-8"); 187 Assert.assertEquals("<html><body><h1>Url: /user/help</h1><br><p>no params in url</p><br>", string); 188 response.close(); 189 } 190 191 @Test doStreamOfData()192 public void doStreamOfData() throws Exception { 193 CloseableHttpClient httpclient = HttpClients.createDefault(); 194 195 HttpGet httpget = new HttpGet("http://localhost:9090/stream"); 196 CloseableHttpResponse response = httpclient.execute(httpget); 197 HttpEntity entity = response.getEntity(); 198 String string = new String(readContents(entity), "UTF-8"); 199 Assert.assertEquals("a stream of data ;-)", string); 200 response.close(); 201 } 202 203 @Test(expected = IllegalStateException.class) illegalMethod1()204 public void illegalMethod1() throws Exception { 205 new AppNanolets.UserHandler().getData(); 206 } 207 208 @Test(expected = IllegalStateException.class) illegalMethod2()209 public void illegalMethod2() throws Exception { 210 new RouterNanoHTTPD.GeneralHandler().getText(); 211 } 212 213 @Test(expected = IllegalStateException.class) illegalMethod3()214 public void illegalMethod3() throws Exception { 215 new RouterNanoHTTPD.StaticPageHandler().getText(); 216 } 217 218 @Test(expected = IllegalStateException.class) illegalMethod4()219 public void illegalMethod4() throws Exception { 220 new RouterNanoHTTPD.StaticPageHandler().getMimeType(); 221 } 222 223 @Test(expected = ClassCastException.class) checkIniParameter1()224 public void checkIniParameter1() throws Exception { 225 new RouterNanoHTTPD.UriResource("browse", 100, null, "init").initParameter(String.class); 226 new RouterNanoHTTPD.UriResource("browse", 100, null, "init").initParameter(Integer.class); 227 } 228 229 @Test checkIniParameter2()230 public void checkIniParameter2() throws Exception { 231 Assert.assertEquals("init", new RouterNanoHTTPD.UriResource("browse", 100, null, "init").initParameter(String.class)); 232 Assert.assertNull(new RouterNanoHTTPD.UriResource("browse", 100, null).initParameter(String.class)); 233 } 234 235 @Test doGeneralParams()236 public void doGeneralParams() throws Exception { 237 CloseableHttpClient httpclient = HttpClients.createDefault(); 238 239 HttpGet httpget = new HttpGet("http://localhost:9090/general/value1/value2?param3=value3¶m4=value4"); 240 241 CloseableHttpResponse response = httpclient.execute(httpget); 242 HttpEntity entity = response.getEntity(); 243 String string = new String(readContents(entity), "UTF-8"); 244 Assert.assertEquals("<html><body><h1>Url: /general/value1/value2</h1><br><p>Param 'param3' = value3</p><p>Param 'param4' = value4</p>", string); 245 response.close(); 246 } 247 248 @Test doIndexHandler()249 public void doIndexHandler() throws Exception { 250 CloseableHttpClient httpclient = HttpClients.createDefault(); 251 252 HttpGet httpget = new HttpGet("http://localhost:9090/index.html"); 253 CloseableHttpResponse response = httpclient.execute(httpget); 254 HttpEntity entity = response.getEntity(); 255 String string = new String(readContents(entity), "UTF-8"); 256 Assert.assertEquals("<html><body><h2>Hello world!</h3></body></html>", string); 257 response.close(); 258 } 259 260 @Test doMissingHandler()261 public void doMissingHandler() throws Exception { 262 CloseableHttpClient httpclient = HttpClients.createDefault(); 263 264 HttpGet httpget = new HttpGet("http://localhost:9090/photos/abc/def"); 265 CloseableHttpResponse response = httpclient.execute(httpget); 266 HttpEntity entity = response.getEntity(); 267 String string = new String(readContents(entity), "UTF-8"); 268 Assert.assertEquals("<html><body><h2>The uri is mapped in the router, but no handler is specified. <br> Status: Not implemented!</h3></body></html>", string); 269 response.close(); 270 } 271 272 @Test uriToString()273 public void uriToString() throws Exception { 274 Assert.assertEquals(// 275 "UrlResource{uri='photos/:customer_id/:photo_id', urlParts=[customer_id, photo_id]}",// 276 new UriResource("/photos/:customer_id/:photo_id", 100, GeneralHandler.class).toString()); 277 } 278 279 @Test doOtherMethod()280 public void doOtherMethod() throws Exception { 281 CloseableHttpClient httpclient = HttpClients.createDefault(); 282 283 HttpTrace httphead = new HttpTrace("http://localhost:9090/index.html"); 284 CloseableHttpResponse response = httpclient.execute(httphead); 285 HttpEntity entity = response.getEntity(); 286 String string = new String(readContents(entity), "UTF-8"); 287 Assert.assertEquals("<html><body><h2>Hello world!</h3></body></html>", string); 288 response.close(); 289 } 290 291 @Test normalize()292 public void normalize() throws Exception { 293 Assert.assertNull(RouterNanoHTTPD.normalizeUri(null)); 294 Assert.assertEquals("", RouterNanoHTTPD.normalizeUri("/")); 295 Assert.assertEquals("xxx/yyy", RouterNanoHTTPD.normalizeUri("/xxx/yyy")); 296 Assert.assertEquals("xxx/yyy", RouterNanoHTTPD.normalizeUri("/xxx/yyy/")); 297 } 298 readContents(HttpEntity entity)299 private byte[] readContents(HttpEntity entity) throws IOException { 300 InputStream instream = entity.getContent(); 301 return readContents(instream); 302 } 303 readContents(InputStream instream)304 private byte[] readContents(InputStream instream) throws IOException { 305 byte[] bytes; 306 ByteArrayOutputStream out = new ByteArrayOutputStream(); 307 308 try { 309 byte[] buffer = new byte[1024]; 310 int count; 311 while ((count = instream.read(buffer)) >= 0) { 312 out.write(buffer, 0, count); 313 } 314 bytes = out.toByteArray(); 315 } finally { 316 instream.close(); 317 } 318 return bytes; 319 } 320 321 @Test staticFiles()322 public void staticFiles() throws Exception { 323 CloseableHttpClient httpclient = HttpClients.createDefault(); 324 325 HttpTrace httphead = new HttpTrace("http://localhost:9090/browse/blabla.html"); 326 CloseableHttpResponse response = httpclient.execute(httphead); 327 HttpEntity entity = response.getEntity(); 328 String string = new String(readContents(entity), "UTF-8"); 329 Assert.assertEquals("<html><body><h3>just a page</h3></body></html>", string); 330 response.close(); 331 332 httphead = new HttpTrace("http://localhost:9090/browse/dir/blabla.html"); 333 response = httpclient.execute(httphead); 334 entity = response.getEntity(); 335 string = new String(readContents(entity), "UTF-8"); 336 Assert.assertEquals("<html><body><h3>just an other page</h3></body></html>", string); 337 response.close(); 338 339 httphead = new HttpTrace("http://localhost:9090/browse/dir/nanohttpd_logo.png"); 340 response = httpclient.execute(httphead); 341 entity = response.getEntity(); 342 Assert.assertEquals("image/png", entity.getContentType().getValue()); 343 response.close(); 344 345 httphead = new HttpTrace("http://localhost:9090/browse/dir/xxx.html"); 346 response = httpclient.execute(httphead); 347 entity = response.getEntity(); 348 string = new String(readContents(entity), "UTF-8"); 349 Assert.assertEquals("<html><body><h3>Error 404: the requested page doesn't exist.</h3></body></html>", string); 350 response.close(); 351 352 httphead = new HttpTrace("http://localhost:9090/browse/dir/"); 353 response = httpclient.execute(httphead); 354 entity = response.getEntity(); 355 string = new String(readContents(entity), "UTF-8"); 356 Assert.assertEquals("<html><body><h3>just an index page</h3></body></html>", string); 357 response.close(); 358 359 httphead = new HttpTrace("http://localhost:9090/browse/exception.html"); 360 response = httpclient.execute(httphead); 361 Assert.assertEquals(NanoHTTPD.Response.Status.REQUEST_TIMEOUT.getRequestStatus(), response.getStatusLine().getStatusCode()); 362 entity = response.getEntity(); 363 string = new String(readContents(entity), "UTF-8"); 364 Assert.assertEquals("", string); 365 response.close(); 366 } 367 368 @AfterClass tearDown()369 public static void tearDown() throws Exception { 370 stdIn.write("\n\n".getBytes()); 371 serverStartThread.join(2000); 372 Assert.assertFalse(serverStartThread.isAlive()); 373 } 374 375 } 376