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

Side by Side Diff: components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java

Issue 2356923002: Flush chunks on each upload read (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.net.TrafficStats; 8 import android.net.TrafficStats;
9 import android.os.Build; 9 import android.os.Build;
10 import android.util.Log; 10 import android.util.Log;
11 11
12 import java.io.Closeable; 12 import java.io.Closeable;
13 import java.io.IOException; 13 import java.io.IOException;
14 import java.io.OutputStream;
14 import java.net.HttpURLConnection; 15 import java.net.HttpURLConnection;
15 import java.net.URI; 16 import java.net.URI;
16 import java.net.URL; 17 import java.net.URL;
17 import java.nio.ByteBuffer; 18 import java.nio.ByteBuffer;
18 import java.nio.channels.Channels; 19 import java.nio.channels.Channels;
19 import java.nio.channels.ReadableByteChannel; 20 import java.nio.channels.ReadableByteChannel;
20 import java.nio.channels.WritableByteChannel; 21 import java.nio.channels.WritableByteChannel;
21 import java.util.AbstractMap.SimpleEntry; 22 import java.util.AbstractMap.SimpleEntry;
22 import java.util.ArrayList; 23 import java.util.ArrayList;
23 import java.util.Collections; 24 import java.util.Collections;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 UPLOADING, 254 UPLOADING,
254 NOT_STARTED, 255 NOT_STARTED,
255 } 256 }
256 257
257 private final class OutputStreamDataSink implements UploadDataSink { 258 private final class OutputStreamDataSink implements UploadDataSink {
258 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink State.NOT_STARTED); 259 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink State.NOT_STARTED);
259 final Executor mUserUploadExecutor; 260 final Executor mUserUploadExecutor;
260 final Executor mExecutor; 261 final Executor mExecutor;
261 final HttpURLConnection mUrlConnection; 262 final HttpURLConnection mUrlConnection;
262 WritableByteChannel mOutputChannel; 263 WritableByteChannel mOutputChannel;
264 OutputStream mUrlConnectionOutputStream;
263 final UploadDataProvider mUploadProvider; 265 final UploadDataProvider mUploadProvider;
264 ByteBuffer mBuffer; 266 ByteBuffer mBuffer;
265 /** This holds the total bytes to send (the content-length). -1 if unkno wn. */ 267 /** This holds the total bytes to send (the content-length). -1 if unkno wn. */
266 long mTotalBytes; 268 long mTotalBytes;
267 /** This holds the bytes written so far */ 269 /** This holds the bytes written so far */
268 long mWrittenBytes = 0; 270 long mWrittenBytes = 0;
269 271
270 OutputStreamDataSink(final Executor userExecutor, Executor executor, 272 OutputStreamDataSink(final Executor userExecutor, Executor executor,
271 HttpURLConnection urlConnection, UploadDataProvider provider) { 273 HttpURLConnection urlConnection, UploadDataProvider provider) {
272 this.mUserUploadExecutor = new Executor() { 274 this.mUserUploadExecutor = new Executor() {
(...skipping 23 matching lines...) Expand all
296 mBuffer.flip(); 298 mBuffer.flip();
297 if (mTotalBytes != -1 && mTotalBytes - mWrittenBytes < mBuff er.remaining()) { 299 if (mTotalBytes != -1 && mTotalBytes - mWrittenBytes < mBuff er.remaining()) {
298 enterUploadErrorState(new IllegalArgumentException(Strin g.format( 300 enterUploadErrorState(new IllegalArgumentException(Strin g.format(
299 "Read upload data length %d exceeds expected len gth %d", 301 "Read upload data length %d exceeds expected len gth %d",
300 mWrittenBytes + mBuffer.remaining(), mTotalBytes ))); 302 mWrittenBytes + mBuffer.remaining(), mTotalBytes )));
301 return; 303 return;
302 } 304 }
303 while (mBuffer.hasRemaining()) { 305 while (mBuffer.hasRemaining()) {
304 mWrittenBytes += mOutputChannel.write(mBuffer); 306 mWrittenBytes += mOutputChannel.write(mBuffer);
305 } 307 }
308 // Forces a chunk to be sent, rather than buffering to the D EFAULT_CHUNK_LENGTH.
309 // This allows clients to trickle-upload bytes as they becom e available without
310 // introducing latency due to buffering.
311 mUrlConnectionOutputStream.flush();
312
306 if (mWrittenBytes < mTotalBytes || (mTotalBytes == -1 && !fi nalChunk)) { 313 if (mWrittenBytes < mTotalBytes || (mTotalBytes == -1 && !fi nalChunk)) {
307 mBuffer.clear(); 314 mBuffer.clear();
308 mSinkState.set(SinkState.AWAITING_READ_RESULT); 315 mSinkState.set(SinkState.AWAITING_READ_RESULT);
309 executeOnUploadExecutor(new CheckedRunnable() { 316 executeOnUploadExecutor(new CheckedRunnable() {
310 @Override 317 @Override
311 public void run() throws Exception { 318 public void run() throws Exception {
312 mUploadProvider.read(OutputStreamDataSink.this, mBuffer); 319 mUploadProvider.read(OutputStreamDataSink.this, mBuffer);
313 } 320 }
314 }); 321 });
315 } else if (mTotalBytes == -1) { 322 } else if (mTotalBytes == -1) {
(...skipping 28 matching lines...) Expand all
344 } 351 }
345 352
346 void startRead() { 353 void startRead() {
347 mExecutor.execute(errorSetting(new CheckedRunnable() { 354 mExecutor.execute(errorSetting(new CheckedRunnable() {
348 @Override 355 @Override
349 public void run() throws Exception { 356 public void run() throws Exception {
350 if (mOutputChannel == null) { 357 if (mOutputChannel == null) {
351 mAdditionalStatusDetails = Status.CONNECTING; 358 mAdditionalStatusDetails = Status.CONNECTING;
352 mUrlConnection.connect(); 359 mUrlConnection.connect();
353 mAdditionalStatusDetails = Status.SENDING_REQUEST; 360 mAdditionalStatusDetails = Status.SENDING_REQUEST;
354 mOutputChannel = Channels.newChannel(mUrlConnection.getO utputStream()); 361 mUrlConnectionOutputStream = mUrlConnection.getOutputStr eam();
362 mOutputChannel = Channels.newChannel(mUrlConnectionOutpu tStream);
355 } 363 }
356 mSinkState.set(SinkState.AWAITING_READ_RESULT); 364 mSinkState.set(SinkState.AWAITING_READ_RESULT);
357 executeOnUploadExecutor(new CheckedRunnable() { 365 executeOnUploadExecutor(new CheckedRunnable() {
358 @Override 366 @Override
359 public void run() throws Exception { 367 public void run() throws Exception {
360 mUploadProvider.read(OutputStreamDataSink.this, mBuf fer); 368 mUploadProvider.read(OutputStreamDataSink.this, mBuf fer);
361 } 369 }
362 }); 370 });
363 } 371 }
364 })); 372 }));
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 // Can't throw directly from here, since the delegate execut or could catch this 957 // Can't throw directly from here, since the delegate execut or could catch this
950 // exception. 958 // exception.
951 mExecutedInline = new InlineExecutionProhibitedException(); 959 mExecutedInline = new InlineExecutionProhibitedException();
952 return; 960 return;
953 } 961 }
954 mCommand.run(); 962 mCommand.run();
955 } 963 }
956 } 964 }
957 } 965 }
958 } 966 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698