aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/fi/iki/elonen/NanoHTTPD.java')
-rw-r--r--core/src/main/java/fi/iki/elonen/NanoHTTPD.java157
1 files changed, 79 insertions, 78 deletions
diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
index 2a7713e..d32ade4 100644
--- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
+++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
@@ -8,18 +8,18 @@ package fi.iki.elonen;
* %%
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* 3. Neither the name of the nanohttpd nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -34,6 +34,7 @@ package fi.iki.elonen;
*/
import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
@@ -43,6 +44,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.PushbackInputStream;
import java.io.RandomAccessFile;
@@ -79,6 +81,9 @@ import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManagerFactory;
+import fi.iki.elonen.NanoHTTPD.Response.IStatus;
+import fi.iki.elonen.NanoHTTPD.Response.Status;
+
/**
* A simple, tiny, nicely embeddable HTTP server in Java
* <p/>
@@ -231,7 +236,7 @@ public abstract class NanoHTTPD {
* Provides rudimentary support for cookies. Doesn't support 'path',
* 'secure' nor 'httpOnly'. Feel free to improve it and/or add unsupported
* features.
- *
+ *
* @author LordFokas
*/
public class CookieHandler implements Iterable<String> {
@@ -256,7 +261,7 @@ public abstract class NanoHTTPD {
/**
* Set a cookie with an expiration date from a month ago, effectively
* deleting it on the client side.
- *
+ *
* @param name
* The cookie name.
*/
@@ -271,7 +276,7 @@ public abstract class NanoHTTPD {
/**
* Read a cookie from the HTTP Headers.
- *
+ *
* @param name
* The cookie's name.
* @return The cookie's value if it exists, null otherwise.
@@ -286,7 +291,7 @@ public abstract class NanoHTTPD {
/**
* Sets a cookie.
- *
+ *
* @param name
* The cookie's name.
* @param value
@@ -301,7 +306,7 @@ public abstract class NanoHTTPD {
/**
* Internally used by the webserver to add all queued cookies into the
* Response's HTTP Headers.
- *
+ *
* @param response
* The Response object to which headers the queued cookies
* will be added.
@@ -730,11 +735,11 @@ public abstract class NanoHTTPD {
// exception up the call stack.
throw ste;
} catch (IOException ioe) {
- Response r = new Response(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
+ Response r = newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
r.send(this.outputStream);
safeClose(this.outputStream);
} catch (ResponseException re) {
- Response r = new Response(re.getStatus(), NanoHTTPD.MIME_PLAINTEXT, re.getMessage());
+ Response r = newFixedLengthResponse(re.getStatus(), NanoHTTPD.MIME_PLAINTEXT, re.getMessage());
r.send(this.outputStream);
safeClose(this.outputStream);
} finally {
@@ -993,7 +998,7 @@ public abstract class NanoHTTPD {
/**
* Adds the files in the request body to the files map.
- *
+ *
* @param files
* map to modify
*/
@@ -1107,63 +1112,19 @@ public abstract class NanoHTTPD {
private boolean chunkedTransfer;
/**
- * Create a response with known length.
- */
- public static Response NewFixedLengthResponse(IStatus status, String mimeType, InputStream data, int totalBytes) {
- return new Response(status, mimeType, data, totalBytes);
- }
-
- /**
- * Create a response with unknown length (using HTTP 1.1 chunking).
- */
- public static Response NewChunkedResponse(IStatus status, String mimeType, InputStream data) {
- return new Response(status, mimeType, data, -1);
- }
-
- @Deprecated
- public Response(IStatus status, String mimeType, InputStream data) {
- this.status = status;
- this.mimeType = mimeType;
- this.data = data;
- this.contentLength = -1;
- this.chunkedTransfer = true;
- }
-
- /**
* Creates a fixed length response if totalBytes>=0, otherwise chunked.
*/
protected Response(IStatus status, String mimeType, InputStream data, int totalBytes) {
this.status = status;
this.mimeType = mimeType;
- this.data = data;
- this.contentLength = totalBytes;
- this.chunkedTransfer = totalBytes < 0;
- }
-
- /**
- * Convenience method that makes an InputStream out of a given UTF-8
- * string.
- */
- public Response(IStatus status, String mimeType, String txt) {
- this.status = status;
- this.mimeType = mimeType;
- this.contentLength = 0;
- try {
- this.data = txt != null ? new ByteArrayInputStream(txt.getBytes("UTF-8")) : null;
- this.contentLength = (this.data != null) ? this.data.available() : 0;
- } catch (java.io.UnsupportedEncodingException uee) {
- NanoHTTPD.LOG.log(Level.SEVERE, "encoding problem", uee);
- } catch (java.io.IOException ioe) {
- NanoHTTPD.LOG.log(Level.SEVERE, "ByteArrayInputStream.available() failed?!?", ioe);
+ if (data == null) {
+ this.data = new ByteArrayInputStream(new byte[0]);
+ this.contentLength = 0;
+ } else {
+ this.data = data;
+ this.contentLength = totalBytes;
}
- }
-
- /**
- * Default constructor: response = Status.OK, mime = MIME_HTML and your
- * supplied message
- */
- public Response(String msg) {
- this(Status.OK, NanoHTTPD.MIME_HTML, msg);
+ this.chunkedTransfer = this.contentLength < 0;
}
/**
@@ -1213,7 +1174,7 @@ public abstract class NanoHTTPD {
if (this.status == null) {
throw new Error("sendResponse(): Status can't be null.");
}
- PrintWriter pw = new PrintWriter(outputStream);
+ PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8")), false);
pw.print("HTTP/1.1 " + this.status.getDescription() + " \r\n");
if (mime != null) {
@@ -1563,7 +1524,7 @@ public abstract class NanoHTTPD {
/**
* create a instance of the client handler, subclasses can return a subclass
* of the ClientHandler.
- *
+ *
* @param finalAccept
* the socket the cleint is connected to
* @param inputStream
@@ -1577,7 +1538,7 @@ public abstract class NanoHTTPD {
/**
* Instantiate the server runnable, can be overwritten by subclasses to
* provide a subclass of the ServerRunnable.
- *
+ *
* @param timeout
* the socet timeout to use.
* @return the server runnable.
@@ -1590,7 +1551,7 @@ public abstract class NanoHTTPD {
* Decode parameters from a URL, handing the case where a single parameter
* name might have been supplied several times, by return lists of values.
* In general these lists will contain a single element.
- *
+ *
* @param parms
* original <b>NanoHTTPD</b> parameters values, as passed to the
* <code>serve()</code> method.
@@ -1608,7 +1569,7 @@ public abstract class NanoHTTPD {
* Decode parameters from a URL, handing the case where a single parameter
* name might have been supplied several times, by return lists of values.
* In general these lists will contain a single element.
- *
+ *
* @param queryString
* a query string pulled from the URL.
* @return a map of <code>String</code> (parameter name) to
@@ -1636,7 +1597,7 @@ public abstract class NanoHTTPD {
/**
* Decode percent encoded <code>String</code> values.
- *
+ *
* @param str
* the percent encoded <code>String</code>
* @return expanded form of the input, for example "foo%20bar" becomes
@@ -1668,11 +1629,50 @@ public abstract class NanoHTTPD {
}
/**
+ * Create a response with unknown length (using HTTP 1.1 chunking).
+ */
+ public Response newChunkedResponse(IStatus status, String mimeType, InputStream data) {
+ return new Response(status, mimeType, data, -1);
+ }
+
+ /**
+ * Create a response with known length.
+ */
+ public Response newFixedLengthResponse(IStatus status, String mimeType, InputStream data, int totalBytes) {
+ return new Response(status, mimeType, data, totalBytes);
+ }
+
+ /**
+ * Create a text response with known length.
+ */
+ public Response newFixedLengthResponse(IStatus status, String mimeType, String txt) {
+ if (txt == null) {
+ return newFixedLengthResponse(status, mimeType, new ByteArrayInputStream(new byte[0]), 0);
+ } else {
+ byte[] bytes;
+ try {
+ bytes = txt.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ NanoHTTPD.LOG.log(Level.SEVERE, "encoding problem, responding nothing", e);
+ bytes = new byte[0];
+ }
+ return newFixedLengthResponse(status, mimeType, new ByteArrayInputStream(bytes), bytes.length);
+ }
+ }
+
+ /**
+ * Create a text response with known length.
+ */
+ public Response newFixedLengthResponse(String msg) {
+ return newFixedLengthResponse(Status.OK, NanoHTTPD.MIME_HTML, msg);
+ }
+
+ /**
* Override this to customize the server.
* <p/>
* <p/>
* (By default, this returns a 404 "Not Found" plain text error response.)
- *
+ *
* @param session
* The HTTP session
* @return HTTP response, see class Response for details
@@ -1684,9 +1684,9 @@ public abstract class NanoHTTPD {
try {
session.parseBody(files);
} catch (IOException ioe) {
- return new Response(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
+ return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
} catch (ResponseException re) {
- return new Response(re.getStatus(), NanoHTTPD.MIME_PLAINTEXT, re.getMessage());
+ return newFixedLengthResponse(re.getStatus(), NanoHTTPD.MIME_PLAINTEXT, re.getMessage());
}
}
@@ -1700,7 +1700,7 @@ public abstract class NanoHTTPD {
* <p/>
* <p/>
* (By default, this returns a 404 "Not Found" plain text error response.)
- *
+ *
* @param uri
* Percent-decoded URI without parameters, for example
* "/index.cgi"
@@ -1715,12 +1715,12 @@ public abstract class NanoHTTPD {
*/
@Deprecated
public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
- return new Response(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Not Found");
+ return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Not Found");
}
/**
* Pluggable strategy for asynchronously executing requests.
- *
+ *
* @param asyncRunner
* new strategy for handling threads.
*/
@@ -1730,7 +1730,7 @@ public abstract class NanoHTTPD {
/**
* Pluggable strategy for creating and cleaning up temporary files.
- *
+ *
* @param tempFileManagerFactory
* new strategy for handling temp files.
*/
@@ -1740,7 +1740,7 @@ public abstract class NanoHTTPD {
/**
* Start the server.
- *
+ *
* @throws IOException
* if the socket is in use.
*/
@@ -1750,7 +1750,7 @@ public abstract class NanoHTTPD {
/**
* Start the server.
- *
+ *
* @param timeout
* timeout to use for socket connections.
* @throws IOException
@@ -1791,4 +1791,5 @@ public abstract class NanoHTTPD {
public final boolean wasStarted() {
return this.myServerSocket != null && this.myThread != null;
}
+
}