xref: /aosp_15_r20/external/nanohttpd/README.md (revision 4711b67f075d8ed195ca46785b125dbea03982c3)
1*4711b67fSTreehugger Robot## NanoHTTPD – a tiny web server in Java
2*4711b67fSTreehugger Robot
3*4711b67fSTreehugger Robot*NanoHTTPD* is a light-weight HTTP server designed for embedding in other applications, released under a Modified BSD licence.
4*4711b67fSTreehugger Robot
5*4711b67fSTreehugger RobotIt is being developed at Github and uses Apache Maven for builds & unit testing:
6*4711b67fSTreehugger Robot
7*4711b67fSTreehugger Robot * Build status: [![Build Status](https://api.travis-ci.org/NanoHttpd/nanohttpd.png)](https://travis-ci.org/NanoHttpd/nanohttpd)
8*4711b67fSTreehugger Robot * Coverage Status: [![Coverage Status](https://coveralls.io/repos/NanoHttpd/nanohttpd/badge.svg)](https://coveralls.io/r/NanoHttpd/nanohttpd)
9*4711b67fSTreehugger Robot * 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*4711b67fSTreehugger Robot
11*4711b67fSTreehugger Robot## Quickstart
12*4711b67fSTreehugger Robot
13*4711b67fSTreehugger RobotWe'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*4711b67fSTreehugger Robot
15*4711b67fSTreehugger Robot    mvn compile
16*4711b67fSTreehugger Robot    mvn exec:java -pl webserver -Dexec.mainClass="fi.iki.elonen.SimpleWebServer"
17*4711b67fSTreehugger Robot
18*4711b67fSTreehugger RobotYou should now have a HTTP file server running on <http://localhost:8080/>.
19*4711b67fSTreehugger Robot
20*4711b67fSTreehugger Robot### Custom web app
21*4711b67fSTreehugger Robot
22*4711b67fSTreehugger RobotLet's raise the bar and build a custom web application next:
23*4711b67fSTreehugger Robot
24*4711b67fSTreehugger Robot    mvn archetype:generate -DgroupId=com.example -DartifactId=myHellopApp -DinteractiveMode=false
25*4711b67fSTreehugger Robot    cd myHellopApp
26*4711b67fSTreehugger Robot
27*4711b67fSTreehugger RobotEdit `pom.xml`, and add this between \<dependencies\>:
28*4711b67fSTreehugger Robot
29*4711b67fSTreehugger Robot	<dependency>
30*4711b67fSTreehugger Robot		<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
31*4711b67fSTreehugger Robot		<artifactId>nanohttpd</artifactId>
32*4711b67fSTreehugger Robot		<version>2.2.0-SNAPSHOT</version>
33*4711b67fSTreehugger Robot	</dependency>
34*4711b67fSTreehugger Robot
35*4711b67fSTreehugger RobotEdit `src/main/java/com/example/App.java` and replace it with:
36*4711b67fSTreehugger Robot```java
37*4711b67fSTreehugger Robotpackage com.example;
38*4711b67fSTreehugger Robot
39*4711b67fSTreehugger Robotimport java.util.Map;
40*4711b67fSTreehugger Robotimport java.io.IOException;
41*4711b67fSTreehugger Robotimport fi.iki.elonen.NanoHTTPD;
42*4711b67fSTreehugger Robot
43*4711b67fSTreehugger Robotpublic class App extends NanoHTTPD {
44*4711b67fSTreehugger Robot
45*4711b67fSTreehugger Robot    public App() throws IOException {
46*4711b67fSTreehugger Robot        super(8080);
47*4711b67fSTreehugger Robot        start();
48*4711b67fSTreehugger Robot		System.out.println( "\nRunning! Point your browers to http://localhost:8080/ \n" );
49*4711b67fSTreehugger Robot    }
50*4711b67fSTreehugger Robot
51*4711b67fSTreehugger Robot    public static void main(String[] args) {
52*4711b67fSTreehugger Robot		try {
53*4711b67fSTreehugger Robot		    new App();
54*4711b67fSTreehugger Robot		}
55*4711b67fSTreehugger Robot		catch( IOException ioe ) {
56*4711b67fSTreehugger Robot			System.err.println( "Couldn't start server:\n" + ioe );
57*4711b67fSTreehugger Robot		}
58*4711b67fSTreehugger Robot    }
59*4711b67fSTreehugger Robot
60*4711b67fSTreehugger Robot    @Override
61*4711b67fSTreehugger Robot    public Response serve(IHTTPSession session) {
62*4711b67fSTreehugger Robot        String msg = "<html><body><h1>Hello server</h1>\n";
63*4711b67fSTreehugger Robot        Map<String, String> parms = session.getParms();
64*4711b67fSTreehugger Robot        if (parms.get("username") == null) {
65*4711b67fSTreehugger Robot            msg += "<form action='?' method='get'>\n  <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
66*4711b67fSTreehugger Robot        } else {
67*4711b67fSTreehugger Robot            msg += "<p>Hello, " + parms.get("username") + "!</p>";
68*4711b67fSTreehugger Robot        }
69*4711b67fSTreehugger Robot        return newFixedLengthResponse( msg + "</body></html>\n" );
70*4711b67fSTreehugger Robot    }
71*4711b67fSTreehugger Robot}
72*4711b67fSTreehugger Robot```
73*4711b67fSTreehugger Robot
74*4711b67fSTreehugger RobotCompile and run the server:
75*4711b67fSTreehugger Robot
76*4711b67fSTreehugger Robot    mvn compile
77*4711b67fSTreehugger Robot    mvn exec:java -Dexec.mainClass="com.example.App"
78*4711b67fSTreehugger Robot
79*4711b67fSTreehugger RobotIf 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*4711b67fSTreehugger Robot
81*4711b67fSTreehugger Robot### Nanolets
82*4711b67fSTreehugger Robot
83*4711b67fSTreehugger RobotNanolets 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*4711b67fSTreehugger RobotThis 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*4711b67fSTreehugger Robot
86*4711b67fSTreehugger Robot## Status
87*4711b67fSTreehugger Robot
88*4711b67fSTreehugger RobotWe 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*4711b67fSTreehugger Robot
90*4711b67fSTreehugger Robot## Project structure
91*4711b67fSTreehugger Robot
92*4711b67fSTreehugger RobotNanoHTTPD project currently consist of four parts:
93*4711b67fSTreehugger Robot
94*4711b67fSTreehugger Robot * `/core` – Fully functional HTTP(s) server consisting of one (1) Java file, ready to be customized/inherited for your own project
95*4711b67fSTreehugger Robot
96*4711b67fSTreehugger Robot * `/samples` – Simple examples on how to customize NanoHTTPD. See *HelloServer.java* for a killer app that greets you enthusiastically!
97*4711b67fSTreehugger Robot
98*4711b67fSTreehugger Robot * `/websocket` – Websocket implementation, also in a single Java file. Depends on core.
99*4711b67fSTreehugger Robot
100*4711b67fSTreehugger Robot * `/webserver` – Standalone file server. Run & enjoy. A popular use seems to be serving files out off an Android device.
101*4711b67fSTreehugger Robot
102*4711b67fSTreehugger Robot * `/nanolets` – Standalone nano app server, giving a servlet like system to the implementor.
103*4711b67fSTreehugger Robot
104*4711b67fSTreehugger Robot * `/fileupload` – integration of the apache common file upload library.
105*4711b67fSTreehugger Robot
106*4711b67fSTreehugger Robot## Features
107*4711b67fSTreehugger Robot### Core
108*4711b67fSTreehugger Robot* Only one Java file, providing HTTP 1.1 support.
109*4711b67fSTreehugger Robot* No fixed config files, logging, authorization etc. (Implement by yourself if you need them. Errors are passed to java.util.logging, though.)
110*4711b67fSTreehugger Robot* Support for HTTPS (SSL)
111*4711b67fSTreehugger Robot* Basic support for cookies
112*4711b67fSTreehugger Robot* Supports parameter parsing of GET and POST methods.
113*4711b67fSTreehugger Robot* Some built-in support for HEAD, POST and DELETE requests. You can easily implement/customize any HTTP method, though.
114*4711b67fSTreehugger Robot* Supports file upload. Uses memory for small uploads, temp files for large ones.
115*4711b67fSTreehugger Robot* Never caches anything.
116*4711b67fSTreehugger Robot* Does not limit bandwidth, request time or simultaneous connections by default.
117*4711b67fSTreehugger Robot* All header names are converted to lower case so they don't vary between browsers/clients.
118*4711b67fSTreehugger Robot* Persistent connections (Connection "keep-alive") support allowing multiple requests to be served over a single socket connection.
119*4711b67fSTreehugger Robot
120*4711b67fSTreehugger Robot### Websocket
121*4711b67fSTreehugger Robot* Tested on Firefox, Chrome and IE.
122*4711b67fSTreehugger Robot
123*4711b67fSTreehugger Robot### Webserver
124*4711b67fSTreehugger Robot* Default code serves files and shows (prints on console) all HTTP parameters and headers.
125*4711b67fSTreehugger Robot* Supports both dynamic content and file serving.
126*4711b67fSTreehugger Robot* File server supports directory listing, `index.html` and `index.htm`.
127*4711b67fSTreehugger Robot* File server supports partial content (streaming & continue download).
128*4711b67fSTreehugger Robot* File server supports ETags.
129*4711b67fSTreehugger Robot* File server does the 301 redirection trick for directories without `/`.
130*4711b67fSTreehugger Robot* File server serves also very long files without memory overhead.
131*4711b67fSTreehugger Robot* Contains a built-in list of most common MIME types.
132*4711b67fSTreehugger Robot* 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*4711b67fSTreehugger Robot* Simple [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) support via `--cors` paramater
134*4711b67fSTreehugger Robot  * by default serves `Access-Control-Allow-Headers: origin,accept,content-type`
135*4711b67fSTreehugger Robot  * possibility to set `Access-Control-Allow-Headers` by setting System property: `AccessControlAllowHeader`
136*4711b67fSTreehugger Robot  * _example: _ `-DAccessControlAllowHeader=origin,accept,content-type,Authorization`
137*4711b67fSTreehugger Robot  * possible values:
138*4711b67fSTreehugger Robot      * `--cors`: activates CORS support, `Access-Control-Allow-Origin` will be set to `*`
139*4711b67fSTreehugger Robot      * `--cors=some_value`: `Access-Control-Allow-Origin` will be set to `some_value`.
140*4711b67fSTreehugger Robot
141*4711b67fSTreehugger Robot**_CORS argument examples_**
142*4711b67fSTreehugger Robot
143*4711b67fSTreehugger Robot
144*4711b67fSTreehugger Robot* `--cors=http://appOne.company.com`
145*4711b67fSTreehugger Robot* `--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*4711b67fSTreehugger Robot
147*4711b67fSTreehugger Robot## Maven dependencies
148*4711b67fSTreehugger Robot
149*4711b67fSTreehugger RobotNanoHTTPD 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*4711b67fSTreehugger Robot
151*4711b67fSTreehugger Robot	<dependencies>
152*4711b67fSTreehugger Robot		<dependency>
153*4711b67fSTreehugger Robot			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
154*4711b67fSTreehugger Robot			<artifactId>nanohttpd</artifactId>
155*4711b67fSTreehugger Robot			<version>CURRENT_VERSION</version>
156*4711b67fSTreehugger Robot		</dependency>
157*4711b67fSTreehugger Robot	</dependencies>
158*4711b67fSTreehugger Robot
159*4711b67fSTreehugger Robot(Replace `CURRENT_VERSION` with whatever is reported latest at <http://nanohttpd.org/>.)
160*4711b67fSTreehugger Robot
161*4711b67fSTreehugger RobotThe 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*4711b67fSTreehugger Robot
163*4711b67fSTreehugger RobotNext it depends what you are useing nanohttpd for, there are tree main usages.
164*4711b67fSTreehugger Robot
165*4711b67fSTreehugger Robot## Gradle dependencies
166*4711b67fSTreehugger Robot
167*4711b67fSTreehugger RobotIn gradle you can use nano http the same way because gradle accesses the same central repository:
168*4711b67fSTreehugger Robot
169*4711b67fSTreehugger Robot	dependencies {
170*4711b67fSTreehugger Robot		runtime(
171*4711b67fSTreehugger Robot			[group: 'org.nanohttpd', name: 'nanohttpd', version: 'CURRENT_VERSION'],
172*4711b67fSTreehugger Robot		)
173*4711b67fSTreehugger Robot	}
174*4711b67fSTreehugger Robot
175*4711b67fSTreehugger Robot(Replace `CURRENT_VERSION` with whatever is reported latest at <http://nanohttpd.org/>.)
176*4711b67fSTreehugger Robot
177*4711b67fSTreehugger RobotJust replace the name with the artifact id of the module you want to use and gradle will find it for you.
178*4711b67fSTreehugger Robot
179*4711b67fSTreehugger Robot### Develop your own specialized HTTP service
180*4711b67fSTreehugger Robot
181*4711b67fSTreehugger RobotFor a specialized HTTP (HTTPS) service you can use the module with artifactId *nanohttpd*.
182*4711b67fSTreehugger Robot
183*4711b67fSTreehugger Robot		<dependency>
184*4711b67fSTreehugger Robot			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
185*4711b67fSTreehugger Robot			<artifactId>nanohttpd</artifactId>
186*4711b67fSTreehugger Robot			<version>CURRENT_VERSION</version>
187*4711b67fSTreehugger Robot		</dependency>
188*4711b67fSTreehugger Robot
189*4711b67fSTreehugger RobotHere you write your own subclass of *fi.iki.elonen.NanoHTTPD* to configure and to serve the requests.
190*4711b67fSTreehugger Robot
191*4711b67fSTreehugger Robot### Develop a websocket based service
192*4711b67fSTreehugger Robot
193*4711b67fSTreehugger RobotFor a specialized websocket service you can use the module with artifactId *nanohttpd-websocket*.
194*4711b67fSTreehugger Robot
195*4711b67fSTreehugger Robot		<dependency>
196*4711b67fSTreehugger Robot			<groupId>org.nanohttpd</groupId> <!-- <groupId>com.nanohttpd</groupId> for 2.1.0 and earlier -->
197*4711b67fSTreehugger Robot			<artifactId>nanohttpd-websocket</artifactId>
198*4711b67fSTreehugger Robot			<version>CURRENT_VERSION</version>
199*4711b67fSTreehugger Robot		</dependency>
200*4711b67fSTreehugger Robot
201*4711b67fSTreehugger RobotHere 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*4711b67fSTreehugger Robot
203*4711b67fSTreehugger Robot### Develop a custom HTTP file server
204*4711b67fSTreehugger Robot
205*4711b67fSTreehugger RobotFor 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*4711b67fSTreehugger Robot
207*4711b67fSTreehugger Robot		<dependency>
208*4711b67fSTreehugger Robot			<groupId>org.nanohttpd</groupId>
209*4711b67fSTreehugger Robot			<artifactId>nanohttpd-webserver</artifactId>
210*4711b67fSTreehugger Robot			<version>CURRENT_VERSION</version>
211*4711b67fSTreehugger Robot		</dependency>
212*4711b67fSTreehugger Robot
213*4711b67fSTreehugger RobotThe 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*4711b67fSTreehugger Robot
215*4711b67fSTreehugger Robot### Living on the edge
216*4711b67fSTreehugger Robot
217*4711b67fSTreehugger RobotThe latest Github master version can be fetched through sonatype.org:
218*4711b67fSTreehugger Robot
219*4711b67fSTreehugger Robot	<dependencies>
220*4711b67fSTreehugger Robot		<dependency>
221*4711b67fSTreehugger Robot			<artifactId>nanohttpd</artifactId>
222*4711b67fSTreehugger Robot			<groupId>org.nanohttpd</groupId>
223*4711b67fSTreehugger Robot			<version>XXXXX-SNAPSHOT</version>
224*4711b67fSTreehugger Robot		</dependency>
225*4711b67fSTreehugger Robot	</dependencies>
226*4711b67fSTreehugger Robot	...
227*4711b67fSTreehugger Robot	<repositories>
228*4711b67fSTreehugger Robot		<repository>
229*4711b67fSTreehugger Robot			<id>sonatype-snapshots</id>
230*4711b67fSTreehugger Robot			<url>https://oss.sonatype.org/content/repositories/snapshots</url>
231*4711b67fSTreehugger Robot			<snapshots>
232*4711b67fSTreehugger Robot				<enabled>true</enabled>
233*4711b67fSTreehugger Robot			</snapshots>
234*4711b67fSTreehugger Robot		</repository>
235*4711b67fSTreehugger Robot	</repositories>
236*4711b67fSTreehugger Robot
237*4711b67fSTreehugger Robot### generating an self signed ssl certificate
238*4711b67fSTreehugger Robot
239*4711b67fSTreehugger RobotJust a hint how to generate a certificate for localhost.
240*4711b67fSTreehugger Robot
241*4711b67fSTreehugger Robot	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*4711b67fSTreehugger Robot
243*4711b67fSTreehugger RobotThis 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*4711b67fSTreehugger Robotyou can use:
245*4711b67fSTreehugger Robot
246*4711b67fSTreehugger Robot	server.makeSecure(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()));
247*4711b67fSTreehugger Robot
248*4711b67fSTreehugger RobotBefore you start the server to make Nanohttpd serve https connections, when you make sure 'keystore.jks' is in your classpath .
249*4711b67fSTreehugger Robot
250*4711b67fSTreehugger Robot-----
251*4711b67fSTreehugger Robot
252*4711b67fSTreehugger Robot*Thank you to everyone who has reported bugs and suggested fixes.*
253