diff options
author | xunjieli <xunjieli@chromium.org> | 2015-08-10 12:16:29 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-10 19:17:13 +0000 |
commit | ca0afe553936e5eab41988b882a859e84578cd38 (patch) | |
tree | 67e9af54fd6368767168067cebfadde0a5106d6a /components/cronet | |
parent | 97f4f34e419ff991d962361dbc68803cd6c2dbe6 (diff) | |
download | chromium_src-ca0afe553936e5eab41988b882a859e84578cd38.zip chromium_src-ca0afe553936e5eab41988b882a859e84578cd38.tar.gz chromium_src-ca0afe553936e5eab41988b882a859e84578cd38.tar.bz2 |
[Cronet] Add a README doc for Cronet
This CL adds a README.md for Cronet. It also generates a html
file from the markdown file, and includes the html file as
the overview page in the javadoc.
BUG=428935
Review URL: https://codereview.chromium.org/1180733003
Cr-Commit-Position: refs/heads/master@{#342663}
Diffstat (limited to 'components/cronet')
4 files changed, 221 insertions, 9 deletions
diff --git a/components/cronet/README.md b/components/cronet/README.md new file mode 100644 index 0000000..8a46ef5 --- /dev/null +++ b/components/cronet/README.md @@ -0,0 +1,169 @@ +# Quick Start Guide to Using Cronet +Cronet is the networking stack of Chromium put into a library for use on +mobile. This is the same networking stack that is used in the Chrome browser +by over a billion people. It offers an easy-to-use, high performance, +standards-compliant, and secure way to perform HTTP requests. Cronet has support +for both Android and iOS. On Android, Cronet offers its own Java asynchronous +API as well as support for the [java.net.HttpURLConnection] API. +This document gives a brief introduction to using these two Java APIs. + +### Basics +First you will need to implement the `UrlRequestListener` interface to handle +events during the lifetime of a request. For example: + + class MyListener implements UrlRequestListener { + @Override + public void onReceivedRedirect(UrlRequest request, + ResponseInfo responseInfo, String newLocationUrl) { + if (followRedirect) { + // Let's tell Cronet to follow the redirect! + mRequest.followRedirect(); + } else { + // Not worth following the redirect? Abandon the request. + mRequest.cancel(); + } + } + + @Override + public void onResponseStarted(UrlRequest request, + ResponseInfo responseInfo) { + // Now we have response headers! + int httpStatusCode = responseInfo.getHttpStatusCode(); + if (httpStatusCode == 200) { + // Success! Let's tell Cronet to read the response body. + request.read(myBuffer); + } else if (httpStatusCode == 503) { + // Do something. Note that 4XX and 5XX are not considered + // errors from Cronet's perspective since the response is + // successfully read. + } + responseHeaders = responseInfo.getAllHeaders(); + } + + @Override + public void onReadCompleted(UrlRequest request, + ResponseInfo responseInfo, ByteBuffer byteBuffer) { + // Response body is available. + doSomethingWithResponseData(byteBuffer); + // Let's tell Cronet to continue reading the response body or + // inform us that the response is complete! + request.read(myBuffer); + } + + @Override + public void onSucceeded(UrlRequest request, + ExtendedResponseInfo extendedResponseInfo) { + // Request has completed successfully! + } + + @Override + public void onFailed(UrlRequest request, + ResponseInfo responseInfo, UrlRequestException error) { + // Request has failed. responseInfo might be null. + Log.e("MyListener", "Request failed. " + error.getMessage()); + // Maybe handle error here. Typical errors include hostname + // not resolved, connection to server refused, etc. + } + } + +Make a request like this: + + UrlRequestContextConfig myConfig = new UrlRequestContextConfig(); + CronetUrlRequestContext myRequestContext = + new CronetUrlRequestContext(getContext(), myConfig); + Executor executor = ExecutorService.newSingleThreadExecutor(); + MyListener listener = new MyListener(); + UrlRequest request = myRequestContext.createRequest( + "https://www.example.com", listener, executor); + request.start(); + +In the above example, `MyListener` implements the `UrlRequestListener` +interface. The request is started asynchronously. When the response is ready +(fully or partially), and in the event of failures or redirects, +`listener`'s methods will be invoked on `executor`'s thread to inform the +client of the request state and/or response information. + +### Downloading Data +When Cronet fetches response headers from the server or gets them from the +cache, `UrlRequestListener.onResponseStarted` will be invoked. To read the +response body, the client should call `UrlRequest.read` and supply a +[ByteBuffer] for Cronet to fill. Once a portion or all of +the response body is read, `UrlRequestListener.onReadCompleted` will be invoked. +The client may consume the data, or copy the contents of the `byteBuffer` +elsewhere for use later. The data in `byteBuffer` is only guaranteed to be +valid for the duration of the `UrlRequestListener.onReadCompleted` callback. +Once the client is ready to consume more data, the client should call +`UrlRequest.read` again. The process continues until +`UrlRequestListener.onSucceeded` or `UrlRequestListener.onFailed` is invoked, +which signals the completion of the request. + +### Uploading Data + MyUploadDataProvider myUploadDataProvider = new MyUploadDataProvider(); + request.setHttpMethod("POST"); + request.setUploadDataProvider(myUploadDataProvider, executor); + request.start(); + +In the above example, `MyUploadDataProvider` implements the +`UploadDataProvider` interface. When Cronet is ready to send the request body, +`myUploadDataProvider.read(UploadDataSink uploadDataSink, +ByteBuffer byteBuffer)` will be invoked. The client will need to write the +request body into `byteBuffer`. Once the client is done writing into +`byteBuffer`, the client can let Cronet know by calling +`uploadDataSink.onReadSucceeded`. If the request body doesn't fit into +`byteBuffer`, the client can continue writing when `UploadDataProvider.read` is +invoked again. For more details, please see the API reference. + +### <a id=configuring-cronet></a> Configuring Cronet +Various configuration options are available via the `UrlRequestContextConfig` +object. + +Enabling HTTP/2, QUIC, or SDCH: + +- For Example: + + myConfig.enableSPDY(true).enableQUIC(true).enableSDCH(true); + +Controlling the cache: + +- Use a 100KiB in-memory cache: + + myConfig.enableHttpCache( + UrlRequestContextConfig.HttpCache.IN_MEMORY, 100 * 1024); + +- or use a 1MiB disk cache: + + myConfig.setStoragePath(storagePathString); + myConfig.enableHttpCache(UrlRequestContextConfig.HttpCache.DISK, + 1024 * 1024); + +### Debugging +To get more information about how Cronet is processing network +requests, you can start and stop **NetLog** logging by calling +`UrlRequestContext.startNetLogToFile` and `UrlRequestContext.stopNetLog`. +Bear in mind that logs may contain sensitive data. You may analyze the +generated log by navigating to [chrome://net-internals#import] using a +Chrome browser. + +# Using the java.net.HttpURLConnection API +Cronet offers an implementation of the [java.net.HttpURLConnection] API to make +it easier for apps which rely on this API to use Cronet. +To use Cronet's implementation instead of the system's default implementation, +simply do the following: + + CronetURLStreamHandlerFactory streamHandlerFactory = + new CronetURLStreamHandlerFactory(getContext(), myConfig); + URL.setURLStreamHandlerFactory(streamHandlerFactory); + +Cronet's +HttpURLConnection implementation has some limitations as compared to the system +implementation, including not utilizing the default system HTTP cache (Please +see {@link org.chromium.net.urlconnection.CronetURLStreamHandlerFactory} for +more information). +You can configure Cronet and control caching through the +`UrlRequestContextConfig` instance, `myConfig` +(See [Configuring Cronet](#configuring-cronet) section), before you pass it +into the `CronetURLStreamHandlerFactory` constructor. + +[ByteBuffer]: https://developer.android.com/reference/java/nio/ByteBuffer.html +[chrome://net-internals#import]: chrome://net-internals#import +[java.net.HttpURLConnection]: https://developer.android.com/reference/java/net/HttpURLConnection.html diff --git a/components/cronet/android/java/build.xml b/components/cronet/android/java/build.xml index b87f615..c72db3a 100644 --- a/components/cronet/android/java/build.xml +++ b/components/cronet/android/java/build.xml @@ -1,6 +1,7 @@ <project> <target name="doc" description="generate documentation"> <javadoc destdir="${doc.dir}" + overview="${overview}" windowtitle="Cronet API" nohelp="yes" notree="yes" diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java index 0a312fe..4e2999f 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java @@ -13,8 +13,31 @@ import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; /** - * An implementation of {@code URLStreamHandlerFactory} to handle http - * and https traffic. + * An implementation of {@code URLStreamHandlerFactory} to handle http and https + * traffic. + * <p> + * Cronet does not use certain HTTP features provided via the system: + * <p> + * - the HTTP cache installed via + * {@link android.net.http.HttpResponseCache#install} + * <p> + * - the HTTP authentication method installed via + * {@link java.net.Authenticator#setDefault} + * <p> + * - the HTTP cookie storage installed via + * {@link java.net.CookieHandler#setDefault} + * <p> + * While Cronet supports and encourages requests using the HTTPS protocol, + * Cronet does not provide support for the + * {@link javax.net.ssl.HttpsURLConnection} API. This lack of support also + * includes not using certain HTTPS features provided via the system: + * <p> + * - the HTTPS hostname verification installed via + * {@link javax.net.ssl.HttpsURLConnection#setHostnameVerifier} + * <p> + * - the HTTPS socket factory installed via + * {@link javax.net.ssl.HttpsURLConnection#setSSLSocketFactory} + * */ public class CronetURLStreamHandlerFactory implements URLStreamHandlerFactory { diff --git a/components/cronet/tools/generate_javadoc.py b/components/cronet/tools/generate_javadoc.py index 614c51f..2326c724 100755 --- a/components/cronet/tools/generate_javadoc.py +++ b/components/cronet/tools/generate_javadoc.py @@ -13,29 +13,48 @@ REPOSITORY_ROOT = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', '..', '..')) sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) +sys.path.append(os.path.join(REPOSITORY_ROOT, 'net/tools/net_docs')) import build_utils +import net_docs +from markdown.postprocessors import Postprocessor +from markdown.extensions import Extension + + +class CronetPostprocessor(Postprocessor): + def run(self, text): + return text.replace('@Override', '@Override') + + +class CronetExtension(Extension): + def extendMarkdown(self, md, md_globals): + md.postprocessors.add('CronetPostprocessor', + CronetPostprocessor(md), '_end') def GenerateJavadoc(options): - source_dir = options.source_dir - output_dir = options.output_dir - working_dir = options.working_dir + output_dir = os.path.abspath(os.path.join(options.output_dir, 'javadoc')) + working_dir = os.path.join(options.input_dir, 'android/java') + overview_file = os.path.abspath(options.overview_file) build_utils.DeleteDirectory(output_dir) build_utils.MakeDirectory(output_dir) - javadoc_cmd = ['ant', '-Dsource.dir=' + source_dir, - '-Ddoc.dir=' + os.path.abspath(output_dir), 'doc'] + javadoc_cmd = ['ant', '-Dsource.dir=src', '-Ddoc.dir=' + output_dir, + '-Doverview=' + overview_file, 'doc'] build_utils.CheckOutput(javadoc_cmd, cwd=working_dir) def main(): parser = optparse.OptionParser() - parser.add_option('--source-dir', help='Source directory') parser.add_option('--output-dir', help='Directory to put javadoc') - parser.add_option('--working-dir', help='Working directory') + parser.add_option('--input-dir', help='Root of cronet source') + parser.add_option('--overview-file', help='Path of the overview page') + parser.add_option('--readme-file', help='Path of the README.md') options, _ = parser.parse_args() + net_docs.ProcessDocs([options.readme_file], options.input_dir, + options.output_dir, extensions=[CronetExtension()]) + GenerateJavadoc(options) if __name__ == '__main__': |