1 package fi.iki.elonen.router; 2 3 /* 4 * #%L 5 * NanoHttpd-Samples 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 /** 37 * Created by vnnv on 7/17/15. 38 * Simple httpd server based on NanoHTTPD 39 * Read the source. Everything is there. 40 */ 41 42 import java.io.BufferedInputStream; 43 import java.io.ByteArrayInputStream; 44 import java.io.File; 45 import java.io.FileNotFoundException; 46 import java.io.IOException; 47 import java.io.InputStream; 48 import java.util.Map; 49 50 import fi.iki.elonen.NanoHTTPD; 51 import fi.iki.elonen.NanoHTTPD.Response.IStatus; 52 import fi.iki.elonen.NanoHTTPD.Response.Status; 53 import fi.iki.elonen.util.ServerRunner; 54 55 public class AppNanolets extends RouterNanoHTTPD { 56 57 private static final int PORT = 9090; 58 59 public static class UserHandler extends DefaultHandler { 60 61 @Override getText()62 public String getText() { 63 return "not implemented"; 64 } 65 getText(Map<String, String> urlParams, NanoHTTPD.IHTTPSession session)66 public String getText(Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) { 67 String text = "<html><body>User handler. Method: " + session.getMethod().toString() + "<br>"; 68 text += "<h1>Uri parameters:</h1>"; 69 for (Map.Entry<String, String> entry : urlParams.entrySet()) { 70 String key = entry.getKey(); 71 String value = entry.getValue(); 72 text += "<div> Param: " + key + " Value: " + value + "</div>"; 73 } 74 text += "<h1>Query parameters:</h1>"; 75 for (Map.Entry<String, String> entry : session.getParms().entrySet()) { 76 String key = entry.getKey(); 77 String value = entry.getValue(); 78 text += "<div> Query Param: " + key + " Value: " + value + "</div>"; 79 } 80 text += "</body></html>"; 81 82 return text; 83 } 84 85 @Override getMimeType()86 public String getMimeType() { 87 return "text/html"; 88 } 89 90 @Override getStatus()91 public NanoHTTPD.Response.IStatus getStatus() { 92 return NanoHTTPD.Response.Status.OK; 93 } 94 get(UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session)95 public NanoHTTPD.Response get(UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) { 96 String text = getText(urlParams, session); 97 ByteArrayInputStream inp = new ByteArrayInputStream(text.getBytes()); 98 int size = text.getBytes().length; 99 return NanoHTTPD.newFixedLengthResponse(getStatus(), getMimeType(), inp, size); 100 } 101 102 } 103 104 static public class StreamUrl extends DefaultStreamHandler { 105 106 @Override getMimeType()107 public String getMimeType() { 108 return "text/plain"; 109 } 110 111 @Override getStatus()112 public IStatus getStatus() { 113 return Status.OK; 114 } 115 116 @Override getData()117 public InputStream getData() { 118 return new ByteArrayInputStream("a stream of data ;-)".getBytes()); 119 } 120 121 } 122 123 static class StaticPageTestHandler extends StaticPageHandler { 124 125 @Override fileToInputStream(File fileOrdirectory)126 protected BufferedInputStream fileToInputStream(File fileOrdirectory) throws IOException { 127 if (fileOrdirectory.getName().equals("exception.html")) { 128 throw new IOException("trigger something wrong"); 129 } 130 return super.fileToInputStream(fileOrdirectory); 131 } 132 } 133 134 /** 135 * Create the server instance 136 */ AppNanolets()137 public AppNanolets() throws IOException { 138 super(PORT); 139 addMappings(); 140 System.out.println("\nRunning! Point your browers to http://localhost:" + PORT + "/ \n"); 141 } 142 143 /** 144 * Add the routes Every route is an absolute path Parameters starts with ":" 145 * Handler class should implement @UriResponder interface If the handler not 146 * implement UriResponder interface - toString() is used 147 */ 148 @Override addMappings()149 public void addMappings() { 150 super.addMappings(); 151 addRoute("/user", UserHandler.class); 152 addRoute("/user/:id", UserHandler.class); 153 addRoute("/user/help", GeneralHandler.class); 154 addRoute("/general/:param1/:param2", GeneralHandler.class); 155 addRoute("/photos/:customer_id/:photo_id", null); 156 addRoute("/test", String.class); 157 addRoute("/interface", UriResponder.class); // this will cause an error 158 // when called 159 addRoute("/toBeDeleted", String.class); 160 removeRoute("/toBeDeleted"); 161 addRoute("/stream", StreamUrl.class); 162 addRoute("/browse/(.)+", StaticPageTestHandler.class, new File("src/test/resources").getAbsoluteFile()); 163 } 164 165 /** 166 * Main entry point 167 * 168 * @param args 169 */ main(String[] args)170 public static void main(String[] args) { 171 ServerRunner.run(AppNanolets.class); 172 } 173 } 174