summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
diff options
context:
space:
mode:
authorSimon Rettberg2015-09-04 15:50:33 +0200
committerSimon Rettberg2015-09-04 15:50:33 +0200
commitcf5c2c886f65e61870b951546258949e3a4030f8 (patch)
tree7ac4dfeb26c60a3213e9e4fa4c69f515a42e2e16 /dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
parent[*] OS now has mem and cpu info (diff)
downloadtutor-module-cf5c2c886f65e61870b951546258949e3a4030f8.tar.gz
tutor-module-cf5c2c886f65e61870b951546258949e3a4030f8.tar.xz
tutor-module-cf5c2c886f65e61870b951546258949e3a4030f8.zip
[server] mailtest RPC methods, bugfixes to nanohttpd
Diffstat (limited to 'dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java')
-rw-r--r--dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java51
1 files changed, 37 insertions, 14 deletions
diff --git a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
index f8e44fa8..8d38f577 100644
--- a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
+++ b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
@@ -50,6 +50,7 @@ import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -66,6 +67,8 @@ import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.log4j.Logger;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
@@ -121,6 +124,9 @@ import org.joda.time.format.DateTimeFormatter;
* licence)
*/
public abstract class NanoHTTPD implements Runnable {
+
+ private static final Logger LOGGER = Logger.getLogger(NanoHTTPD.class);
+
/**
* Maximum time to wait on Socket.getInputStream().read() (in milliseconds)
* This is required as the Keep-Alive HTTP connections would otherwise
@@ -150,6 +156,8 @@ public abstract class NanoHTTPD implements Runnable {
*/
private AsyncRunner asyncRunner;
+ protected int maxRequestSize = 0;
+
/**
* Constructs an HTTP server on given port.
*/
@@ -847,6 +855,8 @@ public abstract class NanoHTTPD implements Runnable {
if (splitbyte > 0)
break;
read = inputStream.read(buf, rlen, BUFSIZE - rlen);
+ if (maxRequestSize != 0 && rlen > maxRequestSize)
+ throw new SocketException("Request too large");
}
}
@@ -909,7 +919,6 @@ public abstract class NanoHTTPD implements Runnable {
@Override
public void parseBody(Map<String, String> files) throws IOException, ResponseException {
- final Reader in = new InputStreamReader(inputStream);
long size;
if (headers.containsKey("content-length")) {
size = Integer.parseInt(headers.get("content-length"));
@@ -922,36 +931,50 @@ public abstract class NanoHTTPD implements Runnable {
// If the method is POST, there may be parameters
// in data section, too, read it:
if (Method.POST.equals(method)) {
- String contentType = "";
+ String contentType = null;
+ String contentEncoding = null;
String contentTypeHeader = headers.get("content-type");
StringTokenizer st = null;
if (contentTypeHeader != null) {
- st = new StringTokenizer(contentTypeHeader, ",; ");
+ st = new StringTokenizer(contentTypeHeader, ",");
if (st.hasMoreTokens()) {
- contentType = st.nextToken();
+ String part[] = st.nextToken().split(";\\s*", 2);
+ contentType = part[0];
+ if (part.length == 2) {
+ contentEncoding = part[1];
+ }
}
}
+ Charset cs = StandardCharsets.ISO_8859_1;
+ if (contentEncoding != null) {
+ try {
+ cs = Charset.forName(contentEncoding);
+ } catch (Exception e) {
+ }
+ }
+ LOGGER.debug("Content type is '" + contentType + "', encoding '" + cs.name() + "'");
if ("multipart/form-data".equalsIgnoreCase(contentType)) {
throw new ResponseException(Response.Status.BAD_REQUEST,
"BAD REQUEST: Content type is multipart/form-data, which is not supported");
} else {
- String postLine = "";
- StringBuilder postLineBuffer = new StringBuilder();
- char pbuf[] = new char[512];
- while (rlen >= 0 && size > 0 && !postLine.endsWith("\r\n")) {
- rlen = in.read(pbuf, 0, (int) Math.min(size, 512));
- if (rlen <= 0)
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte pbuf[] = new byte[1000];
+ while (size > 0) {
+ int ret = inputStream.read(pbuf, 0, (int) Math.min(size, pbuf.length));
+ if (ret <= 0)
+ break;
+ if (ret >= 2 && pbuf[ret - 1] == '\n' && pbuf[ret - 2] == '\r')
break;
- postLine = String.valueOf(pbuf, 0, rlen);
- postLineBuffer.append(postLine);
+ size -= ret;
+ baos.write(pbuf, 0, ret);
}
- postLine = postLineBuffer.toString().trim();
+ String postLine = new String(baos.toByteArray(), cs);
// Handle application/x-www-form-urlencoded
if ("application/x-www-form-urlencoded".equalsIgnoreCase(contentType)) {
decodeParms(postLine, parms);
- } else if (postLine.length() != 0) {
+ } else if (files != null && postLine.length() != 0) {
// Special case for raw POST data => create a special files entry "postData" with raw content data
files.put("postData", postLine);
}