summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxunjieli <xunjieli@chromium.org>2015-04-29 10:36:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-29 17:36:59 +0000
commitb8a6d56ffe39823af7b09ce6b816d3cd9fbac2a6 (patch)
tree60e0bafa48d564006038b39606871f82632337b5
parente9ac6f320030c764af9dca7f662d2f828c1aa223 (diff)
downloadchromium_src-b8a6d56ffe39823af7b09ce6b816d3cd9fbac2a6.zip
chromium_src-b8a6d56ffe39823af7b09ce6b816d3cd9fbac2a6.tar.gz
chromium_src-b8a6d56ffe39823af7b09ce6b816d3cd9fbac2a6.tar.bz2
Enable sdch in Cronet
This CL combined rdsmith@'s CL(747453004) and mef@'s CL(1073193002), and added tests to make sure sdch works for both the old and the new API. BUG=414885 Review URL: https://codereview.chromium.org/1085903002 Cr-Commit-Position: refs/heads/master@{#327517}
-rw-r--r--components/cronet/android/chromium_url_request.cc11
-rw-r--r--components/cronet/android/cronet_url_request_context_adapter.cc7
-rw-r--r--components/cronet/android/cronet_url_request_context_adapter.h2
-rw-r--r--components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java11
-rw-r--r--components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java10
-rw-r--r--components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java2
-rw-r--r--components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequest.java5
-rw-r--r--components/cronet/android/java/src/org/chromium/net/HttpUrlRequest.java5
-rw-r--r--components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java11
-rw-r--r--components/cronet/android/test/assets/test/sdch/LeQxM80O_encodedbin0 -> 33 bytes
-rw-r--r--components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded.mock-http-headers3
-rw-r--r--components/cronet/android/test/assets/test/sdch/dict/LeQxM80O4
-rw-r--r--components/cronet/android/test/assets/test/sdch/dict/LeQxM80O.mock-http-headers3
-rw-r--r--components/cronet/android/test/assets/test/sdch/index1
-rw-r--r--components/cronet/android/test/assets/test/sdch/index.mock-http-headers2
-rw-r--r--components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java218
-rw-r--r--components/cronet/android/test/javatests/src/org/chromium/net/TestHttpUrlRequestListener.java2
-rw-r--r--components/cronet/android/test/native_test_server.cc194
-rw-r--r--components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java8
-rw-r--r--components/cronet/android/test/src/org/chromium/net/NativeTestServer.java29
-rw-r--r--components/cronet/android/url_request_adapter.cc6
-rw-r--r--components/cronet/android/url_request_adapter.h3
-rw-r--r--components/cronet/android/url_request_context_adapter.cc7
-rw-r--r--components/cronet/android/url_request_context_adapter.h5
-rw-r--r--components/cronet/url_request_context_config.cc3
-rw-r--r--components/cronet/url_request_context_config.h2
-rw-r--r--components/cronet/url_request_context_config_list.h1
-rw-r--r--net/url_request/url_request_context_builder.cc9
-rw-r--r--net/url_request/url_request_context_builder.h9
29 files changed, 543 insertions, 30 deletions
diff --git a/components/cronet/android/chromium_url_request.cc b/components/cronet/android/chromium_url_request.cc
index 2da0ccc..140e476 100644
--- a/components/cronet/android/chromium_url_request.cc
+++ b/components/cronet/android/chromium_url_request.cc
@@ -400,6 +400,17 @@ static jstring GetNegotiatedProtocol(JNIEnv* env,
return ConvertUTF8ToJavaString(env, negotiated_protocol.c_str()).Release();
}
+static jboolean GetWasCached(JNIEnv* env,
+ jobject jcaller,
+ jlong jurl_request_adapter) {
+ URLRequestAdapter* request_adapter =
+ reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
+ DCHECK(request_adapter);
+
+ bool was_cached = request_adapter->GetWasCached();
+ return was_cached ? JNI_TRUE : JNI_FALSE;
+}
+
static void DisableRedirects(JNIEnv* env, jobject jcaller,
jlong jrequest_adapter) {
URLRequestAdapter* request_adapter =
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc
index 6553f1e..3ee0c7e 100644
--- a/components/cronet/android/cronet_url_request_context_adapter.cc
+++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -20,6 +20,7 @@
#include "net/http/http_auth_handler_factory.h"
#include "net/log/write_to_file_net_log_observer.h"
#include "net/proxy/proxy_service.h"
+#include "net/sdch/sdch_owner.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
@@ -161,6 +162,12 @@ void CronetURLRequestContextAdapter::InitializeOnNetworkThread(
if (config->load_disable_cache)
default_load_flags_ |= net::LOAD_DISABLE_CACHE;
+ if (config->enable_sdch) {
+ DCHECK(context_->sdch_manager());
+ sdch_owner_.reset(
+ new net::SdchOwner(context_->sdch_manager(), context_.get()));
+ }
+
// Currently (circa M39) enabling QUIC requires setting probability threshold.
if (config->enable_quic) {
context_->http_server_properties()
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h
index fea2454..7319733 100644
--- a/components/cronet/android/cronet_url_request_context_adapter.h
+++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -25,6 +25,7 @@ namespace net {
class WriteToFileNetLogObserver;
class URLRequestContext;
class ProxyConfigService;
+class SdchOwner;
} // namespace net
namespace cronet {
@@ -91,6 +92,7 @@ class CronetURLRequestContextAdapter {
scoped_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;
scoped_ptr<net::URLRequestContext> context_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
+ scoped_ptr<net::SdchOwner> sdch_owner_;
// Context config is only valid untng context is initialized.
scoped_ptr<URLRequestContextConfig> context_config_;
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
index 6372a60..afccf84 100644
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
@@ -422,6 +422,15 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
}
@Override
+ public boolean wasCached() {
+ synchronized (mLock) {
+ validateNativeAdapterNotDestroyed();
+ validateHeadersAvailable();
+ return nativeGetWasCached(mUrlRequestAdapter);
+ }
+ }
+
+ @Override
public String getContentType() {
return mContentType;
}
@@ -748,6 +757,8 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
private native String nativeGetNegotiatedProtocol(long urlRequestAdapter);
+ private native boolean nativeGetWasCached(long urlRequestAdapter);
+
// Explicit class to work around JNI-generator generics confusion.
private static class ResponseHeadersMap extends
HashMap<String, List<String>> {
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
index 03246f4..e7f7968 100644
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
@@ -12,6 +12,7 @@ import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
+import org.chromium.base.VisibleForTesting;
/**
* Provides context for the native HTTP operations.
@@ -95,6 +96,15 @@ public class ChromiumUrlRequestContext {
nativeStopNetLog(mChromiumUrlRequestContextAdapter);
}
+ /**
+ * Returns the native URLRequestContextAdapter pointer.
+ * Currently this method is only used in testing.
+ */
+ @VisibleForTesting
+ long getUrlRequestContextAdapterForTesting() {
+ return mChromiumUrlRequestContextAdapter;
+ }
+
@CalledByNative
private void initNetworkThread() {
Thread.currentThread().setName("ChromiumNet");
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
index 78d3bee..aa2b635 100644
--- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
@@ -15,6 +15,7 @@ import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.NativeClassQualifiedName;
+import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.UsedByReflection;
import java.util.concurrent.Executor;
@@ -152,6 +153,7 @@ public class CronetUrlRequestContext extends UrlRequestContext {
mActiveRequestCount.decrementAndGet();
}
+ @VisibleForTesting
long getUrlRequestContextAdapter() {
synchronized (mLock) {
checkHaveAdapter();
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequest.java
index f2e25f2..88e97ea 100644
--- a/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequest.java
@@ -434,6 +434,11 @@ class HttpUrlConnectionUrlRequest implements HttpUrlRequest {
}
@Override
+ public boolean wasCached() {
+ return false;
+ }
+
+ @Override
public int getHttpStatusCode() {
int httpStatusCode = mHttpStatusCode;
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequest.java
index 1a39a46..a8a943d 100644
--- a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequest.java
@@ -114,6 +114,11 @@ public interface HttpUrlRequest {
String getNegotiatedProtocol();
/**
+ * Returns whether the response is serviced from the cache.
+ */
+ boolean wasCached();
+
+ /**
* Returns the entire response as a ByteBuffer.
*/
ByteBuffer getByteBuffer();
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java b/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java
index 810ce12..32b442a 100644
--- a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java
+++ b/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java
@@ -15,14 +15,14 @@ import java.io.File;
* UrlRequestContext.
*/
public class UrlRequestContextConfig {
-
/**
- * Default config enables SPDY, QUIC, in memory http cache.
+ * Default config enables SPDY, disables QUIC, SDCH and http cache.
*/
public UrlRequestContextConfig() {
enableLegacyMode(false);
enableQUIC(false);
enableSPDY(true);
+ enableSDCH(false);
enableHttpCache(HttpCache.DISABLED, 0);
}
@@ -102,6 +102,13 @@ public class UrlRequestContextConfig {
}
/**
+ * Boolean, enable SDCH compression if true.
+ */
+ public UrlRequestContextConfig enableSDCH(boolean value) {
+ return putBoolean(UrlRequestContextConfigList.ENABLE_SDCH, value);
+ }
+
+ /**
* Enumeration, disable or enable cache in memory or on disk.
*/
public enum HttpCache {
diff --git a/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded b/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded
new file mode 100644
index 0000000..ae6d433
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded
Binary files differ
diff --git a/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded.mock-http-headers b/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded.mock-http-headers
new file mode 100644
index 0000000..11453b9
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/LeQxM80O_encoded.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: text/plain
+Content-Encoding: sdch
diff --git a/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O b/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O
new file mode 100644
index 0000000..ab9a35e
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O
@@ -0,0 +1,4 @@
+Domain: fake.sdch.domain
+Path: /sdch/test
+
+The quick brown fox jumps over the lazy dog.\n
diff --git a/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O.mock-http-headers b/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O.mock-http-headers
new file mode 100644
index 0000000..691e413
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/dict/LeQxM80O.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Cache-Control: public, max-age=31536000
+Content-Type: application/x-sdch-dictionary
diff --git a/components/cronet/android/test/assets/test/sdch/index b/components/cronet/android/test/assets/test/sdch/index
new file mode 100644
index 0000000..e0638b6
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/index
@@ -0,0 +1 @@
+This is an index page.
diff --git a/components/cronet/android/test/assets/test/sdch/index.mock-http-headers b/components/cronet/android/test/assets/test/sdch/index.mock-http-headers
new file mode 100644
index 0000000..5c695b9
--- /dev/null
+++ b/components/cronet/android/test/assets/test/sdch/index.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Content-Type: text/plain
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
new file mode 100644
index 0000000..18c3d72
--- /dev/null
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
@@ -0,0 +1,218 @@
+// Copyright 2015 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 android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests Sdch support.
+ */
+public class SdchTest extends CronetTestBase {
+ private CronetTestActivity mActivity;
+
+ private void setUp(boolean enableSdch) {
+ UrlRequestContextConfig config = new UrlRequestContextConfig();
+ config.enableSDCH(enableSdch);
+ config.setLibraryName("cronet_tests");
+ config.enableHttpCache(UrlRequestContextConfig.HttpCache.IN_MEMORY, 100 * 1024);
+ String[] commandLineArgs = {CronetTestActivity.CONFIG_KEY, config.toString()};
+ mActivity = launchCronetTestAppWithUrlAndCommandLineArgs(null, commandLineArgs);
+ mActivity.startNetLog();
+
+ // Registers custom DNS mapping for legacy ChromiumUrlRequestFactory.
+ ChromiumUrlRequestFactory factory = (ChromiumUrlRequestFactory) mActivity.mRequestFactory;
+ long legacyAdapter = factory.getRequestContext().getUrlRequestContextAdapterForTesting();
+ assertTrue(legacyAdapter != 0);
+ NativeTestServer.registerHostResolverProc(legacyAdapter, true);
+
+ // Registers custom DNS mapping for CronetUrlRequestContext.
+ CronetUrlRequestContext requestContext =
+ (CronetUrlRequestContext) mActivity.mUrlRequestContext;
+ long adapter = requestContext.getUrlRequestContextAdapter();
+ assertTrue(adapter != 0);
+ NativeTestServer.registerHostResolverProc(adapter, false);
+
+ // Starts NativeTestServer.
+ assertTrue(NativeTestServer.startNativeTestServer(getInstrumentation().getTargetContext()));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ NativeTestServer.shutdownNativeTestServer();
+ mActivity.stopNetLog();
+ super.tearDown();
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testSdchEnabled_LegacyAPI() throws Exception {
+ setUp(true);
+ // Make a request to /sdch/index which advertises the dictionary.
+ TestHttpUrlRequestListener listener1 = startAndWaitForComplete_LegacyAPI(
+ NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O");
+ assertEquals(200, listener1.mHttpStatusCode);
+ assertEquals("This is an index page.\n", listener1.mResponseAsString);
+ assertEquals(Arrays.asList("/sdch/dict/LeQxM80O"),
+ listener1.mResponseHeaders.get("Get-Dictionary"));
+
+ waitForDictionaryAdded("LeQxM80O", true);
+
+ // Make a request to fetch encoded response at /sdch/test.
+ TestHttpUrlRequestListener listener2 =
+ startAndWaitForComplete_LegacyAPI(NativeTestServer.getSdchURL() + "/sdch/test");
+ assertEquals(200, listener2.mHttpStatusCode);
+ assertEquals("The quick brown fox jumps over the lazy dog.\n", listener2.mResponseAsString);
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testSdchDisabled_LegacyAPI() throws Exception {
+ setUp(false);
+ // Make a request to /sdch/index.
+ // Since Sdch is not enabled, no dictionary should be advertised.
+ TestHttpUrlRequestListener listener = startAndWaitForComplete_LegacyAPI(
+ NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O");
+ assertEquals(200, listener.mHttpStatusCode);
+ assertEquals("This is an index page.\n", listener.mResponseAsString);
+ assertEquals(null, listener.mResponseHeaders.get("Get-Dictionary"));
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testDictionaryNotFound_LegacyAPI() throws Exception {
+ setUp(true);
+ // Make a request to /sdch/index which advertises a bad dictionary that
+ // does not exist.
+ TestHttpUrlRequestListener listener1 = startAndWaitForComplete_LegacyAPI(
+ NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound");
+ assertEquals(200, listener1.mHttpStatusCode);
+ assertEquals("This is an index page.\n", listener1.mResponseAsString);
+ assertEquals(Arrays.asList("/sdch/dict/NotFound"),
+ listener1.mResponseHeaders.get("Get-Dictionary"));
+
+ waitForDictionaryAdded("NotFound", true);
+
+ // Make a request to fetch /sdch/test, and make sure Sdch encoding is not used.
+ TestHttpUrlRequestListener listener2 =
+ startAndWaitForComplete_LegacyAPI(NativeTestServer.getSdchURL() + "/sdch/test");
+ assertEquals(200, listener2.mHttpStatusCode);
+ assertEquals("Sdch is not used.\n", listener2.mResponseAsString);
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testSdchEnabled() throws Exception {
+ setUp(true);
+ // Make a request to /sdch which advertises the dictionary.
+ TestUrlRequestListener listener1 =
+ startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O");
+ assertEquals(200, listener1.mResponseInfo.getHttpStatusCode());
+ assertEquals("This is an index page.\n", listener1.mResponseAsString);
+ assertEquals(Arrays.asList("/sdch/dict/LeQxM80O"),
+ listener1.mResponseInfo.getAllHeaders().get("Get-Dictionary"));
+
+ waitForDictionaryAdded("LeQxM80O", false);
+
+ // Make a request to fetch encoded response at /sdch/test.
+ TestUrlRequestListener listener2 =
+ startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/test");
+ assertEquals(200, listener1.mResponseInfo.getHttpStatusCode());
+ assertEquals("The quick brown fox jumps over the lazy dog.\n", listener2.mResponseAsString);
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testSdchDisabled() throws Exception {
+ setUp(false);
+ // Make a request to /sdch.
+ // Since Sdch is not enabled, no dictionary should be advertised.
+ TestUrlRequestListener listener =
+ startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O");
+ assertEquals(200, listener.mResponseInfo.getHttpStatusCode());
+ assertEquals("This is an index page.\n", listener.mResponseAsString);
+ assertEquals(null, listener.mResponseInfo.getAllHeaders().get("Get-Dictionary"));
+ }
+
+ @SmallTest
+ @Feature({"Cronet"})
+ public void testDictionaryNotFound() throws Exception {
+ setUp(true);
+ // Make a request to /sdch/index which advertises a bad dictionary that
+ // does not exist.
+ TestUrlRequestListener listener1 =
+ startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound");
+ assertEquals(200, listener1.mResponseInfo.getHttpStatusCode());
+ assertEquals("This is an index page.\n", listener1.mResponseAsString);
+ assertEquals(Arrays.asList("/sdch/dict/NotFound"),
+ listener1.mResponseInfo.getAllHeaders().get("Get-Dictionary"));
+
+ waitForDictionaryAdded("NotFound", false);
+
+ // Make a request to fetch /sdch/test, and make sure Sdch encoding is not used.
+ TestUrlRequestListener listener2 =
+ startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/test");
+ assertEquals(200, listener2.mResponseInfo.getHttpStatusCode());
+ assertEquals("Sdch is not used.\n", listener2.mResponseAsString);
+ }
+
+ /**
+ * Helper method to wait for dictionary to be fetched and added to the list of available
+ * dictionaries.
+ */
+ private void waitForDictionaryAdded(String dict, boolean isLegacyAPI) throws Exception {
+ // Since Http cache is enabled, making a request to the dictionary explicitly will
+ // be served from the cache.
+ String url = NativeTestServer.getSdchURL() + "/sdch/dict/" + dict;
+ if (isLegacyAPI) {
+ TestHttpUrlRequestListener listener = startAndWaitForComplete_LegacyAPI(url);
+ if (dict.equals("NotFound")) {
+ assertEquals(404, listener.mHttpStatusCode);
+ } else {
+ assertEquals(200, listener.mHttpStatusCode);
+ assertTrue(listener.mWasCached);
+ }
+ } else {
+ TestUrlRequestListener listener = startAndWaitForComplete(url);
+ if (dict.equals("NotFound")) {
+ assertEquals(404, listener.mResponseInfo.getHttpStatusCode());
+ } else {
+ assertEquals(200, listener.mResponseInfo.getHttpStatusCode());
+ assertTrue(listener.mResponseInfo.wasCached());
+ }
+ }
+ // Now wait for dictionary to be added to the manager, which occurs
+ // asynchronously.
+ // TODO(xunjieli): Rather than setting an arbitrary delay, consider
+ // implementing a SdchObserver to watch for dictionary add events once
+ // add event is implemented in SdchObserver.
+ Thread.sleep(1000);
+ }
+
+ private TestHttpUrlRequestListener startAndWaitForComplete_LegacyAPI(String url)
+ throws Exception {
+ Map<String, String> headers = new HashMap<String, String>();
+ TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener();
+ HttpUrlRequest request = mActivity.mRequestFactory.createRequest(
+ url, HttpUrlRequest.REQUEST_PRIORITY_MEDIUM, headers, listener);
+ request.start();
+ listener.blockForComplete();
+ return listener;
+ }
+
+ private TestUrlRequestListener startAndWaitForComplete(String url) throws Exception {
+ TestUrlRequestListener listener = new TestUrlRequestListener();
+ UrlRequest request =
+ mActivity.mUrlRequestContext.createRequest(url, listener, listener.getExecutor());
+ request.start();
+ listener.blockForDone();
+ return listener;
+ }
+}
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/TestHttpUrlRequestListener.java b/components/cronet/android/test/javatests/src/org/chromium/net/TestHttpUrlRequestListener.java
index 44eec34..592575e 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/TestHttpUrlRequestListener.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/TestHttpUrlRequestListener.java
@@ -26,6 +26,7 @@ public class TestHttpUrlRequestListener implements HttpUrlRequestListener {
public String mResponseAsString;
public Exception mException;
public Map<String, List<String>> mResponseHeaders;
+ public boolean mWasCached = false;
private final ConditionVariable mStarted = new ConditionVariable();
private final ConditionVariable mComplete = new ConditionVariable();
@@ -42,6 +43,7 @@ public class TestHttpUrlRequestListener implements HttpUrlRequestListener {
mHttpStatusText = request.getHttpStatusText();
mNegotiatedProtocol = request.getNegotiatedProtocol();
mResponseHeaders = request.getAllHeaders();
+ mWasCached = request.wasCached();
mStarted.open();
}
diff --git a/components/cronet/android/test/native_test_server.cc b/components/cronet/android/test/native_test_server.cc
index 9726164..ce8c951 100644
--- a/components/cronet/android/test/native_test_server.cc
+++ b/components/cronet/android/test/native_test_server.cc
@@ -4,14 +4,25 @@
#include "native_test_server.h"
+#include <string>
+
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
+#include "base/android/path_utils.h"
#include "base/bind.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "components/cronet/android/cronet_url_request_context_adapter.h"
+#include "components/cronet/android/url_request_context_adapter.h"
#include "jni/NativeTestServer_jni.h"
+#include "net/base/url_util.h"
+#include "net/dns/host_resolver_impl.h"
+#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
@@ -22,22 +33,66 @@ namespace cronet {
namespace {
-const char echo_body_path[] = "/echo_body";
-const char echo_header_path[] = "/echo_header";
-const char echo_all_headers_path[] = "/echo_all_headers";
-const char echo_method_path[] = "/echo_method";
-const char redirect_to_echo_body_path[] = "/redirect_to_echo_body";
+const char kEchoBodyPath[] = "/echo_body";
+const char kEchoHeaderPath[] = "/echo_header";
+const char kEchoAllHeadersPath[] = "/echo_all_headers";
+const char kEchoMethodPath[] = "/echo_method";
+const char kRedirectToEchoBodyPath[] = "/redirect_to_echo_body";
+const char kFakeSdchDomain[] = "fake.sdch.domain";
+// Path that advertises the dictionary passed in query params if client
+// supports Sdch encoding. E.g. /sdch/index?q=LeQxM80O will make the server
+// responds with "Get-Dictionary: /sdch/dict/LeQxM80O".
+const char kSdchPath[] = "/sdch/index";
+// Path that returns encoded response if client has the right dictionary.
+const char kSdchTestPath[] = "/sdch/test";
+// Path where dictionaries are stored.
+const char kSdchDictPath[] = "/sdch/dict/";
net::test_server::EmbeddedTestServer* g_test_server = nullptr;
-scoped_ptr<net::test_server::HttpResponse> UploadServerRequestHandler(
+class CustomHttpResponse : public net::test_server::HttpResponse {
+ public:
+ CustomHttpResponse(const std::string& headers, const std::string& contents)
+ : headers_(headers), contents_(contents) {}
+
+ std::string ToResponseString() const override {
+ return headers_ + "\r\n" + contents_;
+ }
+
+ void AddHeader(const std::string& key_value_pair) {
+ headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
+ }
+
+ private:
+ std::string headers_;
+ std::string contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(CustomHttpResponse);
+};
+
+scoped_ptr<CustomHttpResponse> ConstructResponseBasedOnFile(
+ const base::FilePath& file_path) {
+ std::string file_contents;
+ bool read_file = base::ReadFileToString(file_path, &file_contents);
+ DCHECK(read_file);
+ base::FilePath headers_path(
+ file_path.AddExtension(FILE_PATH_LITERAL("mock-http-headers")));
+ std::string headers_contents;
+ bool read_headers = base::ReadFileToString(headers_path, &headers_contents);
+ DCHECK(read_headers);
+ scoped_ptr<CustomHttpResponse> http_response(
+ new CustomHttpResponse(headers_contents, file_contents));
+ return http_response.Pass();
+}
+
+scoped_ptr<net::test_server::HttpResponse> NativeTestServerRequestHandler(
const net::test_server::HttpRequest& request) {
DCHECK(g_test_server);
scoped_ptr<net::test_server::BasicHttpResponse> response(
new net::test_server::BasicHttpResponse());
response->set_content_type("text/plain");
- if (request.relative_url == echo_body_path) {
+ if (request.relative_url == kEchoBodyPath) {
if (request.has_content) {
response->set_content(request.content);
} else {
@@ -46,7 +101,7 @@ scoped_ptr<net::test_server::HttpResponse> UploadServerRequestHandler(
return response.Pass();
}
- if (StartsWithASCII(request.relative_url, echo_header_path, true)) {
+ if (StartsWithASCII(request.relative_url, kEchoHeaderPath, true)) {
GURL url = g_test_server->GetURL(request.relative_url);
auto it = request.headers.find(url.query());
if (it != request.headers.end()) {
@@ -57,19 +112,66 @@ scoped_ptr<net::test_server::HttpResponse> UploadServerRequestHandler(
return response.Pass();
}
- if (request.relative_url == echo_all_headers_path) {
+ if (request.relative_url == kEchoAllHeadersPath) {
response->set_content(request.all_headers);
return response.Pass();
}
- if (request.relative_url == echo_method_path) {
+ if (request.relative_url == kEchoMethodPath) {
response->set_content(request.method_string);
return response.Pass();
}
- if (request.relative_url == redirect_to_echo_body_path) {
+ if (request.relative_url == kRedirectToEchoBodyPath) {
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
- response->AddCustomHeader("Location", echo_body_path);
+ response->AddCustomHeader("Location", kEchoBodyPath);
+ return response.Pass();
+ }
+
+ // Unhandled requests result in the Embedded test server sending a 404.
+ return scoped_ptr<net::test_server::BasicHttpResponse>();
+}
+
+scoped_ptr<net::test_server::HttpResponse> SdchRequestHandler(
+ const net::test_server::HttpRequest& request) {
+ DCHECK(g_test_server);
+ base::FilePath dir_path;
+ bool get_data_dir = base::android::GetDataDirectory(&dir_path);
+ DCHECK(get_data_dir);
+ dir_path = dir_path.Append(FILE_PATH_LITERAL("test"));
+
+ if (StartsWithASCII(request.relative_url, kSdchPath, true)) {
+ base::FilePath file_path = dir_path.Append("sdch/index");
+ scoped_ptr<CustomHttpResponse> response =
+ ConstructResponseBasedOnFile(file_path).Pass();
+ // Check for query params to see which dictionary to advertise.
+ // For instance, ?q=dictionaryA will make the server advertise dictionaryA.
+ GURL url = g_test_server->GetURL(request.relative_url);
+ std::string dictionary;
+ if (!net::GetValueForKeyInQuery(url, "q", &dictionary)) {
+ CHECK(false) << "dictionary is not found in query params of "
+ << request.relative_url;
+ }
+ auto accept_encoding_header = request.headers.find("Accept-Encoding");
+ if (accept_encoding_header != request.headers.end()) {
+ if (accept_encoding_header->second.find("sdch") != std::string::npos)
+ response->AddHeader(base::StringPrintf(
+ "Get-Dictionary: %s%s", kSdchDictPath, dictionary.c_str()));
+ }
+ return response.Pass();
+ }
+
+ if (StartsWithASCII(request.relative_url, kSdchTestPath, true)) {
+ auto avail_dictionary_header = request.headers.find("Avail-Dictionary");
+ if (avail_dictionary_header != request.headers.end()) {
+ base::FilePath file_path = dir_path.Append(
+ "sdch/" + avail_dictionary_header->second + "_encoded");
+ return ConstructResponseBasedOnFile(file_path).Pass();
+ }
+ scoped_ptr<net::test_server::BasicHttpResponse> response(
+ new net::test_server::BasicHttpResponse());
+ response->set_content_type("text/plain");
+ response->set_content("Sdch is not used.\n");
return response.Pass();
}
@@ -77,6 +179,30 @@ scoped_ptr<net::test_server::HttpResponse> UploadServerRequestHandler(
return scoped_ptr<net::test_server::BasicHttpResponse>();
}
+void RegisterHostResolverProcHelper(
+ net::URLRequestContext* url_request_context) {
+ net::HostResolverImpl* resolver =
+ static_cast<net::HostResolverImpl*>(url_request_context->host_resolver());
+ scoped_refptr<net::RuleBasedHostResolverProc> proc =
+ new net::RuleBasedHostResolverProc(NULL);
+ proc->AddRule(kFakeSdchDomain, "127.0.0.1");
+ resolver->set_proc_params_for_test(
+ net::HostResolverImpl::ProcTaskParams(proc.get(), 1u));
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NativeTestServer_onHostResolverProcRegistered(env);
+}
+
+void RegisterHostResolverProcOnNetworkThread(
+ CronetURLRequestContextAdapter* context_adapter) {
+ RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
+}
+
+// TODO(xunjieli): Delete this once legacy API is removed.
+void RegisterHostResolverProcOnNetworkThreadLegacyAPI(
+ URLRequestContextAdapter* context_adapter) {
+ RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
+}
+
} // namespace
jboolean StartNativeTestServer(JNIEnv* env,
@@ -87,15 +213,36 @@ jboolean StartNativeTestServer(JNIEnv* env,
return false;
g_test_server = new net::test_server::EmbeddedTestServer();
g_test_server->RegisterRequestHandler(
- base::Bind(&UploadServerRequestHandler));
- // Add a second handler for paths that UploadServerRequestHandler does not
- // handle.
+ base::Bind(&NativeTestServerRequestHandler));
+ g_test_server->RegisterRequestHandler(base::Bind(&SdchRequestHandler));
base::FilePath test_files_root(
base::android::ConvertJavaStringToUTF8(env, jtest_files_root));
+
+ // Add a third handler for paths that NativeTestServerRequestHandler does not
+ // handle.
g_test_server->ServeFilesFromDirectory(test_files_root);
return g_test_server->InitializeAndWaitUntilReady();
}
+void RegisterHostResolverProc(JNIEnv* env,
+ jclass jcaller,
+ jlong jadapter,
+ jboolean jlegacy_api) {
+ if (jlegacy_api == JNI_TRUE) {
+ URLRequestContextAdapter* context_adapter =
+ reinterpret_cast<URLRequestContextAdapter*>(jadapter);
+ context_adapter->PostTaskToNetworkThread(
+ FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThreadLegacyAPI,
+ base::Unretained(context_adapter)));
+ } else {
+ CronetURLRequestContextAdapter* context_adapter =
+ reinterpret_cast<CronetURLRequestContextAdapter*>(jadapter);
+ context_adapter->PostTaskToNetworkThread(
+ FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThread,
+ base::Unretained(context_adapter)));
+ }
+}
+
void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) {
if (!g_test_server)
return;
@@ -105,13 +252,13 @@ void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) {
jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) {
DCHECK(g_test_server);
- GURL url = g_test_server->GetURL(echo_body_path);
+ GURL url = g_test_server->GetURL(kEchoBodyPath);
return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
}
jstring GetEchoHeaderURL(JNIEnv* env, jclass jcaller, jstring jheader) {
DCHECK(g_test_server);
- GURL url = g_test_server->GetURL(echo_header_path);
+ GURL url = g_test_server->GetURL(kEchoHeaderPath);
GURL::Replacements replacements;
std::string header = base::android::ConvertJavaStringToUTF8(env, jheader);
replacements.SetQueryStr(header.c_str());
@@ -121,19 +268,19 @@ jstring GetEchoHeaderURL(JNIEnv* env, jclass jcaller, jstring jheader) {
jstring GetEchoAllHeadersURL(JNIEnv* env, jclass jcaller) {
DCHECK(g_test_server);
- GURL url = g_test_server->GetURL(echo_all_headers_path);
+ GURL url = g_test_server->GetURL(kEchoAllHeadersPath);
return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
}
jstring GetEchoMethodURL(JNIEnv* env, jclass jcaller) {
DCHECK(g_test_server);
- GURL url = g_test_server->GetURL(echo_method_path);
+ GURL url = g_test_server->GetURL(kEchoMethodPath);
return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
}
jstring GetRedirectToEchoBody(JNIEnv* env, jclass jcaller) {
DCHECK(g_test_server);
- GURL url = g_test_server->GetURL(redirect_to_echo_body_path);
+ GURL url = g_test_server->GetURL(kRedirectToEchoBodyPath);
return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
}
@@ -144,6 +291,13 @@ jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) {
return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
}
+jstring GetSdchURL(JNIEnv* env, jclass jcaller) {
+ DCHECK(g_test_server);
+ std::string url(base::StringPrintf("http://%s:%d", kFakeSdchDomain,
+ g_test_server->port()));
+ return base::android::ConvertUTF8ToJavaString(env, url).Release();
+}
+
bool RegisterNativeTestServer(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java b/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java
index 897515f..59768b6 100644
--- a/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java
+++ b/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java
@@ -188,12 +188,14 @@ public class CronetTestActivity extends Activity {
}
public void startNetLog() {
- mRequestFactory.startNetLogToFile(
- Environment.getExternalStorageDirectory().getPath()
- + "/cronet_sample_netlog.json");
+ mRequestFactory.startNetLogToFile(Environment.getExternalStorageDirectory().getPath()
+ + "/cronet_sample_netlog_old_api.json");
+ mUrlRequestContext.startNetLogToFile(Environment.getExternalStorageDirectory().getPath()
+ + "/cronet_sample_netlog_new_api.json");
}
public void stopNetLog() {
mRequestFactory.stopNetLog();
+ mUrlRequestContext.stopNetLog();
}
}
diff --git a/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java b/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
index 08406ea..329b48a 100644
--- a/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
+++ b/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
@@ -5,7 +5,9 @@
package org.chromium.net;
import android.content.Context;
+import android.os.ConditionVariable;
+import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
/**
@@ -14,6 +16,8 @@ import org.chromium.base.JNINamespace;
*/
@JNINamespace("cronet")
public final class NativeTestServer {
+ private static final ConditionVariable sHostResolverBlock = new ConditionVariable();
+
public static boolean startNativeTestServer(Context context) {
return nativeStartNativeTestServer(
TestFilesInstaller.getInstalledPath(context));
@@ -23,6 +27,19 @@ public final class NativeTestServer {
nativeShutdownNativeTestServer();
}
+ /**
+ * Registers customized DNS mapping for {@link NativeTestServer}.
+ * @param contextAdapter native context adapter object that this
+ * mapping should apply to.
+ * @param isLegacyAPI {@code true} if this context adapter is a part of the
+ * old API.
+ */
+ public static void registerHostResolverProc(long contextAdapter, boolean isLegacyAPI) {
+ sHostResolverBlock.close();
+ nativeRegisterHostResolverProc(contextAdapter, isLegacyAPI);
+ sHostResolverBlock.block();
+ }
+
public static String getEchoBodyURL() {
return nativeGetEchoBodyURL();
}
@@ -47,12 +64,24 @@ public final class NativeTestServer {
return nativeGetFileURL(filePath);
}
+ public static String getSdchURL() {
+ return nativeGetSdchURL();
+ }
+
+ @CalledByNative
+ private static void onHostResolverProcRegistered() {
+ sHostResolverBlock.open();
+ }
+
private static native boolean nativeStartNativeTestServer(String filePath);
private static native void nativeShutdownNativeTestServer();
+ private static native void nativeRegisterHostResolverProc(
+ long contextAdapter, boolean isLegacyAPI);
private static native String nativeGetEchoBodyURL();
private static native String nativeGetEchoHeaderURL(String header);
private static native String nativeGetEchoAllHeadersURL();
private static native String nativeGetEchoMethodURL();
private static native String nativeGetRedirectToEchoBody();
private static native String nativeGetFileURL(String filePath);
+ private static native String nativeGetSdchURL();
}
diff --git a/components/cronet/android/url_request_adapter.cc b/components/cronet/android/url_request_adapter.cc
index 59d2aed..43fb8f4 100644
--- a/components/cronet/android/url_request_adapter.cc
+++ b/components/cronet/android/url_request_adapter.cc
@@ -114,6 +114,12 @@ std::string URLRequestAdapter::GetNegotiatedProtocol() const {
return url_request_->response_info().npn_negotiated_protocol;
}
+bool URLRequestAdapter::GetWasCached() const {
+ if (url_request_ == NULL)
+ return false;
+ return url_request_->response_info().was_cached;
+}
+
void URLRequestAdapter::Start() {
context_->PostTaskToNetworkThread(
FROM_HERE,
diff --git a/components/cronet/android/url_request_adapter.h b/components/cronet/android/url_request_adapter.h
index 8704a00..4ba153e 100644
--- a/components/cronet/android/url_request_adapter.h
+++ b/components/cronet/android/url_request_adapter.h
@@ -118,6 +118,9 @@ class URLRequestAdapter : public net::URLRequest::Delegate {
// Get NPN or ALPN Negotiated Protocol (if any) from HttpResponseInfo.
std::string GetNegotiatedProtocol() const;
+ // Returns whether the response is serviced from cache.
+ bool GetWasCached() const;
+
// net::URLRequest::Delegate implementation:
void OnResponseStarted(net::URLRequest* request) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
diff --git a/components/cronet/android/url_request_context_adapter.cc b/components/cronet/android/url_request_context_adapter.cc
index d2adeb4..1524baf 100644
--- a/components/cronet/android/url_request_context_adapter.cc
+++ b/components/cronet/android/url_request_context_adapter.cc
@@ -23,6 +23,7 @@
#include "net/http/http_server_properties.h"
#include "net/log/write_to_file_net_log_observer.h"
#include "net/proxy/proxy_service.h"
+#include "net/sdch/sdch_owner.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context_builder.h"
@@ -151,6 +152,12 @@ void URLRequestContextAdapter::InitRequestContextOnNetworkThread() {
context_.reset(context_builder.Build());
+ if (config_->enable_sdch) {
+ DCHECK(context_->sdch_manager());
+ sdch_owner_.reset(
+ new net::SdchOwner(context_->sdch_manager(), context_.get()));
+ }
+
// Currently (circa M39) enabling QUIC requires setting probability threshold.
if (config_->enable_quic) {
context_->http_server_properties()
diff --git a/components/cronet/android/url_request_context_adapter.h b/components/cronet/android/url_request_context_adapter.h
index cdcc79f..5460911 100644
--- a/components/cronet/android/url_request_context_adapter.h
+++ b/components/cronet/android/url_request_context_adapter.h
@@ -20,11 +20,9 @@
#include "net/url_request/url_request_context_getter.h"
namespace net {
-
class WriteToFileNetLogObserver;
-
class ProxyConfigService;
-
+class SdchOwner;
} // namespace net
namespace cronet {
@@ -109,6 +107,7 @@ class URLRequestContextAdapter : public net::URLRequestContextGetter {
scoped_ptr<NetLogObserver> net_log_observer_;
scoped_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
+ scoped_ptr<net::SdchOwner> sdch_owner_;
scoped_ptr<URLRequestContextConfig> config_;
// A queue of tasks that need to be run after context has been initialized.
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc
index 0aa2089..c8f2150 100644
--- a/components/cronet/url_request_context_config.cc
+++ b/components/cronet/url_request_context_config.cc
@@ -78,6 +78,7 @@ void URLRequestContextConfig::ConfigureURLRequestContextBuilder(
context_builder->SetSpdyAndQuicEnabled(enable_spdy, enable_quic);
context_builder->set_quic_connection_options(
net::QuicUtils::ParseQuicConnectionOptions(quic_connection_options));
+ context_builder->set_sdch_enabled(enable_sdch);
// TODO(mef): Use |config| to set cookies.
}
@@ -92,6 +93,8 @@ void URLRequestContextConfig::RegisterJSONConverter(
&URLRequestContextConfig::enable_quic);
converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_ENABLE_SPDY,
&URLRequestContextConfig::enable_spdy);
+ converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_ENABLE_SDCH,
+ &URLRequestContextConfig::enable_sdch);
converter->RegisterStringField(REQUEST_CONTEXT_CONFIG_HTTP_CACHE,
&URLRequestContextConfig::http_cache);
converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_LOAD_DISABLE_CACHE,
diff --git a/components/cronet/url_request_context_config.h b/components/cronet/url_request_context_config.h
index 30530f5..a74f440 100644
--- a/components/cronet/url_request_context_config.h
+++ b/components/cronet/url_request_context_config.h
@@ -58,6 +58,8 @@ struct URLRequestContextConfig {
bool enable_quic;
// Enable SPDY.
bool enable_spdy;
+ // Enable SDCH.
+ bool enable_sdch;
// Type of http cache: "HTTP_CACHE_DISABLED", "HTTP_CACHE_DISK" or
// "HTTP_CACHE_IN_MEMORY".
std::string http_cache;
diff --git a/components/cronet/url_request_context_config_list.h b/components/cronet/url_request_context_config_list.h
index bf237e9..c5451a9 100644
--- a/components/cronet/url_request_context_config_list.h
+++ b/components/cronet/url_request_context_config_list.h
@@ -14,6 +14,7 @@ DEFINE_CONTEXT_CONFIG(ENABLE_LEGACY_MODE)
DEFINE_CONTEXT_CONFIG(NATIVE_LIBRARY_NAME)
DEFINE_CONTEXT_CONFIG(ENABLE_QUIC)
DEFINE_CONTEXT_CONFIG(ENABLE_SPDY)
+DEFINE_CONTEXT_CONFIG(ENABLE_SDCH)
DEFINE_CONTEXT_CONFIG(HTTP_CACHE)
DEFINE_CONTEXT_CONFIG(HTTP_CACHE_MAX_SIZE)
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index bcb5c68..5e6f721 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -16,6 +16,7 @@
#include "net/base/cache_type.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate_impl.h"
+#include "net/base/sdch_manager.h"
#include "net/cert/cert_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/host_resolver.h"
@@ -205,7 +206,8 @@ URLRequestContextBuilder::URLRequestContextBuilder()
ftp_enabled_(false),
#endif
http_cache_enabled_(true),
- throttling_enabled_(false) {
+ throttling_enabled_(false),
+ sdch_enabled_(false) {
}
URLRequestContextBuilder::~URLRequestContextBuilder() {}
@@ -308,6 +310,11 @@ URLRequestContext* URLRequestContextBuilder::Build() {
new DefaultChannelIDStore(NULL), context->GetFileTaskRunner())));
}
+ if (sdch_enabled_) {
+ storage->set_sdch_manager(
+ scoped_ptr<net::SdchManager>(new SdchManager()).Pass());
+ }
+
storage->set_transport_security_state(new TransportSecurityState());
if (!transport_security_persister_path_.empty()) {
context->set_transport_security_persister(
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index b21a652..2039baa 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -141,7 +141,6 @@ class NET_EXPORT URLRequestContextBuilder {
network_delegate_.reset(delegate);
}
-
// Adds additional auth handler factories to be used in addition to what is
// provided in the default |HttpAuthHandlerRegistryFactory|. The auth |scheme|
// and |factory| are provided. The builder takes ownership of the factory and
@@ -196,6 +195,13 @@ class NET_EXPORT URLRequestContextBuilder {
void SetFileTaskRunner(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
+ // Note that if SDCH is enabled without a policy object observing
+ // the SDCH manager and handling at least Get-Dictionary events, the
+ // result will be "Content-Encoding: sdch" advertisements, but no
+ // dictionaries fetches and no specific dictionaries advertised.
+ // SdchOwner in net/sdch/sdch_owner.h is a simple policy object.
+ void set_sdch_enabled(bool enable) { sdch_enabled_ = enable; }
+
URLRequestContext* Build();
private:
@@ -221,6 +227,7 @@ class NET_EXPORT URLRequestContextBuilder {
#endif
bool http_cache_enabled_;
bool throttling_enabled_;
+ bool sdch_enabled_;
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
HttpCacheParams http_cache_params_;