Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Unified Diff: components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java

Issue 966743003: [Cronet] Implement getOutputStream in CronetHttpURLConnection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chunked_support
Patch Set: Use large data in buffered case too Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java
new file mode 100644
index 0000000000000000000000000000000000000000..9eb03bcf82c386f4b2e26e3129d8ada5a28f1ee3
--- /dev/null
+++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java
@@ -0,0 +1,105 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.net.urlconnection;
+
+import org.chromium.net.UploadDataProvider;
+import org.chromium.net.UploadDataSink;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * An implementation of {@link java.io.OutputStream} that buffers entire request
+ * body in memory. This is used when neither
+ * {@link CronetHttpURLConnection#setFixedLengthStreamingMode}
+ * or {@link CronetHttpURLConnection#setChunkedStreamingMode} is set.
+ */
+final class CronetBufferedOutputStream extends OutputStream
+ implements UploadDataProvider {
+ private final int mInitialContentLength;
+ private final CronetHttpURLConnection mConnection;
+ // Internal buffer that is used to buffer the request body.
+ private final ByteArrayOutputStream mBuffer;
+ // Number of bytes consumed by the native UploadDataStream.
+ private int mBytesConsumed;
+
+ /**
+ * Packaged protected constructor.
mef 2015/03/10 16:48:22 nit: Package protected constructor.
xunjieli 2015/03/12 21:55:09 Done.
+ * @param connection The CronetHttpURLConnection object.
+ * @param contentLength The content length of the request body. If content
+ * length cannot be determined in advance, use -1.
+ */
+ CronetBufferedOutputStream(final CronetHttpURLConnection connection,
+ final long contentLength) {
+ if (connection == null) {
+ throw new NullPointerException();
+ }
+
+ if (contentLength > Integer.MAX_VALUE) {
mef 2015/03/10 16:48:22 what if it is negative, but not -1?
xunjieli 2015/03/12 21:55:09 Done. Right, we should handle that case. To make a
+ throw new IllegalStateException("Use setFixedLengthStreamingMode()"
+ + " or setChunkedStreamingMode() for requests larger than 2GB.");
+ }
+ mConnection = connection;
+ mInitialContentLength = (int) contentLength;
+ if (mInitialContentLength == -1) {
+ // Bufferring without knowing content-length.
+ mBuffer = new ByteArrayOutputStream();
+ } else {
+ mBuffer = new ByteArrayOutputStream(mInitialContentLength);
+ }
+ mBytesConsumed = 0;
+ }
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ mBuffer.write((byte) oneByte);
+ if (mBuffer.size() == mInitialContentLength) {
mef 2015/03/10 16:48:22 what happens if app will write more than expected?
xunjieli 2015/03/12 21:55:09 Done. Good catch, it should fail with a java.net.P
+ // Entire post data has been received. Now start the request.
+ mConnection.connect();
+ }
+ }
+
+ @Override
+ public void write(byte[] buffer, int offset, int count) throws IOException {
+ mBuffer.write(buffer, offset, count);
+ if (mInitialContentLength != -1 && mBuffer.size() > mInitialContentLength) {
+ throw new IllegalStateException("Writing out of bound.");
+ }
+ if (mBuffer.size() == mInitialContentLength) {
mef 2015/03/10 16:48:22 When does it connect() if mInitialContentLength ==
xunjieli 2015/03/12 21:55:09 The embedder calls connect() or any function that
+ // Entire post data has been received. Now start the request.
+ mConnection.connect();
+ }
+ }
+
+ @Override
mef 2015/03/10 16:48:22 nit: Add comment that these methods are implementa
xunjieli 2015/03/12 21:55:09 Done.
+ public long getLength() {
+ // This method is supposed to be called just before starting the request.
+ // If content length is not initially passed in, the number of bytes
+ // written will be used as the content length.
+ if (mInitialContentLength < 0) {
+ return mBuffer.size();
+ }
+ return mInitialContentLength;
+ }
+
+ @Override
+ public void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer) {
+ int toConsume = Math.min(byteBuffer.remaining(),
+ mBuffer.size() - mBytesConsumed);
+ if (toConsume > 0) {
+ byteBuffer.put(mBuffer.toByteArray(), mBytesConsumed, toConsume);
+ }
+ mBytesConsumed += toConsume;
+ uploadDataSink.onReadSucceeded(false);
+ }
+
+ @Override
+ public void rewind(UploadDataSink uploadDataSink) {
+ mBytesConsumed = 0;
+ uploadDataSink.onRewindSucceeded();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698