| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 org.apache.http.conn.ConnectTimeoutException; | 7 import org.apache.http.conn.ConnectTimeoutException; |
| 8 import org.chromium.base.CalledByNative; | 8 import org.chromium.base.CalledByNative; |
| 9 import org.chromium.base.JNINamespace; | 9 import org.chromium.base.JNINamespace; |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 private final WritableByteChannel mSink; | 37 private final WritableByteChannel mSink; |
| 38 private Map<String, String> mAdditionalHeaders; | 38 private Map<String, String> mAdditionalHeaders; |
| 39 private boolean mPostBodySet; | 39 private boolean mPostBodySet; |
| 40 private ReadableByteChannel mPostBodyChannel; | 40 private ReadableByteChannel mPostBodyChannel; |
| 41 private WritableByteChannel mOutputChannel; | 41 private WritableByteChannel mOutputChannel; |
| 42 private IOException mSinkException; | 42 private IOException mSinkException; |
| 43 private volatile boolean mStarted; | 43 private volatile boolean mStarted; |
| 44 private volatile boolean mCanceled; | 44 private volatile boolean mCanceled; |
| 45 private volatile boolean mRecycled; | 45 private volatile boolean mRecycled; |
| 46 private volatile boolean mFinished; | 46 private volatile boolean mFinished; |
| 47 private boolean mHeadersAvailable; |
| 47 private String mContentType; | 48 private String mContentType; |
| 48 private long mContentLength; | 49 private long mContentLength; |
| 49 private Semaphore mAppendChunkSemaphore; | 50 private Semaphore mAppendChunkSemaphore; |
| 50 private final ContextLock mLock; | 51 private final ContextLock mLock; |
| 51 | 52 |
| 52 /** | 53 /** |
| 53 * Native peer object, owned by UrlRequest. | 54 * Native peer object, owned by UrlRequest. |
| 54 */ | 55 */ |
| 55 private long mUrlRequestPeer; | 56 private long mUrlRequestPeer; |
| 56 | 57 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 mPostBodySet = true; | 131 mPostBodySet = true; |
| 131 } | 132 } |
| 132 mAppendChunkSemaphore = new Semaphore(0); | 133 mAppendChunkSemaphore = new Semaphore(0); |
| 133 } | 134 } |
| 134 | 135 |
| 135 public WritableByteChannel getSink() { | 136 public WritableByteChannel getSink() { |
| 136 return mSink; | 137 return mSink; |
| 137 } | 138 } |
| 138 | 139 |
| 139 public void start() { | 140 public void start() { |
| 140 synchronized (mLock) { | 141 try { |
| 141 if (mCanceled) { | 142 synchronized (mLock) { |
| 142 return; | 143 if (mCanceled) { |
| 144 return; |
| 145 } |
| 146 |
| 147 validateNotStarted(); |
| 148 validateNotRecycled(); |
| 149 |
| 150 mStarted = true; |
| 151 |
| 152 if (mHeaders != null && !mHeaders.isEmpty()) { |
| 153 for (Entry<String, String> entry : mHeaders.entrySet()) { |
| 154 nativeAddHeader(mUrlRequestPeer, entry.getKey(), |
| 155 entry.getValue()); |
| 156 } |
| 157 } |
| 158 |
| 159 if (mAdditionalHeaders != null && !mAdditionalHeaders.isEmpty())
{ |
| 160 for (Entry<String, String> entry : |
| 161 mAdditionalHeaders.entrySet()) { |
| 162 nativeAddHeader(mUrlRequestPeer, entry.getKey(), |
| 163 entry.getValue()); |
| 164 } |
| 165 } |
| 166 |
| 167 nativeStart(mUrlRequestPeer); |
| 143 } | 168 } |
| 144 | 169 |
| 145 validateNotStarted(); | 170 if (mPostBodyChannel != null) { |
| 146 validateNotRecycled(); | 171 uploadFromChannel(mPostBodyChannel); |
| 147 | 172 } |
| 148 mStarted = true; | 173 } finally { |
| 149 | 174 if (mPostBodyChannel != null) { |
| 150 if (mHeaders != null && !mHeaders.isEmpty()) { | 175 try { |
| 151 for (Entry<String, String> entry : mHeaders.entrySet()) { | 176 mPostBodyChannel.close(); |
| 152 nativeAddHeader(mUrlRequestPeer, entry.getKey(), | 177 } catch (IOException e) { |
| 153 entry.getValue()); | 178 // Ignore |
| 154 } | 179 } |
| 155 } | 180 } |
| 156 | |
| 157 if (mAdditionalHeaders != null && !mAdditionalHeaders.isEmpty()) { | |
| 158 for (Entry<String, String> entry : | |
| 159 mAdditionalHeaders.entrySet()) { | |
| 160 nativeAddHeader(mUrlRequestPeer, entry.getKey(), | |
| 161 entry.getValue()); | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 nativeStart(mUrlRequestPeer); | |
| 166 } | |
| 167 | |
| 168 if (mPostBodyChannel != null) { | |
| 169 uploadFromChannel(mPostBodyChannel); | |
| 170 } | 181 } |
| 171 } | 182 } |
| 172 | 183 |
| 173 /** | 184 /** |
| 174 * Uploads data from a {@code ReadableByteChannel} using chunked transfer | 185 * Uploads data from a {@code ReadableByteChannel} using chunked transfer |
| 175 * encoding. The native call to append a chunk is asynchronous so a | 186 * encoding. The native call to append a chunk is asynchronous so a |
| 176 * semaphore is used to delay writing into the buffer again until chromium | 187 * semaphore is used to delay writing into the buffer again until chromium |
| 177 * is finished with it. | 188 * is finished with it. |
| 178 * | 189 * |
| 179 * @param channel the channel to read data from. | 190 * @param channel the channel to read data from. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 210 // Acquire permit before writing to the buffer again to ensure | 221 // Acquire permit before writing to the buffer again to ensure |
| 211 // chromium is done with it. | 222 // chromium is done with it. |
| 212 mAppendChunkSemaphore.acquire(); | 223 mAppendChunkSemaphore.acquire(); |
| 213 } while (!lastChunk && !mFinished); | 224 } while (!lastChunk && !mFinished); |
| 214 } catch (IOException e) { | 225 } catch (IOException e) { |
| 215 mSinkException = e; | 226 mSinkException = e; |
| 216 cancel(); | 227 cancel(); |
| 217 } catch (InterruptedException e) { | 228 } catch (InterruptedException e) { |
| 218 mSinkException = new IOException(e); | 229 mSinkException = new IOException(e); |
| 219 cancel(); | 230 cancel(); |
| 220 } finally { | |
| 221 try { | |
| 222 mPostBodyChannel.close(); | |
| 223 } catch (IOException ignore) { | |
| 224 ; | |
| 225 } | |
| 226 } | 231 } |
| 227 } | 232 } |
| 228 | 233 |
| 229 public void cancel() { | 234 public void cancel() { |
| 230 synchronized (mLock) { | 235 synchronized (mLock) { |
| 231 if (mCanceled) { | 236 if (mCanceled) { |
| 232 return; | 237 return; |
| 233 } | 238 } |
| 234 | 239 |
| 235 mCanceled = true; | 240 mCanceled = true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 * server returns the wrong number, which happens even with Google servers. | 301 * server returns the wrong number, which happens even with Google servers. |
| 297 */ | 302 */ |
| 298 public long getContentLength() { | 303 public long getContentLength() { |
| 299 return mContentLength; | 304 return mContentLength; |
| 300 } | 305 } |
| 301 | 306 |
| 302 public String getContentType() { | 307 public String getContentType() { |
| 303 return mContentType; | 308 return mContentType; |
| 304 } | 309 } |
| 305 | 310 |
| 311 public String getHeader(String name) { |
| 312 validateHeadersAvailable(); |
| 313 return nativeGetHeader(mUrlRequestPeer, name); |
| 314 } |
| 315 |
| 306 /** | 316 /** |
| 307 * A callback invoked when appending a chunk to the request has completed. | 317 * A callback invoked when appending a chunk to the request has completed. |
| 308 */ | 318 */ |
| 309 @CalledByNative | 319 @CalledByNative |
| 310 protected void onAppendChunkCompleted() { | 320 protected void onAppendChunkCompleted() { |
| 311 mAppendChunkSemaphore.release(); | 321 mAppendChunkSemaphore.release(); |
| 312 } | 322 } |
| 313 | 323 |
| 314 /** | 324 /** |
| 315 * A callback invoked when the first chunk of the response has arrived. | 325 * A callback invoked when the first chunk of the response has arrived. |
| 316 */ | 326 */ |
| 317 @CalledByNative | 327 @CalledByNative |
| 318 protected void onResponseStarted() { | 328 protected void onResponseStarted() { |
| 319 mContentType = nativeGetContentType(mUrlRequestPeer); | 329 mContentType = nativeGetContentType(mUrlRequestPeer); |
| 320 mContentLength = nativeGetContentLength(mUrlRequestPeer); | 330 mContentLength = nativeGetContentLength(mUrlRequestPeer); |
| 331 mHeadersAvailable = true; |
| 321 } | 332 } |
| 322 | 333 |
| 323 /** | 334 /** |
| 324 * A callback invoked when the response has been fully consumed. | 335 * A callback invoked when the response has been fully consumed. |
| 325 */ | 336 */ |
| 326 protected void onRequestComplete() { | 337 protected void onRequestComplete() { |
| 327 } | 338 } |
| 328 | 339 |
| 329 /** | 340 /** |
| 330 * Consumes a portion of the response. | 341 * Consumes a portion of the response. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 throw new IllegalStateException("Request already started"); | 394 throw new IllegalStateException("Request already started"); |
| 384 } | 395 } |
| 385 } | 396 } |
| 386 | 397 |
| 387 private void validatePostBodyNotSet() { | 398 private void validatePostBodyNotSet() { |
| 388 if (mPostBodySet) { | 399 if (mPostBodySet) { |
| 389 throw new IllegalStateException("Post Body already set"); | 400 throw new IllegalStateException("Post Body already set"); |
| 390 } | 401 } |
| 391 } | 402 } |
| 392 | 403 |
| 404 |
| 405 private void validateHeadersAvailable() { |
| 406 if (!mHeadersAvailable) { |
| 407 throw new IllegalStateException("Response headers not available"); |
| 408 } |
| 409 } |
| 410 |
| 393 public String getUrl() { | 411 public String getUrl() { |
| 394 return mUrl; | 412 return mUrl; |
| 395 } | 413 } |
| 396 | 414 |
| 397 private native long nativeCreateRequestPeer(long urlRequestContextPeer, | 415 private native long nativeCreateRequestPeer(long urlRequestContextPeer, |
| 398 String url, int priority); | 416 String url, int priority); |
| 399 | 417 |
| 400 private native void nativeAddHeader(long urlRequestPeer, String name, | 418 private native void nativeAddHeader(long urlRequestPeer, String name, |
| 401 String value); | 419 String value); |
| 402 | 420 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 417 | 435 |
| 418 private native int nativeGetErrorCode(long urlRequestPeer); | 436 private native int nativeGetErrorCode(long urlRequestPeer); |
| 419 | 437 |
| 420 private native int nativeGetHttpStatusCode(long urlRequestPeer); | 438 private native int nativeGetHttpStatusCode(long urlRequestPeer); |
| 421 | 439 |
| 422 private native String nativeGetErrorString(long urlRequestPeer); | 440 private native String nativeGetErrorString(long urlRequestPeer); |
| 423 | 441 |
| 424 private native String nativeGetContentType(long urlRequestPeer); | 442 private native String nativeGetContentType(long urlRequestPeer); |
| 425 | 443 |
| 426 private native long nativeGetContentLength(long urlRequestPeer); | 444 private native long nativeGetContentLength(long urlRequestPeer); |
| 445 |
| 446 private native String nativeGetHeader(long urlRequestPeer, String name); |
| 427 } | 447 } |
| OLD | NEW |