Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/sunlabs/brazil/util/http/HttpRequest.java

Issue 10102005: ABP/Android Process chunked requests (Closed)
Patch Set: ABP/Android Process chunked requests Created April 9, 2013, 8:45 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/sunlabs/brazil/server/Request.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/sunlabs/brazil/util/http/HttpRequest.java
===================================================================
--- a/src/sunlabs/brazil/util/http/HttpRequest.java
+++ b/src/sunlabs/brazil/util/http/HttpRequest.java
@@ -26,6 +26,9 @@
*
* Version Histories:
*
+ * 13/04/09-12:44:12 (andrey@adblockplus.org)
+ * implemented proxying chunked request body
+ *
* 2.7 07/03/26-13:53:18 (suhler)
* doc updates
*
@@ -479,6 +482,7 @@
HttpInputStream in;
InputStream under;
+ HttpInputStream cs;
/**
* The status line from the HTTP response. This field is not valid until
@@ -670,6 +674,12 @@
return postData;
}
+ public void
+ setHttpInputStream(HttpInputStream cs)
+ {
+ this.cs = cs;
+ }
+
/**
* Connect to the target host (or proxy), send the request, and read the
* response headers. Any setup routines must be called before the call
@@ -869,9 +879,84 @@
postData.writeTo(p);
postData = null; // Release memory.
}
+
+ // Pass any data left in client stream (in case of chunked request content)
+ String encoding = requestHeaders.get("Transfer-Encoding", "");
+ if (encoding != null && encoding.equals("chunked") && cs != null)
Felix Dahlke 2013/04/09 09:16:48 You could just do '"chunked".equals(encoding)' to
Andrey Novikov 2013/04/10 08:30:30 Done.
+ {
+ byte[] buf = new byte[4096];
Felix Dahlke 2013/04/09 09:16:48 Indentation is off here
+ int bytesLeft = -1;
+ while (true)
+ {
+ // Read chunk size
+ if (bytesLeft <= 0)
+ {
+ bytesLeft = getChunkSize(cs);
+ // Output chunk size
+ p.print(Integer.toHexString(bytesLeft) + "\r\n");
+ }
+ if (bytesLeft == 0)
+ break;
+ // Pass chunk data
+ int count = cs.read(buf, 0, Math.min(bytesLeft, buf.length));
+ if (count < 0)
+ {
+ // This shouldn't occur - no final zero chunk
+ bytesLeft = -1;
+ break;
+ }
+ p.write(buf, 0, count);
+ bytesLeft -= count;
+ if (bytesLeft == 0)
+ p.print("\r\n");
+ }
+ // Pass the trailer
+ if (bytesLeft == 0)
+ {
+ while (true)
+ {
+ String line = cs.readLine(LINE_LIMIT);
+ if (line == null)
+ break;
+ p.print(line + "\r\n");
+ if (line.length() == 0)
+ break;
+ }
+ }
+ }
+
p.flush();
}
+ /*
+ * Copied (with some amendmends) from UnchunkingInputStream / andrey@adblockplus.org
+ */
+ private int
+ getChunkSize(HttpInputStream is)
+ throws IOException
+ {
+ /*
+ * Although HTTP/1.1 chunking spec says that there is one "\r\n"
+ * between chunks, some servers (for example, maps.yahoo.com)
+ * send more than one blank line between chunks. So, read and skip
+ * all the blank lines seen between chunks.
+ */
+
+ int bytesLeft = 0;
+ String line;
+ do {
+ // Sanity check: limit chars when expecting a chunk size.
+ line = is.readLine(HttpRequest.LINE_LIMIT);
+ } while ((line != null) && (line.length() == 0));
Felix Dahlke 2013/04/09 09:16:48 Here's a shorter alternative: while("".equals(line
Andrey Novikov 2013/04/10 08:30:30 This was copied from another part of Brazil, I'll
+
+ try {
+ bytesLeft = Integer.parseInt(line.trim(), 16);
+ } catch (Exception e) {
+ throw new IOException("malformed chunk");
+ }
+ return bytesLeft;
+ }
+
void
readStatusLine()
throws IOException
« no previous file with comments | « src/sunlabs/brazil/server/Request.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld