New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POST HTTP Body #99
Comments
+1, experiencing the same problem - consuming the session.getInputStream will never return -1 as end of stream, but rather throw
instead... Switched over to using .available() to get the stream length but this is an ugly hack. |
Can you please give a small example about your work around? I'm not sure what you are meaning. |
You can do this very similarly to how the beginning of the parseBody(Map<String, String> files) method works. Retrieve the "content-length" from the headers, then read the input stream using "content-length" as the number of bytes to be read.
It would be nice if NanoHTTPD did this for us. Maybe a pull request is in order. |
I am always happy to accept pull requests - the proposed helper method sounds very testable too, so please include appropriate unit tests with the code change and I'll see about merging it. |
Quick hack to support reading text-based posts (e.g. JSON) Can someone see if they can apply this to the current tree? I couldn't get format-patch to output a clean patch so this is a bit hacked up @@ -960,6 +928,7 @@ public abstract class NanoHTTPD {
* @param files map to modify
*/
void parseBody(Map<String, String> files) throws IOException, ResponseException;
+ String parsePost() throws IOException, ResponseException;
}
protected class HTTPSession implements IHTTPSession {
@@ -1089,6 +1058,30 @@ public abstract class NanoHTTPD {
}
@Override
+ public String parsePost() throws IOException, ResponseException {
+ long size;
+ if (headers.containsKey("content-length")) {
+ size = Integer.parseInt(headers.get("content-length"));
+ } else {
+ size = 0;
+ }
+ //http://stackoverflow.com/a/9133993/229631
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, len);
+ }
+
+ byte[] outputBytes = outputStream.toByteArray();
+ //todo: this will break with size > int.max
+ byte[] postBodyBytes = Arrays.copyOfRange(outputBytes, outputBytes.length - (int) size, outputBytes.length);
+
+ return new String(postBodyBytes);
+ }
+
+ @Override
public void parseBody(Map<String, String> files) throws IOException, ResponseException {
RandomAccessFile randomAccessFile = null;
BufferedReader in = null;
|
Refactoring the first part of If we decide to provide a request body => String helper, it should probably take character encoding into account. For example: |
At least for my purposes, a function that returned a stream would be most
useful. I'll look at it this week.
I also noticed it's not easy to implement this kind of thing in an
extension class - say for implementing automatic JSON deserialisation.
|
Can you comment on how plausible it would be to pull this out into something that could be extended/overridden by people, like https://github.com/NanoHttpd/nanohttpd/wiki/How-to-use-NanoHttpd? I think that a getBody() that returned a String or Stream would be most useful inside NanoHTTPD itself, and then leave more complex operations (JSON parsing) to the implementer. |
Yes, JSON parsing is definitely too specific a feature, but a Can you elaborate on the extendable/overridable question, or propose something about that @voltagex ? |
@ranjithsr: You can call |
+1. Please simplify getting content of POST request. Answers from http://stackoverflow.com/questions/22349772/retrieve-http-body-in-nanohttpd looks like dirty magic |
@fedotxxl : I'm re-closing this, but if you have a concrete suggestion / question for a better API, feel free to submit a new issue or pull request. |
I tried this code, but the payload is not fully copied to the buffer. It works only for small payloads. |
I'm very late to the party, but I agree with the sentiment expressed in this ticket that it should be more intuitive to get the POST body either as a string, or by just consuming an InputStream. I too lost a lot of time trying to consume the body only to bump into this closed issue that doesn't have a particularly good answer. If this functionality is considered undesirable, then having a clear example snippet in the README would be very helpful. |
How can I read the full HTTP body of the send request in my
public Response serve(IHTTPSession session) {
implementation?(I've tried
IOUtils.readFully(session.getInputStream(), -1, false)
already but it looks like it always ends in aSocketTimeoutException
.)The text was updated successfully, but these errors were encountered: