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

Side by Side Diff: components/cronet/android/api/src/org/chromium/net/CronetEngine.java

Issue 1429863008: [Cronet] Remove JSON serialization of CronetEngine.Builder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix component_unittests Created 5 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 android.content.Context; 7 import android.content.Context;
8 import android.support.annotation.IntDef; 8 import android.support.annotation.IntDef;
9 import android.util.Base64;
10 import android.util.Log; 9 import android.util.Log;
11 10
12 import org.json.JSONArray;
13 import org.json.JSONException;
14 import org.json.JSONObject;
15
16 import java.io.File; 11 import java.io.File;
17 import java.lang.annotation.Retention; 12 import java.lang.annotation.Retention;
18 import java.lang.annotation.RetentionPolicy; 13 import java.lang.annotation.RetentionPolicy;
19 import java.lang.reflect.Constructor; 14 import java.lang.reflect.Constructor;
20 import java.net.IDN; 15 import java.net.IDN;
21 import java.net.Proxy; 16 import java.net.Proxy;
22 import java.net.URL; 17 import java.net.URL;
23 import java.net.URLConnection; 18 import java.net.URLConnection;
24 import java.net.URLStreamHandlerFactory; 19 import java.net.URLStreamHandlerFactory;
25 import java.util.Date; 20 import java.util.Date;
26 import java.util.HashSet; 21 import java.util.HashSet;
22 import java.util.LinkedList;
27 import java.util.List; 23 import java.util.List;
28 import java.util.Map; 24 import java.util.Map;
29 import java.util.Set; 25 import java.util.Set;
30 import java.util.concurrent.Executor; 26 import java.util.concurrent.Executor;
31 import java.util.regex.Pattern; 27 import java.util.regex.Pattern;
32 28
33 /** 29 /**
34 * An engine to process {@link UrlRequest}s, which uses the best HTTP stack 30 * An engine to process {@link UrlRequest}s, which uses the best HTTP stack
35 * available on the current platform. 31 * available on the current platform.
36 */ 32 */
37 public abstract class CronetEngine { 33 public abstract class CronetEngine {
38 /** 34 /**
39 * A builder for {@link CronetEngine}s, which allows runtime configuration o f 35 * A builder for {@link CronetEngine}s, which allows runtime configuration o f
40 * {@code CronetEngine}. Configuration options are set on the builder and 36 * {@code CronetEngine}. Configuration options are set on the builder and
41 * then {@link #build} is called to create the {@code CronetEngine}. 37 * then {@link #build} is called to create the {@code CronetEngine}.
42 */ 38 */
43 public static class Builder { 39 public static class Builder {
40 // A hint that a host supports QUIC.
41 static class QuicHint {
42 // The host.
43 final String mHost;
44 // Port of the server that supports QUIC.
45 final int mPort;
46 // Alternate protocol port.
47 final int mAlternatePort;
48
49 QuicHint(String host, int port, int alternatePort) {
50 mHost = host;
51 mPort = port;
52 mAlternatePort = alternatePort;
53 }
54 }
55
56 // A public key pin.
57 static class Pkp {
58 // Host to pin for.
59 final String mHost;
60 // Array of SHA-256 hashes of keys.
61 final byte[][] mHashes;
62 // Should pin apply to subdomains?
63 final boolean mIncludeSubdomains;
64 // When the pin expires.
65 final Date mExpirationDate;
66
67 Pkp(String host, byte[][] hashes, boolean includeSubdomains, Date ex pirationDate) {
68 mHost = host;
69 mHashes = hashes;
70 mIncludeSubdomains = includeSubdomains;
71 mExpirationDate = expirationDate;
72 }
73 }
74
44 private static final Pattern INVALID_PKP_HOST_NAME = Pattern.compile("^[ 0-9\\.]*$"); 75 private static final Pattern INVALID_PKP_HOST_NAME = Pattern.compile("^[ 0-9\\.]*$");
45 76
46 private final JSONObject mConfig; 77 // Private fields are simply storage of configuration for the resulting CronetEngine.
78 // See setters below for verbose descriptions.
47 private final Context mContext; 79 private final Context mContext;
80 private final List<QuicHint> mQuicHints = new LinkedList<QuicHint>();
81 private final List<Pkp> mPkps = new LinkedList<Pkp>();
82 private String mUserAgent;
83 private String mStoragePath;
84 private boolean mLegacyModeEnabled;
85 private String mLibraryName;
86 private boolean mQuicEnabled;
87 private boolean mHttp2Enabled;
88 private boolean mSdchEnabled;
89 private String mDataReductionProxyKey;
90 private String mDataReductionProxyPrimaryProxy;
91 private String mDataReductionProxyFallbackProxy;
92 private String mDataReductionProxySecureProxyCheckUrl;
93 private boolean mDisableCache;
94 private int mHttpCacheMode;
95 private long mHttpCacheMaxSize;
96 private String mExperimentalOptions;
97 private long mMockCertVerifier;
48 98
49 /** 99 /**
50 * Default config enables SPDY, disables QUIC, SDCH and HTTP cache. 100 * Default config enables SPDY, disables QUIC, SDCH and HTTP cache.
51 * @param context Android {@link Context} for engine to use. 101 * @param context Android {@link Context} for engine to use.
52 */ 102 */
53 public Builder(Context context) { 103 public Builder(Context context) {
54 mConfig = new JSONObject();
55 mContext = context; 104 mContext = context;
105 setLibraryName("cronet");
56 enableLegacyMode(false); 106 enableLegacyMode(false);
57 enableQUIC(false); 107 enableQUIC(false);
58 enableHTTP2(true); 108 enableHTTP2(true);
59 enableSDCH(false); 109 enableSDCH(false);
60 enableHttpCache(HTTP_CACHE_DISABLED, 0); 110 enableHttpCache(HTTP_CACHE_DISABLED, 0);
61 } 111 }
62 112
63 /** 113 /**
64 * Constructs a User-Agent string including Cronet version, and 114 * Constructs a User-Agent string including Cronet version, and
65 * application name and version. 115 * application name and version.
66 * 116 *
67 * @return User-Agent string. 117 * @return User-Agent string.
68 */ 118 */
69 public String getDefaultUserAgent() { 119 public String getDefaultUserAgent() {
70 return UserAgent.from(mContext); 120 return UserAgent.from(mContext);
71 } 121 }
72 122
73 /** 123 /**
74 * Overrides the User-Agent header for all requests. 124 * Overrides the User-Agent header for all requests.
75 * @return the builder to facilitate chaining. 125 * @return the builder to facilitate chaining.
76 */ 126 */
77 public Builder setUserAgent(String userAgent) { 127 public Builder setUserAgent(String userAgent) {
78 return putString(CronetEngineBuilderList.USER_AGENT, userAgent); 128 mUserAgent = userAgent;
129 return this;
79 } 130 }
80 131
81 String getUserAgent() { 132 String getUserAgent() {
82 return mConfig.optString(CronetEngineBuilderList.USER_AGENT); 133 return mUserAgent;
83 } 134 }
84 135
85 /** 136 /**
86 * Sets directory for HTTP Cache and Cookie Storage. The directory must 137 * Sets directory for HTTP Cache and Cookie Storage. The directory must
87 * exist. 138 * exist.
88 * <p> 139 * <p>
89 * <b>NOTE:</b> Do not use the same storage directory with more than one 140 * <b>NOTE:</b> Do not use the same storage directory with more than one
90 * {@code CronetEngine} at a time. Access to the storage directory does 141 * {@code CronetEngine} at a time. Access to the storage directory does
91 * not support concurrent access by multiple {@code CronetEngine}s. 142 * not support concurrent access by multiple {@code CronetEngine}s.
92 * 143 *
93 * @param value path to existing directory. 144 * @param value path to existing directory.
94 * @return the builder to facilitate chaining. 145 * @return the builder to facilitate chaining.
95 */ 146 */
96 public Builder setStoragePath(String value) { 147 public Builder setStoragePath(String value) {
97 if (!new File(value).isDirectory()) { 148 if (!new File(value).isDirectory()) {
98 throw new IllegalArgumentException( 149 throw new IllegalArgumentException(
99 "Storage path must be set to existing directory"); 150 "Storage path must be set to existing directory");
100 } 151 }
101 152 mStoragePath = value;
102 return putString(CronetEngineBuilderList.STORAGE_PATH, value); 153 return this;
103 } 154 }
104 155
105 String storagePath() { 156 String storagePath() {
106 return mConfig.optString(CronetEngineBuilderList.STORAGE_PATH); 157 return mStoragePath;
107 } 158 }
108 159
109 /** 160 /**
110 * Sets whether falling back to implementation based on system's 161 * Sets whether falling back to implementation based on system's
111 * {@link java.net.HttpURLConnection} implementation is enabled. 162 * {@link java.net.HttpURLConnection} implementation is enabled.
112 * Defaults to disabled. 163 * Defaults to disabled.
113 * @return the builder to facilitate chaining. 164 * @return the builder to facilitate chaining.
114 * @deprecated Not supported by the new API. 165 * @deprecated Not supported by the new API.
115 */ 166 */
116 @Deprecated 167 @Deprecated
117 public Builder enableLegacyMode(boolean value) { 168 public Builder enableLegacyMode(boolean value) {
118 return putBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE, value) ; 169 mLegacyModeEnabled = value;
170 return this;
119 } 171 }
120 172
121 boolean legacyMode() { 173 boolean legacyMode() {
122 return mConfig.optBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE ); 174 return mLegacyModeEnabled;
123 } 175 }
124 176
125 /** 177 /**
126 * Overrides the name of the native library backing Cronet. 178 * Overrides the name of the native library backing Cronet.
127 * @return the builder to facilitate chaining. 179 * @return the builder to facilitate chaining.
128 */ 180 */
129 Builder setLibraryName(String libName) { 181 Builder setLibraryName(String libName) {
130 return putString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME, libNam e); 182 mLibraryName = libName;
183 return this;
131 } 184 }
132 185
133 String libraryName() { 186 String libraryName() {
134 return mConfig.optString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME , "cronet"); 187 return mLibraryName;
135 } 188 }
136 189
137 /** 190 /**
138 * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protoco l 191 * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protoco l
139 * is enabled. Defaults to disabled. 192 * is enabled. Defaults to disabled.
140 * @return the builder to facilitate chaining. 193 * @return the builder to facilitate chaining.
141 */ 194 */
142 public Builder enableQUIC(boolean value) { 195 public Builder enableQUIC(boolean value) {
143 return putBoolean(CronetEngineBuilderList.ENABLE_QUIC, value); 196 mQuicEnabled = value;
197 return this;
198 }
199
200 boolean quicEnabled() {
201 return mQuicEnabled;
144 } 202 }
145 203
146 /** 204 /**
147 * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a> 205 * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a>
148 * protocol is enabled. Defaults to enabled. 206 * protocol is enabled. Defaults to enabled.
149 * @return the builder to facilitate chaining. 207 * @return the builder to facilitate chaining.
150 */ 208 */
151 public Builder enableHTTP2(boolean value) { 209 public Builder enableHTTP2(boolean value) {
152 return putBoolean(CronetEngineBuilderList.ENABLE_SPDY, value); 210 mHttp2Enabled = value;
211 return this;
212 }
213
214 boolean http2Enabled() {
215 return mHttp2Enabled;
153 } 216 }
154 217
155 /** 218 /**
156 * Sets whether 219 * Sets whether
157 * <a 220 * <a
158 * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/at t-0441/Shared_Dictionary_Compression_over_HTTP.pdf"> 221 * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/at t-0441/Shared_Dictionary_Compression_over_HTTP.pdf">
159 * SDCH</a> compression is enabled. Defaults to disabled. 222 * SDCH</a> compression is enabled. Defaults to disabled.
160 * @return the builder to facilitate chaining. 223 * @return the builder to facilitate chaining.
161 */ 224 */
162 public Builder enableSDCH(boolean value) { 225 public Builder enableSDCH(boolean value) {
163 return putBoolean(CronetEngineBuilderList.ENABLE_SDCH, value); 226 mSdchEnabled = value;
227 return this;
228 }
229
230 boolean sdchEnabled() {
231 return mSdchEnabled;
164 } 232 }
165 233
166 /** 234 /**
167 * Enables 235 * Enables
168 * <a href="https://developer.chrome.com/multidevice/data-compression">D ata 236 * <a href="https://developer.chrome.com/multidevice/data-compression">D ata
169 * Reduction Proxy</a>. Defaults to disabled. 237 * Reduction Proxy</a>. Defaults to disabled.
170 * @param key key to use when authenticating with the proxy. 238 * @param key key to use when authenticating with the proxy.
171 * @return the builder to facilitate chaining. 239 * @return the builder to facilitate chaining.
172 */ 240 */
173 public Builder enableDataReductionProxy(String key) { 241 public Builder enableDataReductionProxy(String key) {
174 return (putString(CronetEngineBuilderList.DATA_REDUCTION_PROXY_KEY, key)); 242 mDataReductionProxyKey = key;
243 return this;
244 }
245
246 String dataReductionProxyKey() {
247 return mDataReductionProxyKey;
175 } 248 }
176 249
177 /** 250 /**
178 * Overrides 251 * Overrides
179 * <a href="https://developer.chrome.com/multidevice/data-compression"> 252 * <a href="https://developer.chrome.com/multidevice/data-compression">
180 * Data Reduction Proxy</a> configuration parameters with a primary 253 * Data Reduction Proxy</a> configuration parameters with a primary
181 * proxy name, fallback proxy name, and a secure proxy check URL. Proxie s 254 * proxy name, fallback proxy name, and a secure proxy check URL. Proxie s
182 * are specified as [scheme://]host[:port]. Used for testing. 255 * are specified as [scheme://]host[:port]. Used for testing.
183 * @param primaryProxy the primary data reduction proxy to use. 256 * @param primaryProxy the primary data reduction proxy to use.
184 * @param fallbackProxy a fallback data reduction proxy to use. 257 * @param fallbackProxy a fallback data reduction proxy to use.
185 * @param secureProxyCheckUrl a URL to fetch to determine if using a sec ure 258 * @param secureProxyCheckUrl a URL to fetch to determine if using a sec ure
186 * proxy is allowed. 259 * proxy is allowed.
187 * @return the builder to facilitate chaining. 260 * @return the builder to facilitate chaining.
188 * @hide 261 * @hide
189 * @deprecated Marked as deprecated because @hide doesn't properly hide but 262 * @deprecated Marked as deprecated because @hide doesn't properly hide but
190 * javadocs are built with nodeprecated="yes". 263 * javadocs are built with nodeprecated="yes".
191 */ 264 */
192 @SuppressWarnings("DepAnn") 265 @SuppressWarnings("DepAnn")
193 public Builder setDataReductionProxyOptions( 266 public Builder setDataReductionProxyOptions(
194 String primaryProxy, String fallbackProxy, String secureProxyChe ckUrl) { 267 String primaryProxy, String fallbackProxy, String secureProxyChe ckUrl) {
195 if (primaryProxy.isEmpty() || fallbackProxy.isEmpty() 268 if (primaryProxy.isEmpty() || fallbackProxy.isEmpty()
196 || secureProxyCheckUrl.isEmpty()) { 269 || secureProxyCheckUrl.isEmpty()) {
197 throw new IllegalArgumentException( 270 throw new IllegalArgumentException(
198 "Primary and fallback proxies and check url must be set" ); 271 "Primary and fallback proxies and check url must be set" );
199 } 272 }
200 putString(CronetEngineBuilderList.DATA_REDUCTION_PRIMARY_PROXY, prim aryProxy); 273 mDataReductionProxyPrimaryProxy = primaryProxy;
201 putString(CronetEngineBuilderList.DATA_REDUCTION_FALLBACK_PROXY, fal lbackProxy); 274 mDataReductionProxyFallbackProxy = fallbackProxy;
202 putString(CronetEngineBuilderList.DATA_REDUCTION_SECURE_PROXY_CHECK_ URL, 275 mDataReductionProxySecureProxyCheckUrl = secureProxyCheckUrl;
203 secureProxyCheckUrl);
204 return this; 276 return this;
205 } 277 }
206 278
279 String dataReductionProxyPrimaryProxy() {
280 return mDataReductionProxyPrimaryProxy;
281 }
282
283 String dataReductionProxyFallbackProxy() {
284 return mDataReductionProxyFallbackProxy;
285 }
286
287 String dataReductionProxySecureProxyCheckUrl() {
288 return mDataReductionProxySecureProxyCheckUrl;
289 }
290
207 /** @deprecated not really deprecated but hidden. */ 291 /** @deprecated not really deprecated but hidden. */
208 @IntDef({ 292 @IntDef({
209 HTTP_CACHE_DISABLED, HTTP_CACHE_IN_MEMORY, HTTP_CACHE_DISK_NO_HT TP, HTTP_CACHE_DISK, 293 HTTP_CACHE_DISABLED, HTTP_CACHE_IN_MEMORY, HTTP_CACHE_DISK_NO_HT TP, HTTP_CACHE_DISK,
210 }) 294 })
211 @Retention(RetentionPolicy.SOURCE) 295 @Retention(RetentionPolicy.SOURCE)
212 @SuppressWarnings("DepAnn") 296 @SuppressWarnings("DepAnn")
213 public @interface HttpCacheSetting {} 297 public @interface HttpCacheSetting {}
214 298
215 /** 299 /**
216 * Setting to disable HTTP cache. Some data may still be temporarily sto red in memory. 300 * Setting to disable HTTP cache. Some data may still be temporarily sto red in memory.
(...skipping 25 matching lines...) Expand all
242 * Enables or disables caching of HTTP data and other information like Q UIC 326 * Enables or disables caching of HTTP data and other information like Q UIC
243 * server information. 327 * server information.
244 * @param cacheMode control location and type of cached data. Must be on e of 328 * @param cacheMode control location and type of cached data. Must be on e of
245 * {@link #HTTP_CACHE_DISABLED HTTP_CACHE_*}. 329 * {@link #HTTP_CACHE_DISABLED HTTP_CACHE_*}.
246 * @param maxSize maximum size in bytes used to cache data (advisory and maybe 330 * @param maxSize maximum size in bytes used to cache data (advisory and maybe
247 * exceeded at times). 331 * exceeded at times).
248 * @return the builder to facilitate chaining. 332 * @return the builder to facilitate chaining.
249 */ 333 */
250 public Builder enableHttpCache(@HttpCacheSetting int cacheMode, long max Size) { 334 public Builder enableHttpCache(@HttpCacheSetting int cacheMode, long max Size) {
251 if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_ HTTP) { 335 if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_ HTTP) {
252 if (storagePath().isEmpty()) { 336 if (storagePath() == null) {
253 throw new IllegalArgumentException("Storage path must be set "); 337 throw new IllegalArgumentException("Storage path must be set ");
254 } 338 }
255 } else { 339 } else {
256 if (!storagePath().isEmpty()) { 340 if (storagePath() != null) {
257 throw new IllegalArgumentException("Storage path must be emp ty"); 341 throw new IllegalArgumentException("Storage path must not be set");
258 } 342 }
259 } 343 }
260 putBoolean(CronetEngineBuilderList.LOAD_DISABLE_CACHE, 344 mDisableCache =
261 cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_ DISK_NO_HTTP); 345 (cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE _DISK_NO_HTTP);
262 putLong(CronetEngineBuilderList.HTTP_CACHE_MAX_SIZE, maxSize); 346 mHttpCacheMaxSize = maxSize;
263 347
264 switch (cacheMode) { 348 switch (cacheMode) {
265 case HTTP_CACHE_DISABLED: 349 case HTTP_CACHE_DISABLED:
266 return putString(CronetEngineBuilderList.HTTP_CACHE, 350 mHttpCacheMode = HttpCacheType.DISABLED;
267 CronetEngineBuilderList.HTTP_CACHE_DISABLED); 351 break;
268 case HTTP_CACHE_DISK_NO_HTTP: 352 case HTTP_CACHE_DISK_NO_HTTP:
269 case HTTP_CACHE_DISK: 353 case HTTP_CACHE_DISK:
270 return putString(CronetEngineBuilderList.HTTP_CACHE, 354 mHttpCacheMode = HttpCacheType.DISK;
271 CronetEngineBuilderList.HTTP_CACHE_DISK); 355 break;
272
273 case HTTP_CACHE_IN_MEMORY: 356 case HTTP_CACHE_IN_MEMORY:
274 return putString(CronetEngineBuilderList.HTTP_CACHE, 357 mHttpCacheMode = HttpCacheType.MEMORY;
275 CronetEngineBuilderList.HTTP_CACHE_MEMORY); 358 break;
359 default:
360 throw new IllegalArgumentException("Unknown cache mode");
276 } 361 }
277 return this; 362 return this;
278 } 363 }
279 364
365 boolean cacheDisabled() {
366 return mDisableCache;
367 }
368
369 long httpCacheMaxSize() {
370 return mHttpCacheMaxSize;
371 }
372
373 int httpCacheMode() {
374 return mHttpCacheMode;
375 }
376
280 /** 377 /**
281 * Adds hint that {@code host} supports QUIC. 378 * Adds hint that {@code host} supports QUIC.
282 * Note that {@link #enableHttpCache enableHttpCache} 379 * Note that {@link #enableHttpCache enableHttpCache}
283 * ({@link #HTTP_CACHE_DISK}) is needed to take advantage of 0-RTT 380 * ({@link #HTTP_CACHE_DISK}) is needed to take advantage of 0-RTT
284 * connection establishment between sessions. 381 * connection establishment between sessions.
285 * 382 *
286 * @param host hostname of the server that supports QUIC. 383 * @param host hostname of the server that supports QUIC.
287 * @param port host of the server that supports QUIC. 384 * @param port host of the server that supports QUIC.
288 * @param alternatePort alternate port to use for QUIC. 385 * @param alternatePort alternate port to use for QUIC.
289 * @return the builder to facilitate chaining. 386 * @return the builder to facilitate chaining.
290 */ 387 */
291 public Builder addQuicHint(String host, int port, int alternatePort) { 388 public Builder addQuicHint(String host, int port, int alternatePort) {
292 if (host.contains("/")) { 389 if (host.contains("/")) {
293 throw new IllegalArgumentException("Illegal QUIC Hint Host: " + host); 390 throw new IllegalArgumentException("Illegal QUIC Hint Host: " + host);
294 } 391 }
295 try { 392 mQuicHints.add(new QuicHint(host, port, alternatePort));
296 JSONArray quicHints = mConfig.optJSONArray(CronetEngineBuilderLi st.QUIC_HINTS); 393 return this;
297 if (quicHints == null) { 394 }
298 quicHints = new JSONArray();
299 mConfig.put(CronetEngineBuilderList.QUIC_HINTS, quicHints);
300 }
301 395
302 JSONObject hint = new JSONObject(); 396 List<QuicHint> quicHints() {
303 hint.put(CronetEngineBuilderList.QUIC_HINT_HOST, host); 397 return mQuicHints;
304 hint.put(CronetEngineBuilderList.QUIC_HINT_PORT, port);
305 hint.put(CronetEngineBuilderList.QUIC_HINT_ALT_PORT, alternatePo rt);
306 quicHints.put(hint);
307 } catch (JSONException e) {
308 // Intentionally do nothing.
309 }
310 return this;
311 } 398 }
312 399
313 /** 400 /**
314 * <p> 401 * <p>
315 * Pins a set of public keys for a given host. By pinning a set of publi c keys, 402 * Pins a set of public keys for a given host. By pinning a set of publi c keys,
316 * {@code pinsSha256}, communication with {@code hostName} is required t o 403 * {@code pinsSha256}, communication with {@code hostName} is required t o
317 * authenticate with a certificate with a public key from the set of pin ned ones. 404 * authenticate with a certificate with a public key from the set of pin ned ones.
318 * An app can pin the public key of the root certificate, any of the int ermediate 405 * An app can pin the public key of the root certificate, any of the int ermediate
319 * certificates or the end-entry certificate. Authentication will fail a nd secure 406 * certificates or the end-entry certificate. Authentication will fail a nd secure
320 * communication will not be established if none of the public keys is p resent in the 407 * communication will not be established if none of the public keys is p resent in the
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 if (hostName == null) { 443 if (hostName == null) {
357 throw new NullPointerException("The hostname cannot be null"); 444 throw new NullPointerException("The hostname cannot be null");
358 } 445 }
359 if (pinsSha256 == null) { 446 if (pinsSha256 == null) {
360 throw new NullPointerException("The set of SHA256 pins cannot be null"); 447 throw new NullPointerException("The set of SHA256 pins cannot be null");
361 } 448 }
362 if (expirationDate == null) { 449 if (expirationDate == null) {
363 throw new NullPointerException("The pin expiration date cannot b e null"); 450 throw new NullPointerException("The pin expiration date cannot b e null");
364 } 451 }
365 String idnHostName = validateHostNameForPinningAndConvert(hostName); 452 String idnHostName = validateHostNameForPinningAndConvert(hostName);
366 try { 453 // Convert the pin to BASE64 encoding. The hash set will eliminate d uplications.
367 // Add PKP_LIST JSON array element if it is not present. 454 Set<byte[]> hashes = new HashSet<>(pinsSha256.size());
368 JSONArray pkpList = mConfig.optJSONArray(CronetEngineBuilderList .PKP_LIST); 455 for (byte[] pinSha256 : pinsSha256) {
369 if (pkpList == null) { 456 if (pinSha256 == null || pinSha256.length != 32) {
370 pkpList = new JSONArray(); 457 throw new IllegalArgumentException("Public key pin is invali d");
371 mConfig.put(CronetEngineBuilderList.PKP_LIST, pkpList);
372 } 458 }
373 459 hashes.add(pinSha256);
374 // Convert the pin to BASE64 encoding. The hash set will elimina te duplications.
375 Set<String> hashes = new HashSet<>(pinsSha256.size());
376 for (byte[] pinSha256 : pinsSha256) {
377 hashes.add(convertSha256ToBase64WithPrefix(pinSha256));
378 }
379
380 // Add new element to PKP_LIST JSON array.
381 JSONObject pkp = new JSONObject();
382 pkp.put(CronetEngineBuilderList.PKP_HOST, idnHostName);
383 pkp.put(CronetEngineBuilderList.PKP_PIN_HASHES, new JSONArray(ha shes));
384 pkp.put(CronetEngineBuilderList.PKP_INCLUDE_SUBDOMAINS, includeS ubdomains);
385 // The expiration time is passed as a double, in seconds since J anuary 1, 1970.
386 pkp.put(CronetEngineBuilderList.PKP_EXPIRATION_DATE,
387 (double) expirationDate.getTime() / 1000);
388 pkpList.put(pkp);
389 } catch (JSONException e) {
390 // This exception should never happen.
391 throw new RuntimeException(
392 "Failed to add pubic key pins with the given arguments", e);
393 } 460 }
461 // Add new element to PKP list.
462 mPkps.add(new Pkp(idnHostName, hashes.toArray(new byte[hashes.size() ][]),
463 includeSubdomains, expirationDate));
394 return this; 464 return this;
395 } 465 }
396 466
397 /** 467 /**
398 * Converts a given SHA256 array of bytes to BASE64 encoded string and p repends 468 * Returns list of public key pins.
399 * {@code sha256/} prefix to it. The format corresponds to the format th at is expected by
400 * {@code net::HashValue} class.
401 *
402 * @param sha256 SHA256 bytes to convert to BASE64.
403 * @return the BASE64 encoded SHA256 with the prefix.
404 * @throws IllegalArgumentException if the provided pin is invalid.
405 */ 469 */
406 private static String convertSha256ToBase64WithPrefix(byte[] sha256) { 470 List<Pkp> publicKeyPins() {
407 if (sha256 == null || sha256.length != 32) { 471 return mPkps;
408 throw new IllegalArgumentException("Public key pin is invalid");
409 }
410 return "sha256/" + Base64.encodeToString(sha256, Base64.NO_WRAP);
411 } 472 }
412 473
413 /** 474 /**
414 * Checks whether a given string represents a valid host name for PKP an d converts it 475 * Checks whether a given string represents a valid host name for PKP an d converts it
415 * to ASCII Compatible Encoding representation according to RFC 1122, RF C 1123 and 476 * to ASCII Compatible Encoding representation according to RFC 1122, RF C 1123 and
416 * RFC 3490. This method is more restrictive than required by RFC 7469. Thus, a host 477 * RFC 3490. This method is more restrictive than required by RFC 7469. Thus, a host
417 * that contains digits and the dot character only is considered invalid . 478 * that contains digits and the dot character only is considered invalid .
418 * 479 *
419 * Note: Currently Cronet doesn't have native implementation of host nam e validation that 480 * Note: Currently Cronet doesn't have native implementation of host nam e validation that
420 * can be used. There is code that parses a provided URL but doesn 't ensure its 481 * can be used. There is code that parses a provided URL but doesn 't ensure its
(...skipping 18 matching lines...) Expand all
439 } 500 }
440 } 501 }
441 502
442 /** 503 /**
443 * Sets experimental options to be used in Cronet. 504 * Sets experimental options to be used in Cronet.
444 * 505 *
445 * @param options JSON formatted experimental options. 506 * @param options JSON formatted experimental options.
446 * @return the builder to facilitate chaining. 507 * @return the builder to facilitate chaining.
447 */ 508 */
448 public Builder setExperimentalOptions(String options) { 509 public Builder setExperimentalOptions(String options) {
449 return putString(CronetEngineBuilderList.EXPERIMENTAL_OPTIONS, optio ns); 510 mExperimentalOptions = options;
511 return this;
512 }
513
514 String experimentalOptions() {
515 return mExperimentalOptions;
450 } 516 }
451 517
452 /** 518 /**
453 * Sets a native MockCertVerifier for testing. 519 * Sets a native MockCertVerifier for testing.
454 */ 520 */
455 Builder setMockCertVerifierForTesting(long mockCertVerifier) { 521 Builder setMockCertVerifierForTesting(long mockCertVerifier) {
456 return putString( 522 mMockCertVerifier = mockCertVerifier;
457 CronetEngineBuilderList.MOCK_CERT_VERIFIER, String.valueOf(m ockCertVerifier)); 523 return this;
524 }
525
526 long mockCertVerifier() {
527 return mMockCertVerifier;
458 } 528 }
459 529
460 /** 530 /**
461 * Gets a JSON string representation of the builder.
462 */
463 String toJSONString() {
464 return mConfig.toString();
465 }
466
467 /**
468 * Returns {@link Context} for builder. 531 * Returns {@link Context} for builder.
469 * 532 *
470 * @return {@link Context} for builder. 533 * @return {@link Context} for builder.
471 */ 534 */
472 Context getContext() { 535 Context getContext() {
473 return mContext; 536 return mContext;
474 } 537 }
475 538
476 /** 539 /**
477 * Sets a boolean value in the config. Returns a reference to the same
478 * config object, so you can chain put calls together.
479 * @return the builder to facilitate chaining.
480 */
481 private Builder putBoolean(String key, boolean value) {
482 try {
483 mConfig.put(key, value);
484 } catch (JSONException e) {
485 // Intentionally do nothing.
486 }
487 return this;
488 }
489
490 /**
491 * Sets a long value in the config. Returns a reference to the same
492 * config object, so you can chain put calls together.
493 * @return the builder to facilitate chaining.
494 */
495 private Builder putLong(String key, long value) {
496 try {
497 mConfig.put(key, value);
498 } catch (JSONException e) {
499 // Intentionally do nothing.
500 }
501 return this;
502 }
503
504 /**
505 * Sets a string value in the config. Returns a reference to the same
506 * config object, so you can chain put calls together.
507 * @return the builder to facilitate chaining.
508 */
509 private Builder putString(String key, String value) {
510 try {
511 mConfig.put(key, value);
512 } catch (JSONException e) {
513 // Intentionally do nothing.
514 }
515 return this;
516 }
517
518 /**
519 * Build a {@link CronetEngine} using this builder's configuration. 540 * Build a {@link CronetEngine} using this builder's configuration.
520 */ 541 */
521 public CronetEngine build() { 542 public CronetEngine build() {
522 CronetEngine engine = createContext(this); 543 CronetEngine engine = createContext(this);
523 // Clear MOCK_CERT_VERIFIER reference if there is any, since 544 // Clear MOCK_CERT_VERIFIER reference if there is any, since
524 // the ownership has been transferred to the engine. 545 // the ownership has been transferred to the engine.
525 mConfig.remove(CronetEngineBuilderList.MOCK_CERT_VERIFIER); 546 mMockCertVerifier = 0;
526 return engine; 547 return engine;
527 } 548 }
528 } 549 }
529 550
530 private static final String TAG = "UrlRequestFactory"; 551 private static final String TAG = "UrlRequestFactory";
531 private static final String CRONET_URL_REQUEST_CONTEXT = 552 private static final String CRONET_URL_REQUEST_CONTEXT =
532 "org.chromium.net.CronetUrlRequestContext"; 553 "org.chromium.net.CronetUrlRequestContext";
533 554
534 /** 555 /**
535 * Creates a {@link UrlRequest} object. All callbacks will 556 * Creates a {@link UrlRequest} object. All callbacks will
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 /** 812 /**
792 * Creates a {@link CronetEngine} with the given {@link Builder}. 813 * Creates a {@link CronetEngine} with the given {@link Builder}.
793 * 814 *
794 * @param builder builder to used for creating the CronetEngine instance. 815 * @param builder builder to used for creating the CronetEngine instance.
795 * @return the created CronetEngine instance. 816 * @return the created CronetEngine instance.
796 * @deprecated Use {@link CronetEngine.Builder}. 817 * @deprecated Use {@link CronetEngine.Builder}.
797 */ 818 */
798 @Deprecated 819 @Deprecated
799 public static CronetEngine createContext(Builder builder) { 820 public static CronetEngine createContext(Builder builder) {
800 CronetEngine cronetEngine = null; 821 CronetEngine cronetEngine = null;
801 if (builder.getUserAgent().isEmpty()) { 822 if (builder.getUserAgent() == null) {
802 builder.setUserAgent(builder.getDefaultUserAgent()); 823 builder.setUserAgent(builder.getDefaultUserAgent());
803 } 824 }
804 if (!builder.legacyMode()) { 825 if (!builder.legacyMode()) {
805 cronetEngine = createCronetEngine(builder); 826 cronetEngine = createCronetEngine(builder);
806 } 827 }
807 if (cronetEngine == null) { 828 if (cronetEngine == null) {
808 // TODO(mef): Fallback to stub implementation. Once stub 829 // TODO(mef): Fallback to stub implementation. Once stub
809 // implementation is available merge with createCronetFactory. 830 // implementation is available merge with createCronetFactory.
810 cronetEngine = createCronetEngine(builder); 831 cronetEngine = createCronetEngine(builder);
811 } 832 }
(...skipping 15 matching lines...) Expand all
827 cronetEngine = possibleEngine; 848 cronetEngine = possibleEngine;
828 } 849 }
829 } catch (ClassNotFoundException e) { 850 } catch (ClassNotFoundException e) {
830 // Leave as null. 851 // Leave as null.
831 } catch (Exception e) { 852 } catch (Exception e) {
832 throw new IllegalStateException("Cannot instantiate: " + CRONET_URL_ REQUEST_CONTEXT, e); 853 throw new IllegalStateException("Cannot instantiate: " + CRONET_URL_ REQUEST_CONTEXT, e);
833 } 854 }
834 return cronetEngine; 855 return cronetEngine;
835 } 856 }
836 } 857 }
OLDNEW
« no previous file with comments | « components/cronet.gypi ('k') | components/cronet/android/api/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698