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

Side by Side 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: Address Paul's and Misha's comments 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.net.urlconnection;
6
7 import org.chromium.net.UploadDataProvider;
8 import org.chromium.net.UploadDataSink;
9
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.io.OutputStream;
13 import java.net.ProtocolException;
14 import java.nio.ByteBuffer;
15
16 /**
17 * An implementation of {@link java.io.OutputStream} that buffers entire request
18 * body in memory. This is used when neither
19 * {@link CronetHttpURLConnection#setFixedLengthStreamingMode}
20 * or {@link CronetHttpURLConnection#setChunkedStreamingMode} is set.
21 */
22 final class CronetBufferedOutputStream extends OutputStream
23 implements UploadDataProvider {
24 // If content length is not passed in the constructor, this is -1.
25 private final int mInitialContentLength;
26 private final CronetHttpURLConnection mConnection;
27 // Internal buffer that is used to buffer the request body.
28 private final ByteArrayOutputStream mBuffer;
29 // Number of bytes consumed by the native UploadDataStream.
30 private int mBytesConsumed;
31
32 /**
33 * Package protected constructor.
34 * @param connection The CronetHttpURLConnection object.
35 * @param contentLength The content length of the request body. It must not
36 * be smaller than 0 or bigger than {@link Integer.MAX_VALUE}.
37 */
38 CronetBufferedOutputStream(final CronetHttpURLConnection connection,
39 final long contentLength) {
40 if (connection == null) {
41 throw new NullPointerException();
42 }
43
44 if (contentLength > Integer.MAX_VALUE) {
45 throw new IllegalStateException("Use setFixedLengthStreamingMode()"
46 + " or setChunkedStreamingMode() for requests larger than 2GB.") ;
47 }
48 if (contentLength < 0) {
49 throw new IllegalArgumentException("Content length < 0.");
50 }
51 mConnection = connection;
52 mInitialContentLength = (int) contentLength;
53 mBuffer = new ByteArrayOutputStream(mInitialContentLength);
54 mBytesConsumed = 0;
55 }
56
57 /**
58 * Package protected constructor used when content length is not known.
59 * @param connection The CronetHttpURLConnection object.
60 */
61 CronetBufferedOutputStream(final CronetHttpURLConnection connection) {
62 if (connection == null) {
63 throw new NullPointerException();
64 }
65
66 mConnection = connection;
67 mInitialContentLength = -1;
68 // Bufferring without knowing content-length.
69 mBuffer = new ByteArrayOutputStream();
70 mBytesConsumed = 0;
71 }
72
73 @Override
74 public void write(int oneByte) throws IOException {
75 checkNotExceedContentLength(1);
76 mBuffer.write((byte) oneByte);
77 if (mBuffer.size() == mInitialContentLength) {
78 // Entire post data has been received. Now start the request.
79 mConnection.connect();
80 }
81 }
82
83 @Override
84 public void write(byte[] buffer, int offset, int count) throws IOException {
85 checkNotExceedContentLength(count);
86 mBuffer.write(buffer, offset, count);
87 if (mBuffer.size() == mInitialContentLength) {
88 // Entire post data has been received. Now start the request.
89 mConnection.connect();
90 }
91 }
92
93 /**
94 * Throws {@link java.net.ProtocolException} if adding {@code numBytes} will
95 * exceed content length.
96 */
97 private void checkNotExceedContentLength(int numBytes) throws ProtocolExcept ion {
98 if (mInitialContentLength != -1
99 && mBuffer.size() + numBytes > mInitialContentLength) {
100 throw new ProtocolException("exceeded content-length limit of "
101 + mInitialContentLength + " bytes");
102 }
103 }
104
105 // Below are UploadDataProvider implementations. Only intended to be used
106 // within Cronet.
107
108 @Override
109 public long getLength() {
110 // This method is supposed to be called just before starting the request .
111 // If content length is not initially passed in, the number of bytes
112 // written will be used as the content length.
113 if (mInitialContentLength == -1) {
114 return mBuffer.size();
mmenke 2015/03/13 14:51:11 Wait...we're requiring the entire body be passed i
xunjieli 2015/03/13 19:26:40 Yes, we require the entire body to be passed to us
mmenke 2015/03/25 18:34:57 So when uploading data, calling connect() breaks t
115 }
116 return mInitialContentLength;
117 }
118
119 @Override
120 public void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer) {
121 int toConsume = Math.min(byteBuffer.remaining(),
122 mBuffer.size() - mBytesConsumed);
123 if (toConsume > 0) {
124 byteBuffer.put(mBuffer.toByteArray(), mBytesConsumed, toConsume);
125 }
126 mBytesConsumed += toConsume;
127 uploadDataSink.onReadSucceeded(false);
128 }
129
130 @Override
131 public void rewind(UploadDataSink uploadDataSink) {
132 mBytesConsumed = 0;
133 uploadDataSink.onRewindSucceeded();
134 }
135 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698