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 17 matching lines...) Expand all Loading... | |
28 public class UrlRequest { | 28 public class UrlRequest { |
29 private static final class ContextLock { | 29 private static final class ContextLock { |
30 } | 30 } |
31 | 31 |
32 private final UrlRequestContext mRequestContext; | 32 private final UrlRequestContext mRequestContext; |
33 private final String mUrl; | 33 private final String mUrl; |
34 private final int mPriority; | 34 private final int mPriority; |
35 private final Map<String, String> mHeaders; | 35 private final Map<String, String> mHeaders; |
36 private final WritableByteChannel mSink; | 36 private final WritableByteChannel mSink; |
37 private Map<String, String> mAdditionalHeaders; | 37 private Map<String, String> mAdditionalHeaders; |
38 private String mPostBodyContentType; | 38 private String mUploadContentType; |
39 private String mMethod; | 39 private String mMethod; |
40 private byte[] mPostBody; | 40 private byte[] mUploadData; |
41 private ReadableByteChannel mPostBodyChannel; | 41 private ReadableByteChannel mUploadChannel; |
42 private WritableByteChannel mOutputChannel; | 42 private WritableByteChannel mOutputChannel; |
43 private IOException mSinkException; | 43 private IOException mSinkException; |
44 private volatile boolean mStarted; | 44 private volatile boolean mStarted; |
45 private volatile boolean mCanceled; | 45 private volatile boolean mCanceled; |
46 private volatile boolean mRecycled; | 46 private volatile boolean mRecycled; |
47 private volatile boolean mFinished; | 47 private volatile boolean mFinished; |
48 private boolean mHeadersAvailable; | 48 private boolean mHeadersAvailable; |
49 private String mContentType; | 49 private String mContentType; |
50 private long mContentLength; | 50 private long mContentLength; |
51 private long mUploadContentLength; | 51 private long mUploadContentLength; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 * Sets data to upload as part of a POST request. | 100 * Sets data to upload as part of a POST request. |
101 * | 101 * |
102 * @param contentType MIME type of the post content or null if this is not a | 102 * @param contentType MIME type of the post content or null if this is not a |
103 * POST. | 103 * POST. |
104 * @param data The content that needs to be uploaded if this is a POST | 104 * @param data The content that needs to be uploaded if this is a POST |
105 * request. | 105 * request. |
106 */ | 106 */ |
107 public void setUploadData(String contentType, byte[] data) { | 107 public void setUploadData(String contentType, byte[] data) { |
108 synchronized (mLock) { | 108 synchronized (mLock) { |
109 validateNotStarted(); | 109 validateNotStarted(); |
110 mPostBodyContentType = contentType; | 110 mUploadContentType = contentType; |
111 mPostBody = data; | 111 mUploadData = data; |
112 mPostBodyChannel = null; | 112 mUploadChannel = null; |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 /** | 116 /** |
117 * Sets a readable byte channel to upload as part of a POST request. | 117 * Sets a readable byte channel to upload as part of a POST request. |
118 * | 118 * |
119 * @param contentType MIME type of the post content or null if this is not a | 119 * @param contentType MIME type of the post content or null if this is not a |
120 * POST request. | 120 * POST request. |
121 * @param channel The channel to read to read upload data from if this is a | 121 * @param channel The channel to read to read upload data from if this is a |
122 * POST request. | 122 * POST request. |
123 * @param contentLength The length of data to upload. | 123 * @param contentLength The length of data to upload. |
124 */ | 124 */ |
125 public void setUploadChannel(String contentType, | 125 public void setUploadChannel(String contentType, |
126 ReadableByteChannel channel, long contentLength) { | 126 ReadableByteChannel channel, long contentLength) { |
127 synchronized (mLock) { | 127 synchronized (mLock) { |
128 validateNotStarted(); | 128 validateNotStarted(); |
129 mPostBodyContentType = contentType; | 129 mUploadContentType = contentType; |
130 mPostBodyChannel = channel; | 130 mUploadChannel = channel; |
131 mUploadContentLength = contentLength; | 131 mUploadContentLength = contentLength; |
132 mPostBody = null; | 132 mUploadData = null; |
133 } | 133 } |
134 } | 134 } |
135 | 135 |
136 public void setHttpMethod(String method) { | 136 public void setHttpMethod(String method) { |
137 validateNotStarted(); | 137 validateNotStarted(); |
138 if (!("PUT".equals(method) || "POST".equals(method))) { | 138 if (!("PUT".equals(method) || "POST".equals(method))) { |
139 throw new IllegalArgumentException("Only PUT and POST are allowed.") ; | 139 throw new IllegalArgumentException("Only PUT and POST are allowed.") ; |
140 } | 140 } |
141 mMethod = method; | 141 mMethod = method; |
142 } | 142 } |
143 | 143 |
144 public WritableByteChannel getSink() { | 144 public WritableByteChannel getSink() { |
145 return mSink; | 145 return mSink; |
146 } | 146 } |
147 | 147 |
148 public void start() { | 148 public void start() { |
149 synchronized (mLock) { | 149 synchronized (mLock) { |
150 if (mCanceled) { | 150 if (mCanceled) { |
151 return; | 151 return; |
152 } | 152 } |
153 | 153 |
154 validateNotStarted(); | 154 validateNotStarted(); |
155 validateNotRecycled(); | 155 validateNotRecycled(); |
156 | 156 |
157 mStarted = true; | 157 mStarted = true; |
158 | 158 |
159 String method = mMethod; | 159 String method = mMethod; |
160 if (method == null && | 160 if (method == null && |
161 ((mPostBody != null && mPostBody.length > 0) || | 161 ((mUploadData != null && mUploadData.length > 0) || |
162 mPostBodyChannel != null)) { | 162 mUploadChannel != null)) { |
163 // Default to POST if there is data to upload but no method was | 163 // Default to POST if there is data to upload but no method was |
164 // specified. | 164 // specified. |
165 method = "POST"; | 165 method = "POST"; |
166 } | 166 } |
167 | 167 |
168 if (method != null) { | 168 if (method != null) { |
169 nativeSetMethod(mUrlRequestPeer, method); | 169 nativeSetMethod(mUrlRequestPeer, method); |
170 } | 170 } |
171 | 171 |
172 if (mHeaders != null && !mHeaders.isEmpty()) { | 172 if (mHeaders != null && !mHeaders.isEmpty()) { |
173 for (Entry<String, String> entry : mHeaders.entrySet()) { | 173 for (Entry<String, String> entry : mHeaders.entrySet()) { |
174 nativeAddHeader(mUrlRequestPeer, entry.getKey(), | 174 nativeAddHeader(mUrlRequestPeer, entry.getKey(), |
175 entry.getValue()); | 175 entry.getValue()); |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 if (mAdditionalHeaders != null) { | 179 if (mAdditionalHeaders != null) { |
180 for (Entry<String, String> entry : | 180 for (Entry<String, String> entry : |
181 mAdditionalHeaders.entrySet()) { | 181 mAdditionalHeaders.entrySet()) { |
182 nativeAddHeader(mUrlRequestPeer, entry.getKey(), | 182 nativeAddHeader(mUrlRequestPeer, entry.getKey(), |
183 entry.getValue()); | 183 entry.getValue()); |
184 } | 184 } |
185 } | 185 } |
186 | 186 |
187 if (mPostBody != null && mPostBody.length > 0) { | 187 if (mUploadData != null && mUploadData.length > 0) { |
188 nativeSetUploadData(mUrlRequestPeer, mPostBodyContentType, | 188 nativeSetUploadData(mUrlRequestPeer, mUploadContentType, |
189 mPostBody); | 189 mUploadData); |
190 } else if (mPostBodyChannel != null) { | 190 } else if (mUploadChannel != null) { |
191 nativeSetUploadChannel(mUrlRequestPeer, mPostBodyContentType, | 191 nativeSetUploadChannel(mUrlRequestPeer, mUploadContentType, |
192 mPostBodyChannel, mUploadContentLength); | 192 mUploadContentLength); |
193 } | 193 } |
194 | 194 |
195 nativeStart(mUrlRequestPeer); | 195 nativeStart(mUrlRequestPeer); |
196 } | 196 } |
197 } | 197 } |
198 | 198 |
199 public void cancel() { | 199 public void cancel() { |
200 synchronized (mLock) { | 200 synchronized (mLock) { |
201 if (mCanceled) { | 201 if (mCanceled) { |
202 return; | 202 return; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
351 @SuppressWarnings("unused") | 351 @SuppressWarnings("unused") |
352 @CalledByNative | 352 @CalledByNative |
353 private void onAppendResponseHeader(ResponseHeadersMap headersMap, | 353 private void onAppendResponseHeader(ResponseHeadersMap headersMap, |
354 String name, String value) { | 354 String name, String value) { |
355 if (!headersMap.containsKey(name)) { | 355 if (!headersMap.containsKey(name)) { |
356 headersMap.put(name, new ArrayList<String>()); | 356 headersMap.put(name, new ArrayList<String>()); |
357 } | 357 } |
358 headersMap.get(name).add(value); | 358 headersMap.get(name).add(value); |
359 } | 359 } |
360 | 360 |
361 /** | |
362 * Reads data from |mUploadChannel| into |dst|. Returns -1 and closes | |
363 * the channel on error. | |
mmenke
2014/08/05 21:08:02
Should we be using javadoc comments? @param, @ret
mef
2014/08/05 21:38:45
Done.
| |
364 */ | |
365 @SuppressWarnings("unused") | |
366 @CalledByNative | |
367 private int readFromUploadChannel(ByteBuffer dst) { | |
mmenke
2014/08/05 21:08:02
nit: Suggest dest instead of dst. It's a bit mor
mef
2014/08/05 21:38:45
Done.
| |
368 if (mUploadChannel == null || !mUploadChannel.isOpen()) | |
369 return -1; | |
370 try { | |
371 int result = mUploadChannel.read(dst); | |
372 if (result < 0) { | |
373 mUploadChannel.close(); | |
374 return 0; | |
mmenke
2014/08/05 21:08:02
Hrm...think this is actually a fail case, too. We
mef
2014/08/05 21:38:45
Yeah, in my testing current implementation doesn't
mmenke
2014/08/06 14:33:27
Yea, the issue is just if we get the wrong length.
| |
375 } | |
376 return result; | |
377 } catch (IOException e) { | |
378 mSinkException = e; | |
379 try { | |
380 mUploadChannel.close(); | |
381 } catch (IOException ignored) { | |
382 // Ignore this exception. | |
383 } | |
384 cancel(); | |
385 return -1; | |
386 } | |
387 } | |
388 | |
361 private void validateNotRecycled() { | 389 private void validateNotRecycled() { |
362 if (mRecycled) { | 390 if (mRecycled) { |
363 throw new IllegalStateException("Accessing recycled request"); | 391 throw new IllegalStateException("Accessing recycled request"); |
364 } | 392 } |
365 } | 393 } |
366 | 394 |
367 private void validateNotStarted() { | 395 private void validateNotStarted() { |
368 if (mStarted) { | 396 if (mStarted) { |
369 throw new IllegalStateException("Request already started"); | 397 throw new IllegalStateException("Request already started"); |
370 } | 398 } |
(...skipping 14 matching lines...) Expand all Loading... | |
385 | 413 |
386 private native void nativeAddHeader(long urlRequestPeer, String name, | 414 private native void nativeAddHeader(long urlRequestPeer, String name, |
387 String value); | 415 String value); |
388 | 416 |
389 private native void nativeSetMethod(long urlRequestPeer, String method); | 417 private native void nativeSetMethod(long urlRequestPeer, String method); |
390 | 418 |
391 private native void nativeSetUploadData(long urlRequestPeer, | 419 private native void nativeSetUploadData(long urlRequestPeer, |
392 String contentType, byte[] content); | 420 String contentType, byte[] content); |
393 | 421 |
394 private native void nativeSetUploadChannel(long urlRequestPeer, | 422 private native void nativeSetUploadChannel(long urlRequestPeer, |
395 String contentType, ReadableByteChannel content, | 423 String contentType, long contentLength); |
396 long contentLength); | |
397 | 424 |
398 private native void nativeStart(long urlRequestPeer); | 425 private native void nativeStart(long urlRequestPeer); |
399 | 426 |
400 private native void nativeCancel(long urlRequestPeer); | 427 private native void nativeCancel(long urlRequestPeer); |
401 | 428 |
402 private native void nativeDestroyRequestPeer(long urlRequestPeer); | 429 private native void nativeDestroyRequestPeer(long urlRequestPeer); |
403 | 430 |
404 private native int nativeGetErrorCode(long urlRequestPeer); | 431 private native int nativeGetErrorCode(long urlRequestPeer); |
405 | 432 |
406 private native int nativeGetHttpStatusCode(long urlRequestPeer); | 433 private native int nativeGetHttpStatusCode(long urlRequestPeer); |
407 | 434 |
408 private native String nativeGetErrorString(long urlRequestPeer); | 435 private native String nativeGetErrorString(long urlRequestPeer); |
409 | 436 |
410 private native String nativeGetContentType(long urlRequestPeer); | 437 private native String nativeGetContentType(long urlRequestPeer); |
411 | 438 |
412 private native long nativeGetContentLength(long urlRequestPeer); | 439 private native long nativeGetContentLength(long urlRequestPeer); |
413 | 440 |
414 private native String nativeGetHeader(long urlRequestPeer, String name); | 441 private native String nativeGetHeader(long urlRequestPeer, String name); |
415 | 442 |
416 private native void nativeGetAllHeaders(long urlRequestPeer, | 443 private native void nativeGetAllHeaders(long urlRequestPeer, |
417 ResponseHeadersMap headers); | 444 ResponseHeadersMap headers); |
418 | 445 |
419 // Explicit class to work around JNI-generator generics confusion. | 446 // Explicit class to work around JNI-generator generics confusion. |
420 private class ResponseHeadersMap extends HashMap<String, List<String>> { | 447 private class ResponseHeadersMap extends HashMap<String, List<String>> { |
421 } | 448 } |
422 } | 449 } |
OLD | NEW |