Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
Expand Down Expand Up @@ -64,13 +65,17 @@ public void close() {
NanoHTTPD.safeClose(this.acceptSocket);
}

protected HTTPSession createHTTPSession(NanoHTTPD httpd, ITempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream, InetAddress inetAddress) {
return new HTTPSession(httpd, tempFileManager, inputStream, outputStream, inetAddress);
}

@Override
public void run() {
OutputStream outputStream = null;
try {
outputStream = this.acceptSocket.getOutputStream();
ITempFileManager tempFileManager = httpd.getTempFileManagerFactory().create();
HTTPSession session = new HTTPSession(httpd, tempFileManager, this.inputStream, outputStream, this.acceptSocket.getInetAddress());
final ITempFileManager tempFileManager = httpd.getTempFileManagerFactory().create();
final HTTPSession session = createHTTPSession(httpd, tempFileManager, this.inputStream, outputStream, this.acceptSocket.getInetAddress());
while (!this.acceptSocket.isClosed()) {
session.execute();
}
Expand Down
46 changes: 32 additions & 14 deletions core/src/main/java/org/nanohttpd/protocols/http/HTTPSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,17 @@ public class HTTPSession implements IHTTPSession {

public static final String POST_DATA = "postData";

private static final int REQUEST_BUFFER_LEN = 512;
private static final int DEFAULT_REQUEST_BUFFER_LEN = 512;

private static final int MEMORY_STORE_LIMIT = 1024;
private static final int DEFAULT_MEMORY_STORE_LIMIT = 1024;

public static final int BUFSIZE = 8192;

public static final int MAX_HEADER_SIZE = 1024;

private final NanoHTTPD httpd;

private final ITempFileManager tempFileManager;
protected final ITempFileManager tempFileManager;

private final OutputStream outputStream;

Expand Down Expand Up @@ -121,10 +121,7 @@ public HTTPSession(NanoHTTPD httpd, ITempFileManager tempFileManager, InputStrea
}

public HTTPSession(NanoHTTPD httpd, ITempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream, InetAddress inetAddress) {
this.httpd = httpd;
this.tempFileManager = tempFileManager;
this.inputStream = new BufferedInputStream(inputStream, HTTPSession.BUFSIZE);
this.outputStream = outputStream;
this(httpd, tempFileManager, inputStream, outputStream);
this.remoteIp = inetAddress.isLoopbackAddress() || inetAddress.isAnyLocalAddress() ? "127.0.0.1" : inetAddress.getHostAddress().toString();
this.remoteHostname = inetAddress.isLoopbackAddress() || inetAddress.isAnyLocalAddress() ? "localhost" : inetAddress.getHostName().toString();
this.headers = new HashMap<String, String>();
Expand Down Expand Up @@ -584,6 +581,22 @@ private RandomAccessFile getTmpBucket() {
}
}

/**
* Get the maximum size of uploaded data to be stored in memory;
* otherwise it will be dumped to disk.
* If null, disk storage is never used.
*/
protected Integer getMemoryStoreLimit() {
return new Integer(DEFAULT_MEMORY_STORE_LIMIT);
}

/**
* Get the buffer size for network reads.
*/
protected int getRequestBufferLen() {
return DEFAULT_REQUEST_BUFFER_LEN;
}

@Override
public final String getUri() {
return this.uri;
Expand All @@ -607,29 +620,34 @@ public void parseBody(Map<String, String> files) throws IOException, ResponseExc
RandomAccessFile randomAccessFile = null;
try {
long size = getBodySize();
ByteArrayOutputStream baos = null;
DataOutput requestDataOutput = null;
final ByteArrayOutputStream baos;
final DataOutput requestDataOutput;

final Integer memoryStoreLimit = getMemoryStoreLimit();

// Store the request in memory or a file, depending on size
if (size < MEMORY_STORE_LIMIT) {
if (memoryStoreLimit == null || size < memoryStoreLimit.intValue()) {
baos = new ByteArrayOutputStream();
requestDataOutput = new DataOutputStream(baos);
} else {
baos = null;
randomAccessFile = getTmpBucket();
requestDataOutput = randomAccessFile;
}

final int requestBufferLen = getRequestBufferLen();

// Read all the body and write it to request_data_output
byte[] buf = new byte[REQUEST_BUFFER_LEN];
final byte[] buf = new byte[requestBufferLen];
while (this.rlen >= 0 && size > 0) {
this.rlen = this.inputStream.read(buf, 0, (int) Math.min(size, REQUEST_BUFFER_LEN));
this.rlen = this.inputStream.read(buf, 0, (int) Math.min(size, requestBufferLen));
size -= this.rlen;
if (this.rlen > 0) {
requestDataOutput.write(buf, 0, this.rlen);
}
}

ByteBuffer fbuf = null;
final ByteBuffer fbuf;
if (baos != null) {
fbuf = ByteBuffer.wrap(baos.toByteArray(), 0, baos.size());
} else {
Expand Down Expand Up @@ -673,7 +691,7 @@ public void parseBody(Map<String, String> files) throws IOException, ResponseExc
* Retrieves the content of a sent file and saves it to a temporary file.
* The full path to the saved file is returned.
*/
private String saveTmpFile(ByteBuffer b, int offset, int len, String filename_hint) {
protected String saveTmpFile(ByteBuffer b, int offset, int len, String filename_hint) {
String path = "";
if (len > 0) {
FileOutputStream fileOutputStream = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
*/
public interface ITempFile {

public void delete() throws Exception;
void delete() throws Exception;

public String getName();
String getName();

public OutputStream open() throws Exception;
OutputStream open() throws Exception;
}