Chromium Code Reviews| Index: net/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
| diff --git a/net/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java b/net/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c17f19f2763de808712c24a3299efb5664f890f7 |
| --- /dev/null |
| +++ b/net/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
| @@ -0,0 +1,178 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.net; |
| + |
| +import java.io.IOException; |
| +import java.nio.ByteBuffer; |
| +import java.nio.channels.WritableByteChannel; |
| +import java.util.Map; |
| + |
| +/** |
| + * Network request using the native http stack implementation. |
| + */ |
| +class ChromiumUrlRequest extends UrlRequest implements HttpUrlRequest { |
| + |
| + private final HttpUrlRequestListener mListener; |
| + private boolean mBufferFullResponse; |
| + private long mOffset; |
|
dplotnikov
2014/03/07 20:01:12
Do you believe we should keep this resumable downl
mef
2014/03/07 20:54:12
Good question. At this point my primary goal was t
|
| + private long mContentLength; |
| + private long mContentLengthLimit; |
| + private boolean mCancelIfContentLengthOverLimit; |
| + private boolean mContentLengthOverLimit; |
| + private boolean mSkippingToOffset; |
| + private long mSize; |
|
mmenke
2014/03/07 17:02:39
Entire file should be using 4-space indent (Goes f
mef
2014/03/07 20:54:12
Yeah, is there some tool for that? 'git cl format'
mef
2014/03/14 20:03:24
Done.
|
| + |
| + public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, String url, |
|
mmenke
2014/03/07 17:02:39
Line too long (Goes for a bunch of lines in these
mef
2014/03/07 20:54:12
Roger that.
|
| + int priority, Map<String, String> headers, HttpUrlRequestListener listener) { |
|
mmenke
2014/03/07 17:02:39
All lines with arguments should be lined up.First
|
| + this(requestContext, url, priority, headers, new ChunkedWritableByteChannel(), listener); |
| + mBufferFullResponse = true; |
| + } |
| + |
| + public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext, String url, |
| + int priority, Map<String, String> headers, WritableByteChannel sink, |
| + HttpUrlRequestListener listener) { |
| + super(requestContext, url, convertRequestPriority(priority), headers, sink); |
| + if (requestContext == null) { |
| + throw new NullPointerException("Context is required"); |
| + } |
| + if (url == null) { |
| + throw new NullPointerException("URL is required"); |
| + } |
| + mListener = listener; |
| + } |
| + |
| + private static int convertRequestPriority(int priority) { |
| + switch (priority) { |
| + case HttpUrlRequest.REQUEST_PRIORITY_IDLE: |
| + return UrlRequest.REQUEST_PRIORITY_IDLE; |
| + case HttpUrlRequest.REQUEST_PRIORITY_LOWEST: |
| + return UrlRequest.REQUEST_PRIORITY_LOWEST; |
| + case HttpUrlRequest.REQUEST_PRIORITY_LOW: |
| + return UrlRequest.REQUEST_PRIORITY_LOW; |
| + case HttpUrlRequest.REQUEST_PRIORITY_MEDIUM: |
| + return UrlRequest.REQUEST_PRIORITY_MEDIUM; |
| + case HttpUrlRequest.REQUEST_PRIORITY_HIGHEST: |
| + return UrlRequest.REQUEST_PRIORITY_HIGHEST; |
| + default: |
| + return UrlRequest.REQUEST_PRIORITY_MEDIUM; |
| + } |
| + } |
| + |
| + @Override |
| + public void setOffset(long offset) { |
| + mOffset = offset; |
| + if (offset != 0) { |
| + addHeader("Range", "bytes=" + offset + "-"); |
| + } |
| + } |
| + |
| + @Override |
| + public long getContentLength() { |
| + return mContentLength; |
| + } |
| + |
| + @Override |
| + public void setContentLengthLimit(long limit, boolean cancelEarly) { |
| + mContentLengthLimit = limit; |
| + mCancelIfContentLengthOverLimit = cancelEarly; |
| + } |
| + |
| + @Override |
| + protected void onResponseStarted() { |
| + super.onResponseStarted(); |
| + |
| + mContentLength = super.getContentLength(); |
| + if (mContentLengthLimit > 0 && mContentLength > mContentLengthLimit |
| + && mCancelIfContentLengthOverLimit) { |
| + onContentLengthOverLimit(); |
| + return; |
| + } |
| + |
| + if (mBufferFullResponse && mContentLength != -1 && !mContentLengthOverLimit) { |
| + ((ChunkedWritableByteChannel) getSink()).setCapacity((int) mContentLength); |
| + } |
| + |
| + if (mOffset != 0) { |
| + // The server may ignore the request for a byte range |
|
mmenke
2014/03/07 17:02:39
Suggestion adding a period. Android style guide d
mef
2014/03/07 20:54:12
Done. Agreed.
|
| + if (super.getHttpStatusCode() == 200) { |
| + if (mContentLength != -1) { |
| + mContentLength -= mOffset; |
| + } |
| + mSkippingToOffset = true; |
| + } else { |
| + mSize = mOffset; |
| + } |
| + } |
| + } |
| + |
| + @Override |
| + protected void onBytesRead(ByteBuffer buffer) { |
| + if (mContentLengthOverLimit) { |
| + return; |
| + } |
| + |
| + int size = buffer.remaining(); |
| + mSize += size; |
| + if (mSkippingToOffset) { |
| + if (mSize <= mOffset) { |
| + return; |
| + } else { |
| + mSkippingToOffset = false; |
| + buffer.position((int) (mOffset - (mSize - size))); |
| + } |
| + } |
| + |
| + if (mContentLengthLimit != 0 && mSize > mContentLengthLimit) { |
| + buffer.limit(size - (int) (mSize - mContentLengthLimit)); |
| + super.onBytesRead(buffer); |
| + onContentLengthOverLimit(); |
| + return; |
| + } |
| + |
| + super.onBytesRead(buffer); |
| + } |
| + |
| + private void onContentLengthOverLimit() { |
| + mContentLengthOverLimit = true; |
| + cancel(); |
| + } |
| + |
| + @Override |
| + protected void onRequestComplete() { |
| + mListener.onRequestComplete(this); |
| + } |
| + |
| + @Override |
| + public int getHttpStatusCode() { |
| + int httpStatusCode = super.getHttpStatusCode(); |
| + |
| + // If we have been able to successfully resume a previously interrupted download, |
| + // the status code will be 206, not 200. Since the rest of the application is |
| + // expecting 200 to indicate success, we need to fake it. |
|
mmenke
2014/03/07 17:02:39
Add a TODO about investigating this - I'm not sure
mef
2014/03/07 20:54:12
Done.
|
| + if (httpStatusCode == 206) { |
| + httpStatusCode = 200; |
| + } |
| + return httpStatusCode; |
| + } |
| + |
| + @Override |
| + public IOException getException() { |
| + IOException ex = super.getException(); |
| + if (ex == null && mContentLengthOverLimit) { |
| + ex = new ResponseTooLargeException(); |
| + } |
| + return ex; |
| + } |
| + |
| + @Override |
| + public ByteBuffer getByteBuffer() { |
| + return ((ChunkedWritableByteChannel) getSink()).getByteBuffer(); |
| + } |
| + |
| + @Override |
| + public byte[] getResponseAsBytes() { |
| + return ((ChunkedWritableByteChannel) getSink()).getBytes(); |
| + } |
| +} |