Home | History | Annotate | Download | only in nanohttpd
      1 ## NanoHTTPD  a tiny web server in Java
      2 
      3 *NanoHTTPD* is a light-weight HTTP server designed for embedding in other applications, released under a Modified BSD licence.
      4 
      5 It is being developed at Github and uses Apache Maven for builds & unit testing:
      6 
      7  * Build status: [![Build Status](https://api.travis-ci.org/NanoHttpd/nanohttpd.png)](https://travis-ci.org/NanoHttpd/nanohttpd)
      8  * Coverage Status: [![Coverage Status](https://coveralls.io/repos/NanoHttpd/nanohttpd/badge.svg)](https://coveralls.io/r/NanoHttpd/nanohttpd)
      9  * Current central released version: [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.nanohttpd/nanohttpd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.nanohttpd/nanohttpd)
     10 
     11 ## Quickstart
     12 
     13 We'll create a custom HTTP server project using Maven for build/dep system. This tutorial assumes you are using a Unix variant and a shell. First, install Maven and Java SDK if not already installed. Then run:
     14 
     15     mvn compile
     16     mvn exec:java -pl webserver -Dexec.mainClass="fi.iki.elonen.SimpleWebServer"
     17     
     18 You should now have a HTTP file server running on <http://localhost:8080/>.
     19 
     20 ### Custom web app
     21 
     22 Let's raise the bar and build a custom web application next:
     23 
     24     mvn archetype:generate -DgroupId=com.example -DartifactId=myHellopApp -DinteractiveMode=false
     25     cd myHellopApp
     26     
     27 Edit `pom.xml`, and add this between \<dependencies\>:
     28  
     29 	<dependency>
     30 		<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
     31 		<artifactId>nanohttpd</artifactId>
     32 		<version>2.2.0-SNAPSHOT</version>
     33 	</dependency>
     34 	
     35 Edit `src/main/java/com/example/App.java` and replace it with:
     36 ```java
     37 package com.example;
     38 
     39 import java.util.Map;
     40 import java.io.IOException;
     41 import fi.iki.elonen.NanoHTTPD;
     42 
     43 public class App extends NanoHTTPD {
     44 
     45     public App() throws IOException {
     46         super(8080);
     47         start();
     48 		System.out.println( "\nRunning! Point your browers to http://localhost:8080/ \n" );
     49     }
     50 
     51     public static void main(String[] args) {
     52 		try {
     53 		    new App();
     54 		}
     55 		catch( IOException ioe ) {
     56 			System.err.println( "Couldn't start server:\n" + ioe );
     57 		}
     58     }
     59 
     60     @Override
     61     public Response serve(IHTTPSession session) {
     62         String msg = "<html><body><h1>Hello server</h1>\n";
     63         Map<String, String> parms = session.getParms();
     64         if (parms.get("username") == null) {
     65             msg += "<form action='?' method='get'>\n  <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
     66         } else {
     67             msg += "<p>Hello, " + parms.get("username") + "!</p>";
     68         }
     69         return newFixedLengthResponse( msg + "</body></html>\n" );
     70     }
     71 }
     72 ```
     73 
     74 Compile and run the server:
     75  
     76     mvn compile
     77     mvn exec:java -Dexec.mainClass="com.example.App"
     78     
     79 If it started ok, point your browser at <http://localhost:8080/> and enjoy a web server that asks your name and replies with a greeting. 
     80 
     81 ### Nanolets
     82 
     83 Nanolets are like sevlet's only that they have a extrem low profile. They offer an easy to use system for a more complex server application. 
     84 This text has to be extrended with an example, so for now take a look at the unit tests for the usage. <https://github.com/NanoHttpd/nanohttpd/blob/master/nanolets/src/test/java/fi/iki/elonen/router/AppNanolets.java>
     85 
     86 ## Status
     87 
     88 We are currently in the process of stabilizing NanoHttpd from the many pull requests and feature requests that were integrated over the last few months. The next release will come soon, and there will not be any more "intended" major changes before the next release. If you want to use the bleeding edge version, you can clone it from Github, or get it from sonatype.org (see "Maven dependencies / Living on the edge" below).
     89 
     90 ## Project structure
     91 
     92 NanoHTTPD project currently consist of four parts:
     93 
     94  * `/core`  Fully functional HTTP(s) server consisting of one (1) Java file, ready to be customized/inherited for your own project
     95 
     96  * `/samples`  Simple examples on how to customize NanoHTTPD. See *HelloServer.java* for a killer app that greets you enthusiastically!
     97 
     98  * `/websocket`  Websocket implementation, also in a single Java file. Depends on core.
     99 
    100  * `/webserver`  Standalone file server. Run & enjoy. A popular use seems to be serving files out off an Android device.
    101 
    102  * `/nanolets`  Standalone nano app server, giving a servlet like system to the implementor.
    103 
    104  * `/fileupload`  integration of the apache common file upload library.
    105 
    106 ## Features
    107 ### Core
    108 * Only one Java file, providing HTTP 1.1 support.
    109 * No fixed config files, logging, authorization etc. (Implement by yourself if you need them. Errors are passed to java.util.logging, though.)
    110 * Support for HTTPS (SSL)
    111 * Basic support for cookies
    112 * Supports parameter parsing of GET and POST methods.
    113 * Some built-in support for HEAD, POST and DELETE requests. You can easily implement/customize any HTTP method, though.
    114 * Supports file upload. Uses memory for small uploads, temp files for large ones.
    115 * Never caches anything.
    116 * Does not limit bandwidth, request time or simultaneous connections by default.
    117 * All header names are converted to lower case so they don't vary between browsers/clients.
    118 * Persistent connections (Connection "keep-alive") support allowing multiple requests to be served over a single socket connection.
    119 
    120 ### Websocket
    121 * Tested on Firefox, Chrome and IE.
    122 
    123 ### Webserver
    124 * Default code serves files and shows (prints on console) all HTTP parameters and headers.
    125 * Supports both dynamic content and file serving.
    126 * File server supports directory listing, `index.html` and `index.htm`.
    127 * File server supports partial content (streaming & continue download).
    128 * File server supports ETags.
    129 * File server does the 301 redirection trick for directories without `/`.
    130 * File server serves also very long files without memory overhead.
    131 * Contains a built-in list of most common MIME types.
    132 * Runtime extension support (extensions that serve particular MIME types) - example extension that serves Markdown formatted files. Simply including an extension JAR in the webserver classpath is enough for the extension to be loaded.
    133 * Simple [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) support via `--cors` paramater
    134   * by default serves `Access-Control-Allow-Headers: origin,accept,content-type`
    135   * possibility to set `Access-Control-Allow-Headers` by setting System property: `AccessControlAllowHeader`
    136   * _example: _ `-DAccessControlAllowHeader=origin,accept,content-type,Authorization`
    137   * possible values:
    138       * `--cors`: activates CORS support, `Access-Control-Allow-Origin` will be set to `*`
    139       * `--cors=some_value`: `Access-Control-Allow-Origin` will be set to `some_value`. 
    140 
    141 **_CORS argument examples_**
    142 
    143 
    144 * `--cors=http://appOne.company.com`
    145 * `--cors="http://appOne.company.com, http://appTwo.company.com"`: note the double quotes so that the 2 URLs are considered part of a single argument.
    146 
    147 ## Maven dependencies
    148 
    149 NanoHTTPD is a Maven based project and deployed to central. Most development environments have means to access the central repository. The coordinates to use in Maven are: 
    150 
    151 	<dependencies>
    152 		<dependency>
    153 			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
    154 			<artifactId>nanohttpd</artifactId>
    155 			<version>CURRENT_VERSION</version>
    156 		</dependency>
    157 	</dependencies>
    158 
    159 (Replace `CURRENT_VERSION` with whatever is reported latest at <http://nanohttpd.org/>.)
    160 
    161 The coordinates for your development environment should correspond to these. When looking for an older version take care because we switched groupId from *com.nanohttpd* to *org.nanohttpd* in mid 2015.
    162 
    163 Next it depends what you are useing nanohttpd for, there are tree main usages.
    164 
    165 ## Gradle dependencies
    166 
    167 In gradle you can use nano http the same way because gradle accesses the same central repository:
    168 
    169 	dependencies {
    170 		runtime(
    171 			[group: 'org.nanohttpd', name: 'nanohttpd', version: 'CURRENT_VERSION'],
    172 		)
    173 	}
    174 
    175 (Replace `CURRENT_VERSION` with whatever is reported latest at <http://nanohttpd.org/>.)
    176 
    177 Just replace the name with the artifact id of the module you want to use and gradle will find it for you. 
    178 
    179 ### Develop your own specialized HTTP service
    180 
    181 For a specialized HTTP (HTTPS) service you can use the module with artifactId *nanohttpd*.
    182 
    183 		<dependency>
    184 			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
    185 			<artifactId>nanohttpd</artifactId>
    186 			<version>CURRENT_VERSION</version>
    187 		</dependency>
    188 		
    189 Here you write your own subclass of *fi.iki.elonen.NanoHTTPD* to configure and to serve the requests.
    190   
    191 ### Develop a websocket based service    
    192 
    193 For a specialized websocket service you can use the module with artifactId *nanohttpd-websocket*.
    194 
    195 		<dependency>
    196 			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
    197 			<artifactId>nanohttpd-websocket</artifactId>
    198 			<version>CURRENT_VERSION</version>
    199 		</dependency>
    200 
    201 Here you write your own subclass of *fi.iki.elonen.NanoWebSocketServer* to configure and to serve the websocket requests. A small standard echo example is included as *fi.iki.elonen.samples.echo.DebugWebSocketServer*. You can use it as a starting point to implement your own services.
    202 
    203 ### Develop a custom HTTP file server    
    204 
    205 For a more classic aproach, perhaps to just create a HTTP server serving mostly service files from your disk, you can use the module with artifactId *nanohttpd-webserver*.
    206 
    207 		<dependency>
    208 			<groupId>org.nanohttpd</groupId>
    209 			<artifactId>nanohttpd-webserver</artifactId>
    210 			<version>CURRENT_VERSION</version>
    211 		</dependency>
    212 
    213 The included class *fi.iki.elonen.SimpleWebServer* is intended to be used as a starting point for your own implementation but it also can be used as is. Staring the class as is will start a http server on port 8080 and publishing the current directory.  
    214 
    215 ### Living on the edge
    216 
    217 The latest Github master version can be fetched through sonatype.org:
    218 
    219 	<dependencies>
    220 		<dependency>
    221 			<artifactId>nanohttpd</artifactId>
    222 			<groupId>org.nanohttpd</groupId>
    223 			<version>XXXXX-SNAPSHOT</version>
    224 		</dependency>
    225 	</dependencies>
    226 	...
    227 	<repositories>
    228 		<repository>
    229 			<id>sonatype-snapshots</id>
    230 			<url>https://oss.sonatype.org/content/repositories/snapshots</url>
    231 			<snapshots>
    232 				<enabled>true</enabled>
    233 			</snapshots>
    234 		</repository>
    235 	</repositories>
    236 
    237 ### generating an self signed ssl certificate
    238 
    239 Just a hint how to generate a certificate for localhost.
    240 
    241 	keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048 -ext SAN=DNS:localhost,IP:127.0.0.1  -validity 9999
    242 
    243 This will generate a keystore file named 'keystore.jks' with a self signed certificate for a host named localhost with the ip adress 127.0.0.1 . Now 
    244 you can use:
    245 
    246 	server.makeSecure(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()));
    247 
    248 Before you start the server to make Nanohttpd serve https connections, when you make sure 'keystore.jks' is in your classpath .  
    249  
    250 -----
    251 
    252 *Thank you to everyone who has reported bugs and suggested fixes.*
    253