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

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

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