Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Unified Diff: net/cronet/android/java/src/org/chromium/net/UrlRequest.java

Issue 145213003: Initial upload of cronet for Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added cronet_package target to copy cronet.jar and stripped libcronet.so Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/cronet/android/java/src/org/chromium/net/UrlRequest.java
diff --git a/net/cronet/android/java/src/org/chromium/net/UrlRequest.java b/net/cronet/android/java/src/org/chromium/net/UrlRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b44e4a2190a247c6bbac7588b5be2885c26c846f
--- /dev/null
+++ b/net/cronet/android/java/src/org/chromium/net/UrlRequest.java
@@ -0,0 +1,286 @@
+// 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 org.apache.http.conn.ConnectTimeoutException;
+import org.chromium.base.AccessedByNative;
+import org.chromium.base.CalledByNative;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Network request using the native http stack implementation.
+ */
+public class UrlRequest {
+
+ /*
+ * Must match definitions in the native source.
+ */
+ public static final int REQUEST_PRIORITY_IDLE = 0;
+ public static final int REQUEST_PRIORITY_LOWEST = 1;
+ public static final int REQUEST_PRIORITY_LOW = 2;
+ public static final int REQUEST_PRIORITY_MEDIUM = 3;
+ public static final int REQUEST_PRIORITY_HIGHEST = 4;
+
+ /*
+ * Must match definitions in the native source.
+ */
+ private static final int SUCCESS = 0;
+ private static final int UNKNOWN_ERROR = 1;
+ private static final int MALFORMED_URL_ERROR = 2;
+ private static final int CONNECTION_TIMED_OUT = 3;
+ private static final int UNKNOWN_HOST = 4;
+
+ private final UrlRequestContext mRequestContext;
+ private final String mUrl;
+ private final int mPriority;
+ private final Map<String, String> mHeaders;
+ private final WritableByteChannel mSink;
+
+ private Map<String, String> mAdditionalHeaders;
+ private String mPostBodyContentType;
+ private byte[] mPostBody;
+ private WritableByteChannel mOutputChannel;
+ private IOException mSinkException;
+ private boolean mStarted;
+ private boolean mCanceled;
+ private boolean mRecycled;
+ private String mContentType;
+ private long mContentLength;
+
+ /**
+ * This field is accessed exclusively from the native layer.
+ */
+ @AccessedByNative
+ @SuppressWarnings("unused")
+ private long mRequest;
+
+ /**
+ * Constructor.
+ *
+ * @param requestContext The context.
+ * @param url The URL.
+ * @param priority Request priority, e.g. {@link #REQUEST_PRIORITY_MEDIUM}.
+ * @param headers HTTP headers.
+ * @param sink The output channel into which downloaded content will be written.
+ */
+ public UrlRequest(UrlRequestContext requestContext, String url, int priority,
+ Map<String, String> headers, WritableByteChannel sink) {
+ mRequestContext = requestContext;
+ mUrl = url;
+ mPriority = priority;
+ mHeaders = headers;
+ mSink = sink;
+ nativeInit(mRequestContext, mUrl, mPriority);
+ }
+
+ /**
+ * Adds a request header.
+ */
+ public void addHeader(String header, String value) {
+ validateNotStarted();
+ if (mAdditionalHeaders == null) {
+ mAdditionalHeaders = new HashMap<String, String>();
+ }
+ mAdditionalHeaders.put(header, value);
+ }
+
+ /**
+ * Sets data to upload as part of a POST request.
+ *
+ * @param contentType MIME type of the post content or null if this is not a POST.
+ * @param data The content that needs to be uploaded if this is a POST request.
+ */
+ public void setUploadData(String contentType, byte[] data) {
+ validateNotStarted();
+ mPostBodyContentType = contentType;
+ mPostBody = data;
+ }
+
+ public WritableByteChannel getSink() {
+ return mSink;
+ }
+
+ public synchronized void start() {
+ if (mCanceled) {
+ return;
+ }
+
+ validateNotStarted();
+ validateNotRecycled();
+
+ if (mPostBody != null && mPostBody.length > 0) {
+ nativeSetPostData(mPostBodyContentType, mPostBody);
+ }
+
+ if (mHeaders != null && !mHeaders.isEmpty()) {
+ for (Entry<String, String> entry : mHeaders.entrySet()) {
+ nativeAddHeader(entry.getKey(), entry.getValue());
+ }
+ }
+
+ if (mAdditionalHeaders != null && !mAdditionalHeaders.isEmpty()) {
+ for (Entry<String, String> entry : mAdditionalHeaders.entrySet()) {
+ nativeAddHeader(entry.getKey(), entry.getValue());
+ }
+ }
+
+ nativeStart();
+ }
+
+ public synchronized void cancel() {
+ if (mCanceled) {
+ return;
+ }
+
+ mCanceled = true;
+
+ if (!mRecycled) {
+ nativeCancel();
+ }
+ }
+
+ public synchronized boolean isCanceled() {
+ return mCanceled;
+ }
+
+ public synchronized boolean isRecycled() {
+ return mRecycled;
+ }
+
+ /**
+ * Returns an exception if any, or null if the request was completed successfully.
+ */
+ public IOException getException() {
+ if (mSinkException != null) {
+ return mSinkException;
+ }
+
+ validateNotRecycled();
+
+ int errorCode = nativeGetErrorCode();
+ switch (errorCode) {
+ case SUCCESS:
+ return null;
+ case UNKNOWN_ERROR:
+ return new IOException(nativeGetErrorString());
+ case MALFORMED_URL_ERROR:
+ return new MalformedURLException("Malformed URL: " + mUrl);
+ case CONNECTION_TIMED_OUT:
+ return new ConnectTimeoutException("Connection timed out");
+ case UNKNOWN_HOST:
+ String host;
+ try {
+ host = new URL(mUrl).getHost();
+ } catch (MalformedURLException e) {
+ host = mUrl;
+ }
+ return new UnknownHostException("Unknown host: " + host);
+ default:
+ throw new IllegalStateException("Unrecognized error code: " + errorCode);
+ }
+ }
+
+ public native int getHttpStatusCode();
+
+ /**
+ * Content length as reported by the server. May be -1 or incorrect if the server returns the
+ * wrong number, which happens even with Google servers.
+ */
+ public long getContentLength() {
+ return mContentLength;
+ }
+
+ public String getContentType() {
+ return mContentType;
+ }
+
+ /**
+ * A callback invoked when the first chunk of the response has arrived.
+ */
+ @CalledByNative
+ protected void onResponseStarted() {
+ mContentType = nativeGetContentType();
+ mContentLength = nativeGetContentLength();
+ }
+
+ /**
+ * A callback invoked when the response has been fully consumed.
+ */
+ protected void onRequestComplete() {
+ }
+
+ /**
+ * Consumes a portion of the response.
+ *
+ * @param byteBuffer The ByteBuffer to append. Must be a direct buffer, and no references to it
+ * may be retained after the method ends, as it wraps code managed on the native heap.
+ */
+ @CalledByNative
+ protected void onBytesRead(ByteBuffer byteBuffer) {
+ try {
+ while (byteBuffer.hasRemaining()) {
+ mSink.write(byteBuffer);
+ }
+ } catch (IOException e) {
+ mSinkException = e;
+ cancel();
+ }
+ }
+
+ /**
+ * Notifies the listener, releases native data structures.
+ */
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private synchronized void finish() {
+ if (mRecycled) {
+ return;
+ }
+ try {
+ mSink.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ onRequestComplete();
+ nativeRecycle();
+ mRecycled = true;
+ }
+
+ private void validateNotRecycled() {
+ if (mRecycled) {
+ throw new IllegalStateException("Accessing recycled request");
+ }
+ }
+
+ private void validateNotStarted() {
+ if (mStarted) {
+ throw new IllegalStateException("Request already started");
+ }
+ }
+
+ public String getUrl() {
+ return mUrl;
+ }
+
+ private native void nativeInit(UrlRequestContext requestContext, String url, int priority);
+ private native void nativeAddHeader(String name, String value);
+ private native void nativeSetPostData(String contentType, byte[] content);
+ private native void nativeStart();
+ private native void nativeCancel();
+ private native void nativeRecycle();
+ private native int nativeGetErrorCode();
+ private native String nativeGetErrorString();
+ private native String nativeGetContentType();
+ private native long nativeGetContentLength();
+}

Powered by Google App Engine
This is Rietveld 408576698