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 |