| OLD | NEW |
| 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.impl; |
| 6 | 6 |
| 7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.annotation.TargetApi; | 8 import android.annotation.TargetApi; |
| 9 import android.net.TrafficStats; | 9 import android.net.TrafficStats; |
| 10 import android.os.Build; | 10 import android.os.Build; |
| 11 |
| 11 import android.util.Log; | 12 import android.util.Log; |
| 12 | 13 |
| 14 import org.chromium.net.InlineExecutionProhibitedException; |
| 15 import org.chromium.net.UploadDataProvider; |
| 16 import org.chromium.net.UploadDataSink; |
| 17 import org.chromium.net.UrlRequestException; |
| 18 import org.chromium.net.UrlResponseInfo; |
| 19 |
| 13 import java.io.Closeable; | 20 import java.io.Closeable; |
| 14 import java.io.IOException; | 21 import java.io.IOException; |
| 15 import java.io.OutputStream; | 22 import java.io.OutputStream; |
| 16 import java.net.HttpURLConnection; | 23 import java.net.HttpURLConnection; |
| 17 import java.net.URI; | 24 import java.net.URI; |
| 18 import java.net.URL; | 25 import java.net.URL; |
| 19 import java.nio.ByteBuffer; | 26 import java.nio.ByteBuffer; |
| 20 import java.nio.channels.Channels; | 27 import java.nio.channels.Channels; |
| 21 import java.nio.channels.ReadableByteChannel; | 28 import java.nio.channels.ReadableByteChannel; |
| 22 import java.nio.channels.WritableByteChannel; | 29 import java.nio.channels.WritableByteChannel; |
| 23 import java.util.AbstractMap.SimpleEntry; | 30 import java.util.AbstractMap.SimpleEntry; |
| 24 import java.util.ArrayList; | 31 import java.util.ArrayList; |
| 25 import java.util.Collections; | 32 import java.util.Collections; |
| 26 import java.util.List; | 33 import java.util.List; |
| 27 import java.util.Map; | 34 import java.util.Map; |
| 28 import java.util.TreeMap; | 35 import java.util.TreeMap; |
| 29 import java.util.concurrent.Executor; | 36 import java.util.concurrent.Executor; |
| 30 import java.util.concurrent.RejectedExecutionException; | 37 import java.util.concurrent.RejectedExecutionException; |
| 31 import java.util.concurrent.atomic.AtomicBoolean; | 38 import java.util.concurrent.atomic.AtomicBoolean; |
| 32 import java.util.concurrent.atomic.AtomicReference; | 39 import java.util.concurrent.atomic.AtomicReference; |
| 33 | 40 |
| 34 /** | 41 /** |
| 35 * Pure java UrlRequest, backed by {@link HttpURLConnection}. | 42 * Pure java UrlRequest, backed by {@link HttpURLConnection}. |
| 36 */ | 43 */ |
| 37 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) // TrafficStats only availabl
e on ICS | 44 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) // TrafficStats only availabl
e on ICS |
| 38 final class JavaUrlRequest implements UrlRequest { | 45 final class JavaUrlRequest extends UrlRequestBase { |
| 39 private static final String X_ANDROID = "X-Android"; | 46 private static final String X_ANDROID = "X-Android"; |
| 40 private static final String X_ANDROID_SELECTED_TRANSPORT = "X-Android-Select
ed-Transport"; | 47 private static final String X_ANDROID_SELECTED_TRANSPORT = "X-Android-Select
ed-Transport"; |
| 41 private static final String TAG = "JavaUrlConnection"; | 48 private static final String TAG = "JavaUrlConnection"; |
| 42 private static final int DEFAULT_UPLOAD_BUFFER_SIZE = 8192; | 49 private static final int DEFAULT_UPLOAD_BUFFER_SIZE = 8192; |
| 43 private static final int DEFAULT_CHUNK_LENGTH = DEFAULT_UPLOAD_BUFFER_SIZE; | 50 private static final int DEFAULT_CHUNK_LENGTH = DEFAULT_UPLOAD_BUFFER_SIZE; |
| 44 private static final String USER_AGENT = "User-Agent"; | 51 private static final String USER_AGENT = "User-Agent"; |
| 45 private final AsyncUrlRequestCallback mCallbackAsync; | 52 private final AsyncUrlRequestCallback mCallbackAsync; |
| 46 private final Executor mExecutor; | 53 private final Executor mExecutor; |
| 47 private final String mUserAgent; | 54 private final String mUserAgent; |
| 48 private final Map<String, String> mRequestHeaders = | 55 private final Map<String, String> mRequestHeaders = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 76 /** | 83 /** |
| 77 * Holds a subset of StatusValues - {@link State#STARTED} can represent | 84 * Holds a subset of StatusValues - {@link State#STARTED} can represent |
| 78 * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. Wh
ile the distinction | 85 * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. Wh
ile the distinction |
| 79 * isn't needed to implement the logic in this class, it is needed to implem
ent | 86 * isn't needed to implement the logic in this class, it is needed to implem
ent |
| 80 * {@link #getStatus(StatusListener)}. | 87 * {@link #getStatus(StatusListener)}. |
| 81 * | 88 * |
| 82 * <p>Concurrency notes - this value is not atomically updated with mState,
so there is some | 89 * <p>Concurrency notes - this value is not atomically updated with mState,
so there is some |
| 83 * risk that we'd get an inconsistent snapshot of both - however, it also ha
ppens that this | 90 * risk that we'd get an inconsistent snapshot of both - however, it also ha
ppens that this |
| 84 * value is only used with the STARTED state, so it's inconsequential. | 91 * value is only used with the STARTED state, so it's inconsequential. |
| 85 */ | 92 */ |
| 86 @Status.StatusValues private volatile int mAdditionalStatusDetails = Status.
INVALID; | 93 @StatusValues |
| 94 private volatile int mAdditionalStatusDetails = Status.INVALID; |
| 87 | 95 |
| 88 /* These change with redirects. */ | 96 /* These change with redirects. */ |
| 89 private String mCurrentUrl; | 97 private String mCurrentUrl; |
| 90 private ReadableByteChannel mResponseChannel; | 98 private ReadableByteChannel mResponseChannel; |
| 91 private UrlResponseInfo mUrlResponseInfo; | 99 private UrlResponseInfo mUrlResponseInfo; |
| 92 private String mPendingRedirectUrl; | 100 private String mPendingRedirectUrl; |
| 93 /** | 101 /** |
| 94 * The happens-before edges created by the executor submission and AtomicRef
erence setting are | 102 * The happens-before edges created by the executor submission and AtomicRef
erence setting are |
| 95 * sufficient to guarantee the correct behavior of this field; however, this
is an | 103 * sufficient to guarantee the correct behavior of this field; however, this
is an |
| 96 * AtomicReference so that we can cleanly dispose of a new connection if we'
re cancelled during | 104 * AtomicReference so that we can cleanly dispose of a new connection if we'
re cancelled during |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 } | 257 } |
| 250 } | 258 } |
| 251 | 259 |
| 252 private enum SinkState { | 260 private enum SinkState { |
| 253 AWAITING_READ_RESULT, | 261 AWAITING_READ_RESULT, |
| 254 AWAITING_REWIND_RESULT, | 262 AWAITING_REWIND_RESULT, |
| 255 UPLOADING, | 263 UPLOADING, |
| 256 NOT_STARTED, | 264 NOT_STARTED, |
| 257 } | 265 } |
| 258 | 266 |
| 259 private final class OutputStreamDataSink implements UploadDataSink { | 267 private final class OutputStreamDataSink extends UploadDataSink { |
| 260 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink
State.NOT_STARTED); | 268 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink
State.NOT_STARTED); |
| 261 final Executor mUserUploadExecutor; | 269 final Executor mUserUploadExecutor; |
| 262 final Executor mExecutor; | 270 final Executor mExecutor; |
| 263 final HttpURLConnection mUrlConnection; | 271 final HttpURLConnection mUrlConnection; |
| 264 WritableByteChannel mOutputChannel; | 272 WritableByteChannel mOutputChannel; |
| 265 OutputStream mUrlConnectionOutputStream; | 273 OutputStream mUrlConnectionOutputStream; |
| 266 final UploadDataProvider mUploadProvider; | 274 final UploadDataProvider mUploadProvider; |
| 267 ByteBuffer mBuffer; | 275 ByteBuffer mBuffer; |
| 268 /** This holds the total bytes to send (the content-length). -1 if unkno
wn. */ | 276 /** This holds the total bytes to send (the content-length). -1 if unkno
wn. */ |
| 269 long mTotalBytes; | 277 long mTotalBytes; |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 public boolean isDone() { | 759 public boolean isDone() { |
| 752 State state = mState.get(); | 760 State state = mState.get(); |
| 753 return state == State.COMPLETE | state == State.ERROR | state == State.C
ANCELLED; | 761 return state == State.COMPLETE | state == State.ERROR | state == State.C
ANCELLED; |
| 754 } | 762 } |
| 755 | 763 |
| 756 @Override | 764 @Override |
| 757 public void getStatus(StatusListener listener) { | 765 public void getStatus(StatusListener listener) { |
| 758 State state = mState.get(); | 766 State state = mState.get(); |
| 759 int extraStatus = this.mAdditionalStatusDetails; | 767 int extraStatus = this.mAdditionalStatusDetails; |
| 760 | 768 |
| 761 @Status.StatusValues final int status; | 769 @StatusValues |
| 770 final int status; |
| 762 switch (state) { | 771 switch (state) { |
| 763 case ERROR: | 772 case ERROR: |
| 764 case COMPLETE: | 773 case COMPLETE: |
| 765 case CANCELLED: | 774 case CANCELLED: |
| 766 case NOT_STARTED: | 775 case NOT_STARTED: |
| 767 status = Status.INVALID; | 776 status = Status.INVALID; |
| 768 break; | 777 break; |
| 769 case STARTED: | 778 case STARTED: |
| 770 status = extraStatus; | 779 status = extraStatus; |
| 771 break; | 780 break; |
| 772 case REDIRECT_RECEIVED: | 781 case REDIRECT_RECEIVED: |
| 773 case AWAITING_FOLLOW_REDIRECT: | 782 case AWAITING_FOLLOW_REDIRECT: |
| 774 case AWAITING_READ: | 783 case AWAITING_READ: |
| 775 status = Status.IDLE; | 784 status = Status.IDLE; |
| 776 break; | 785 break; |
| 777 case READING: | 786 case READING: |
| 778 status = Status.READING_RESPONSE; | 787 status = Status.READING_RESPONSE; |
| 779 break; | 788 break; |
| 780 default: | 789 default: |
| 781 throw new IllegalStateException("Switch is exhaustive: " + state
); | 790 throw new IllegalStateException("Switch is exhaustive: " + state
); |
| 782 } | 791 } |
| 783 | 792 |
| 784 mCallbackAsync.sendStatus(listener, status); | 793 mCallbackAsync.sendStatus(listener, status); |
| 785 } | 794 } |
| 786 | 795 |
| 787 /** This wrapper ensures that callbacks are always called on the correct exe
cutor */ | 796 /** This wrapper ensures that callbacks are always called on the correct exe
cutor */ |
| 788 private final class AsyncUrlRequestCallback { | 797 private final class AsyncUrlRequestCallback { |
| 789 final UrlRequest.Callback mCallback; | 798 final Callback mCallback; |
| 790 final Executor mUserExecutor; | 799 final Executor mUserExecutor; |
| 791 final Executor mFallbackExecutor; | 800 final Executor mFallbackExecutor; |
| 792 | 801 |
| 793 AsyncUrlRequestCallback(Callback callback, final Executor userExecutor)
{ | 802 AsyncUrlRequestCallback(Callback callback, final Executor userExecutor)
{ |
| 794 this.mCallback = callback; | 803 this.mCallback = callback; |
| 795 if (mAllowDirectExecutor) { | 804 if (mAllowDirectExecutor) { |
| 796 this.mUserExecutor = userExecutor; | 805 this.mUserExecutor = userExecutor; |
| 797 this.mFallbackExecutor = null; | 806 this.mFallbackExecutor = null; |
| 798 } else { | 807 } else { |
| 799 mUserExecutor = new DirectPreventingExecutor(userExecutor); | 808 mUserExecutor = new DirectPreventingExecutor(userExecutor); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 // Can't throw directly from here, since the delegate execut
or could catch this | 968 // Can't throw directly from here, since the delegate execut
or could catch this |
| 960 // exception. | 969 // exception. |
| 961 mExecutedInline = new InlineExecutionProhibitedException(); | 970 mExecutedInline = new InlineExecutionProhibitedException(); |
| 962 return; | 971 return; |
| 963 } | 972 } |
| 964 mCommand.run(); | 973 mCommand.run(); |
| 965 } | 974 } |
| 966 } | 975 } |
| 967 } | 976 } |
| 968 } | 977 } |
| OLD | NEW |