| 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.impl; |
| 6 | 6 |
| 7 import android.util.Log; | 7 import android.util.Log; |
| 8 | 8 |
| 9 import org.chromium.base.annotations.CalledByNative; | 9 import org.chromium.base.annotations.CalledByNative; |
| 10 import org.chromium.base.annotations.JNINamespace; | 10 import org.chromium.base.annotations.JNINamespace; |
| 11 import org.chromium.base.annotations.SuppressFBWarnings; | 11 import org.chromium.base.annotations.SuppressFBWarnings; |
| 12 import org.chromium.net.ChromiumUrlRequestError; |
| 13 import org.chromium.net.ChromiumUrlRequestPriority; |
| 14 import org.chromium.net.ChunkedWritableByteChannel; |
| 15 import org.chromium.net.HttpUrlRequest; |
| 16 import org.chromium.net.HttpUrlRequestListener; |
| 17 import org.chromium.net.ResponseTooLargeException; |
| 12 | 18 |
| 13 import java.io.IOException; | 19 import java.io.IOException; |
| 14 import java.net.MalformedURLException; | 20 import java.net.MalformedURLException; |
| 15 import java.net.SocketTimeoutException; | 21 import java.net.SocketTimeoutException; |
| 16 import java.net.URL; | 22 import java.net.URL; |
| 17 import java.net.UnknownHostException; | 23 import java.net.UnknownHostException; |
| 18 import java.nio.ByteBuffer; | 24 import java.nio.ByteBuffer; |
| 19 import java.nio.channels.ReadableByteChannel; | 25 import java.nio.channels.ReadableByteChannel; |
| 20 import java.nio.channels.WritableByteChannel; | 26 import java.nio.channels.WritableByteChannel; |
| 21 import java.util.ArrayList; | 27 import java.util.ArrayList; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 84 |
| 79 // Native error code. Default to no error. Populated in onRequestComplete(). | 85 // Native error code. Default to no error. Populated in onRequestComplete(). |
| 80 private int mErrorCode = ChromiumUrlRequestError.SUCCESS; | 86 private int mErrorCode = ChromiumUrlRequestError.SUCCESS; |
| 81 | 87 |
| 82 // Native error string. Default to null. Populated in onRequestComplete(). | 88 // Native error string. Default to null. Populated in onRequestComplete(). |
| 83 private String mErrorString; | 89 private String mErrorString; |
| 84 | 90 |
| 85 // Protects access of mUrlRequestAdapter, mStarted, mCanceled, and mFinished
. | 91 // Protects access of mUrlRequestAdapter, mStarted, mCanceled, and mFinished
. |
| 86 private final Object mLock = new Object(); | 92 private final Object mLock = new Object(); |
| 87 | 93 |
| 88 public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, | 94 public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, String u
rl, int priority, |
| 89 String url, int priority, Map<String, String> headers, | 95 Map<String, String> headers, HttpUrlRequestListener listener) { |
| 90 HttpUrlRequestListener listener) { | 96 this(requestContext, url, priority, headers, new ChunkedWritableByteChan
nel(), listener); |
| 91 this(requestContext, url, priority, headers, | |
| 92 new ChunkedWritableByteChannel(), listener); | |
| 93 mBufferFullResponse = true; | 97 mBufferFullResponse = true; |
| 94 } | 98 } |
| 95 | 99 |
| 96 /** | 100 /** |
| 97 * Constructor. | 101 * Constructor. |
| 98 * | 102 * |
| 99 * @param requestContext The context. | 103 * @param requestContext The context. |
| 100 * @param url The URL. | 104 * @param url The URL. |
| 101 * @param priority Request priority, e.g. {@link #REQUEST_PRIORITY_MEDIUM}. | 105 * @param priority Request priority, e.g. {@link #REQUEST_PRIORITY_MEDIUM}. |
| 102 * @param headers HTTP headers. | 106 * @param headers HTTP headers. |
| 103 * @param sink The output channel into which downloaded content will be | 107 * @param sink The output channel into which downloaded content will be |
| 104 * written. | 108 * written. |
| 105 */ | 109 */ |
| 106 public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, | 110 public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, String u
rl, int priority, |
| 107 String url, int priority, Map<String, String> headers, | 111 Map<String, String> headers, WritableByteChannel sink, |
| 108 WritableByteChannel sink, HttpUrlRequestListener listener) { | 112 HttpUrlRequestListener listener) { |
| 109 if (requestContext == null) { | 113 if (requestContext == null) { |
| 110 throw new NullPointerException("Context is required"); | 114 throw new NullPointerException("Context is required"); |
| 111 } | 115 } |
| 112 if (url == null) { | 116 if (url == null) { |
| 113 throw new NullPointerException("URL is required"); | 117 throw new NullPointerException("URL is required"); |
| 114 } | 118 } |
| 115 mRequestContext = requestContext; | 119 mRequestContext = requestContext; |
| 116 mUrl = url; | 120 mUrl = url; |
| 117 mPriority = convertRequestPriority(priority); | 121 mPriority = convertRequestPriority(priority); |
| 118 mHeaders = headers; | 122 mHeaders = headers; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 try { | 196 try { |
| 193 host = new URL(mUrl).getHost(); | 197 host = new URL(mUrl).getHost(); |
| 194 } catch (MalformedURLException e) { | 198 } catch (MalformedURLException e) { |
| 195 host = mUrl; | 199 host = mUrl; |
| 196 } | 200 } |
| 197 return new UnknownHostException("Unknown host: " + host); | 201 return new UnknownHostException("Unknown host: " + host); |
| 198 case ChromiumUrlRequestError.TOO_MANY_REDIRECTS: | 202 case ChromiumUrlRequestError.TOO_MANY_REDIRECTS: |
| 199 return new IOException("Request failed because there were too " | 203 return new IOException("Request failed because there were too " |
| 200 + "many redirects or redirects have been disabled"); | 204 + "many redirects or redirects have been disabled"); |
| 201 default: | 205 default: |
| 202 throw new IllegalStateException( | 206 throw new IllegalStateException("Unrecognized error code: " + mE
rrorCode); |
| 203 "Unrecognized error code: " + mErrorCode); | |
| 204 } | 207 } |
| 205 } | 208 } |
| 206 | 209 |
| 207 @Override | 210 @Override |
| 208 public ByteBuffer getByteBuffer() { | 211 public ByteBuffer getByteBuffer() { |
| 209 return ((ChunkedWritableByteChannel) getSink()).getByteBuffer(); | 212 return ((ChunkedWritableByteChannel) getSink()).getByteBuffer(); |
| 210 } | 213 } |
| 211 | 214 |
| 212 @Override | 215 @Override |
| 213 public byte[] getResponseAsBytes() { | 216 public byte[] getResponseAsBytes() { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 /** | 253 /** |
| 251 * Sets a readable byte channel to upload as part of a POST or PUT request. | 254 * Sets a readable byte channel to upload as part of a POST or PUT request. |
| 252 * | 255 * |
| 253 * @param contentType MIME type of the upload content or null if this is not | 256 * @param contentType MIME type of the upload content or null if this is not |
| 254 * an upload request. | 257 * an upload request. |
| 255 * @param channel The channel to read to read upload data from if this is an | 258 * @param channel The channel to read to read upload data from if this is an |
| 256 * upload request. | 259 * upload request. |
| 257 * @param contentLength The length of data to upload. | 260 * @param contentLength The length of data to upload. |
| 258 */ | 261 */ |
| 259 @Override | 262 @Override |
| 260 public void setUploadChannel(String contentType, | 263 public void setUploadChannel( |
| 261 ReadableByteChannel channel, long contentLength) { | 264 String contentType, ReadableByteChannel channel, long contentLength)
{ |
| 262 synchronized (mLock) { | 265 synchronized (mLock) { |
| 263 validateNotStarted(); | 266 validateNotStarted(); |
| 264 validateContentType(contentType); | 267 validateContentType(contentType); |
| 265 mUploadContentType = contentType; | 268 mUploadContentType = contentType; |
| 266 mUploadChannel = channel; | 269 mUploadChannel = channel; |
| 267 mUploadContentLength = contentLength; | 270 mUploadContentLength = contentLength; |
| 268 mUploadData = null; | 271 mUploadData = null; |
| 269 mChunkedUpload = false; | 272 mChunkedUpload = false; |
| 270 } | 273 } |
| 271 } | 274 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 290 | 293 |
| 291 /** | 294 /** |
| 292 * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)} | 295 * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)} |
| 293 * and {@link #start()}. | 296 * and {@link #start()}. |
| 294 * | 297 * |
| 295 * @param chunk The data, which will not be modified. Its current position. | 298 * @param chunk The data, which will not be modified. Its current position. |
| 296 * must be zero. The last chunk can be empty, but all other | 299 * must be zero. The last chunk can be empty, but all other |
| 297 * chunks must be non-empty. | 300 * chunks must be non-empty. |
| 298 * @param isLastChunk Whether this chunk is the last one. | 301 * @param isLastChunk Whether this chunk is the last one. |
| 299 */ | 302 */ |
| 300 public void appendChunk(ByteBuffer chunk, boolean isLastChunk) | 303 public void appendChunk(ByteBuffer chunk, boolean isLastChunk) throws IOExce
ption { |
| 301 throws IOException { | |
| 302 if (!isLastChunk && !chunk.hasRemaining()) { | 304 if (!isLastChunk && !chunk.hasRemaining()) { |
| 303 throw new IllegalArgumentException( | 305 throw new IllegalArgumentException("Attempted to write empty buffer.
"); |
| 304 "Attempted to write empty buffer."); | |
| 305 } | 306 } |
| 306 if (chunk.position() != 0) { | 307 if (chunk.position() != 0) { |
| 307 throw new IllegalArgumentException("The position must be zero."); | 308 throw new IllegalArgumentException("The position must be zero."); |
| 308 } | 309 } |
| 309 synchronized (mLock) { | 310 synchronized (mLock) { |
| 310 if (!mStarted) { | 311 if (!mStarted) { |
| 311 throw new IllegalStateException("Request not yet started."); | 312 throw new IllegalStateException("Request not yet started."); |
| 312 } | 313 } |
| 313 if (!mChunkedUpload) { | 314 if (!mChunkedUpload) { |
| 314 throw new IllegalStateException( | 315 throw new IllegalStateException("Request not set for chunked upl
oadind."); |
| 315 "Request not set for chunked uploadind."); | |
| 316 } | 316 } |
| 317 if (mUrlRequestAdapter == 0) { | 317 if (mUrlRequestAdapter == 0) { |
| 318 throw new IOException("Native peer destroyed."); | 318 throw new IOException("Native peer destroyed."); |
| 319 } | 319 } |
| 320 nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(), | 320 nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(), isLastCh
unk); |
| 321 isLastChunk); | |
| 322 } | 321 } |
| 323 } | 322 } |
| 324 | 323 |
| 325 @Override | 324 @Override |
| 326 public void setHttpMethod(String method) { | 325 public void setHttpMethod(String method) { |
| 327 validateNotStarted(); | 326 validateNotStarted(); |
| 328 mMethod = method; | 327 mMethod = method; |
| 329 } | 328 } |
| 330 | 329 |
| 331 @Override | 330 @Override |
| (...skipping 17 matching lines...) Expand all Loading... |
| 349 return; | 348 return; |
| 350 } | 349 } |
| 351 | 350 |
| 352 validateNotStarted(); | 351 validateNotStarted(); |
| 353 validateNativeAdapterNotDestroyed(); | 352 validateNativeAdapterNotDestroyed(); |
| 354 | 353 |
| 355 mStarted = true; | 354 mStarted = true; |
| 356 | 355 |
| 357 if (mHeaders != null && !mHeaders.isEmpty()) { | 356 if (mHeaders != null && !mHeaders.isEmpty()) { |
| 358 for (Entry<String, String> entry : mHeaders.entrySet()) { | 357 for (Entry<String, String> entry : mHeaders.entrySet()) { |
| 359 nativeAddHeader(mUrlRequestAdapter, entry.getKey(), | 358 nativeAddHeader(mUrlRequestAdapter, entry.getKey(), entry.ge
tValue()); |
| 360 entry.getValue()); | |
| 361 } | 359 } |
| 362 } | 360 } |
| 363 | 361 |
| 364 if (mAdditionalHeaders != null) { | 362 if (mAdditionalHeaders != null) { |
| 365 for (Entry<String, String> entry : | 363 for (Entry<String, String> entry : mAdditionalHeaders.entrySet()
) { |
| 366 mAdditionalHeaders.entrySet()) { | 364 nativeAddHeader(mUrlRequestAdapter, entry.getKey(), entry.ge
tValue()); |
| 367 nativeAddHeader(mUrlRequestAdapter, entry.getKey(), | |
| 368 entry.getValue()); | |
| 369 } | 365 } |
| 370 } | 366 } |
| 371 | 367 |
| 372 if (mUploadData != null && mUploadData.length > 0) { | 368 if (mUploadData != null && mUploadData.length > 0) { |
| 373 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, | 369 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, mUpl
oadData); |
| 374 mUploadData); | |
| 375 } else if (mUploadChannel != null) { | 370 } else if (mUploadChannel != null) { |
| 376 nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType, | 371 nativeSetUploadChannel( |
| 377 mUploadContentLength); | 372 mUrlRequestAdapter, mUploadContentType, mUploadContentLe
ngth); |
| 378 } else if (mChunkedUpload) { | 373 } else if (mChunkedUpload) { |
| 379 nativeEnableChunkedUpload(mUrlRequestAdapter, | 374 nativeEnableChunkedUpload(mUrlRequestAdapter, mUploadContentType
); |
| 380 mUploadContentType); | |
| 381 } | 375 } |
| 382 | 376 |
| 383 // Note: The above functions to set the upload body also set the | 377 // Note: The above functions to set the upload body also set the |
| 384 // method to POST, behind the scenes, so if mMethod is null but | 378 // method to POST, behind the scenes, so if mMethod is null but |
| 385 // there's an upload body, the method will default to POST. | 379 // there's an upload body, the method will default to POST. |
| 386 if (mMethod != null) { | 380 if (mMethod != null) { |
| 387 nativeSetMethod(mUrlRequestAdapter, mMethod); | 381 nativeSetMethod(mUrlRequestAdapter, mMethod); |
| 388 } | 382 } |
| 389 | 383 |
| 390 nativeStart(mUrlRequestAdapter); | 384 nativeStart(mUrlRequestAdapter); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 } | 520 } |
| 527 } | 521 } |
| 528 | 522 |
| 529 // Private methods called by native library. | 523 // Private methods called by native library. |
| 530 | 524 |
| 531 /** | 525 /** |
| 532 * If @CalledByNative method throws an exception, request gets canceled | 526 * If @CalledByNative method throws an exception, request gets canceled |
| 533 * and exception could be retrieved from request using getException(). | 527 * and exception could be retrieved from request using getException(). |
| 534 */ | 528 */ |
| 535 private void onCalledByNativeException(Exception e) { | 529 private void onCalledByNativeException(Exception e) { |
| 536 mSinkException = new IOException( | 530 mSinkException = new IOException("CalledByNative method has thrown an ex
ception", e); |
| 537 "CalledByNative method has thrown an exception", e); | 531 Log.e(ChromiumUrlRequestContext.LOG_TAG, "Exception in CalledByNative me
thod", e); |
| 538 Log.e(ChromiumUrlRequestContext.LOG_TAG, | |
| 539 "Exception in CalledByNative method", e); | |
| 540 try { | 532 try { |
| 541 cancel(); | 533 cancel(); |
| 542 } catch (Exception cancel_exception) { | 534 } catch (Exception cancel_exception) { |
| 543 Log.e(ChromiumUrlRequestContext.LOG_TAG, | 535 Log.e(ChromiumUrlRequestContext.LOG_TAG, "Exception trying to cancel
request", |
| 544 "Exception trying to cancel request", cancel_exception); | 536 cancel_exception); |
| 545 } | 537 } |
| 546 } | 538 } |
| 547 | 539 |
| 548 /** | 540 /** |
| 549 * A callback invoked when the first chunk of the response has arrived. | 541 * A callback invoked when the first chunk of the response has arrived. |
| 550 */ | 542 */ |
| 551 @CalledByNative | 543 @CalledByNative |
| 552 private void onResponseStarted() { | 544 private void onResponseStarted() { |
| 553 try { | 545 try { |
| 554 mHttpStatusCode = nativeGetHttpStatusCode(mUrlRequestAdapter); | 546 mHttpStatusCode = nativeGetHttpStatusCode(mUrlRequestAdapter); |
| 555 mHttpStatusText = nativeGetHttpStatusText(mUrlRequestAdapter); | 547 mHttpStatusText = nativeGetHttpStatusText(mUrlRequestAdapter); |
| 556 mContentType = nativeGetContentType(mUrlRequestAdapter); | 548 mContentType = nativeGetContentType(mUrlRequestAdapter); |
| 557 mContentLength = nativeGetContentLength(mUrlRequestAdapter); | 549 mContentLength = nativeGetContentLength(mUrlRequestAdapter); |
| 558 mHeadersAvailable = true; | 550 mHeadersAvailable = true; |
| 559 | 551 |
| 560 if (mContentLengthLimit > 0 | 552 if (mContentLengthLimit > 0 && mContentLength > mContentLengthLimit |
| 561 && mContentLength > mContentLengthLimit | |
| 562 && mCancelIfContentLengthOverLimit) { | 553 && mCancelIfContentLengthOverLimit) { |
| 563 onContentLengthOverLimit(); | 554 onContentLengthOverLimit(); |
| 564 return; | 555 return; |
| 565 } | 556 } |
| 566 | 557 |
| 567 if (mBufferFullResponse && mContentLength != -1 | 558 if (mBufferFullResponse && mContentLength != -1 && !mContentLengthOv
erLimit) { |
| 568 && !mContentLengthOverLimit) { | 559 ((ChunkedWritableByteChannel) getSink()).setCapacity((int) mCont
entLength); |
| 569 ((ChunkedWritableByteChannel) getSink()).setCapacity( | |
| 570 (int) mContentLength); | |
| 571 } | 560 } |
| 572 | 561 |
| 573 if (mOffset != 0) { | 562 if (mOffset != 0) { |
| 574 // The server may ignore the request for a byte range, in which | 563 // The server may ignore the request for a byte range, in which |
| 575 // case status code will be 200, instead of 206. Note that we | 564 // case status code will be 200, instead of 206. Note that we |
| 576 // cannot call getHttpStatusCode as it rewrites 206 into 200. | 565 // cannot call getHttpStatusCode as it rewrites 206 into 200. |
| 577 if (mHttpStatusCode == 200) { | 566 if (mHttpStatusCode == 200) { |
| 578 // TODO(mef): Revisit this logic. | 567 // TODO(mef): Revisit this logic. |
| 579 if (mContentLength != -1) { | 568 if (mContentLength != -1) { |
| 580 mContentLength -= mOffset; | 569 mContentLength -= mOffset; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 } catch (Exception e) { | 656 } catch (Exception e) { |
| 668 mSinkException = new IOException("Exception in finish", e); | 657 mSinkException = new IOException("Exception in finish", e); |
| 669 } | 658 } |
| 670 } | 659 } |
| 671 | 660 |
| 672 /** | 661 /** |
| 673 * Appends header |name| with value |value| to |headersMap|. | 662 * Appends header |name| with value |value| to |headersMap|. |
| 674 */ | 663 */ |
| 675 @SuppressWarnings("unused") | 664 @SuppressWarnings("unused") |
| 676 @CalledByNative | 665 @CalledByNative |
| 677 private void onAppendResponseHeader(ResponseHeadersMap headersMap, | 666 private void onAppendResponseHeader(ResponseHeadersMap headersMap, String na
me, String value) { |
| 678 String name, String value) { | |
| 679 try { | 667 try { |
| 680 if (!headersMap.containsKey(name)) { | 668 if (!headersMap.containsKey(name)) { |
| 681 headersMap.put(name, new ArrayList<String>()); | 669 headersMap.put(name, new ArrayList<String>()); |
| 682 } | 670 } |
| 683 headersMap.get(name).add(value); | 671 headersMap.get(name).add(value); |
| 684 } catch (Exception e) { | 672 } catch (Exception e) { |
| 685 onCalledByNativeException(e); | 673 onCalledByNativeException(e); |
| 686 } | 674 } |
| 687 } | 675 } |
| 688 | 676 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 707 onCalledByNativeException(e); | 695 onCalledByNativeException(e); |
| 708 } | 696 } |
| 709 return -1; | 697 return -1; |
| 710 } | 698 } |
| 711 | 699 |
| 712 // Native methods are implemented in chromium_url_request.cc. | 700 // Native methods are implemented in chromium_url_request.cc. |
| 713 | 701 |
| 714 private native long nativeCreateRequestAdapter( | 702 private native long nativeCreateRequestAdapter( |
| 715 long urlRequestContextAdapter, String url, int priority); | 703 long urlRequestContextAdapter, String url, int priority); |
| 716 | 704 |
| 717 private native void nativeAddHeader(long urlRequestAdapter, String name, | 705 private native void nativeAddHeader(long urlRequestAdapter, String name, Str
ing value); |
| 718 String value); | |
| 719 | 706 |
| 720 private native void nativeSetMethod(long urlRequestAdapter, String method); | 707 private native void nativeSetMethod(long urlRequestAdapter, String method); |
| 721 | 708 |
| 722 private native void nativeSetUploadData(long urlRequestAdapter, | 709 private native void nativeSetUploadData( |
| 723 String contentType, byte[] content); | 710 long urlRequestAdapter, String contentType, byte[] content); |
| 724 | 711 |
| 725 private native void nativeSetUploadChannel(long urlRequestAdapter, | 712 private native void nativeSetUploadChannel( |
| 726 String contentType, long contentLength); | 713 long urlRequestAdapter, String contentType, long contentLength); |
| 727 | 714 |
| 728 private native void nativeEnableChunkedUpload(long urlRequestAdapter, | 715 private native void nativeEnableChunkedUpload(long urlRequestAdapter, String
contentType); |
| 729 String contentType); | |
| 730 | 716 |
| 731 private native void nativeDisableRedirects(long urlRequestAdapter); | 717 private native void nativeDisableRedirects(long urlRequestAdapter); |
| 732 | 718 |
| 733 private native void nativeAppendChunk(long urlRequestAdapter, | 719 private native void nativeAppendChunk( |
| 734 ByteBuffer chunk, int chunkSize, boolean isLastChunk); | 720 long urlRequestAdapter, ByteBuffer chunk, int chunkSize, boolean isL
astChunk); |
| 735 | 721 |
| 736 private native void nativeStart(long urlRequestAdapter); | 722 private native void nativeStart(long urlRequestAdapter); |
| 737 | 723 |
| 738 private native void nativeCancel(long urlRequestAdapter); | 724 private native void nativeCancel(long urlRequestAdapter); |
| 739 | 725 |
| 740 private native void nativeDestroyRequestAdapter(long urlRequestAdapter); | 726 private native void nativeDestroyRequestAdapter(long urlRequestAdapter); |
| 741 | 727 |
| 742 private native int nativeGetErrorCode(long urlRequestAdapter); | 728 private native int nativeGetErrorCode(long urlRequestAdapter); |
| 743 | 729 |
| 744 private native int nativeGetHttpStatusCode(long urlRequestAdapter); | 730 private native int nativeGetHttpStatusCode(long urlRequestAdapter); |
| 745 | 731 |
| 746 private native String nativeGetHttpStatusText(long urlRequestAdapter); | 732 private native String nativeGetHttpStatusText(long urlRequestAdapter); |
| 747 | 733 |
| 748 private native String nativeGetErrorString(long urlRequestAdapter); | 734 private native String nativeGetErrorString(long urlRequestAdapter); |
| 749 | 735 |
| 750 private native String nativeGetContentType(long urlRequestAdapter); | 736 private native String nativeGetContentType(long urlRequestAdapter); |
| 751 | 737 |
| 752 private native long nativeGetContentLength(long urlRequestAdapter); | 738 private native long nativeGetContentLength(long urlRequestAdapter); |
| 753 | 739 |
| 754 private native String nativeGetHeader(long urlRequestAdapter, String name); | 740 private native String nativeGetHeader(long urlRequestAdapter, String name); |
| 755 | 741 |
| 756 private native void nativeGetAllHeaders(long urlRequestAdapter, | 742 private native void nativeGetAllHeaders(long urlRequestAdapter, ResponseHead
ersMap headers); |
| 757 ResponseHeadersMap headers); | |
| 758 | 743 |
| 759 private native String nativeGetNegotiatedProtocol(long urlRequestAdapter); | 744 private native String nativeGetNegotiatedProtocol(long urlRequestAdapter); |
| 760 | 745 |
| 761 private native boolean nativeGetWasCached(long urlRequestAdapter); | 746 private native boolean nativeGetWasCached(long urlRequestAdapter); |
| 762 | 747 |
| 763 // Explicit class to work around JNI-generator generics confusion. | 748 // Explicit class to work around JNI-generator generics confusion. |
| 764 private static class ResponseHeadersMap extends | 749 private static class ResponseHeadersMap extends HashMap<String, List<String>
> {} |
| 765 HashMap<String, List<String>> { | |
| 766 } | |
| 767 } | 750 } |
| OLD | NEW |