1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.android_webview.test;
7 import android.test.suitebuilder.annotation.SmallTest;
8 import android.util.Pair;
10 import org.apache.http.Header;
11 import org.apache.http.HttpRequest;
12 import org.chromium.android_webview.AwContents;
13 import org.chromium.android_webview.AwSettings;
14 import org.chromium.android_webview.test.util.CommonResources;
15 import org.chromium.android_webview.test.util.JSUtils;
16 import org.chromium.base.test.util.Feature;
17 import org.chromium.content.browser.test.util.CallbackHelper;
18 import org.chromium.content.browser.test.util.HistoryUtils;
19 import org.chromium.content_public.browser.LoadUrlParams;
20 import org.chromium.net.test.util.TestWebServer;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Locale;
27 import java.util.concurrent.TimeUnit;
30 * Test suite for loadUrl().
32 public class LoadUrlTest extends AwTestBase {
34 @Feature({"AndroidWebView"})
35 public void testDataUrl() throws Throwable {
36 final String expectedTitle = "dataUrlTest";
38 "<html><head><title>" + expectedTitle + "</title></head><body>foo</body></html>";
40 final TestAwContentsClient contentsClient = new TestAwContentsClient();
41 final AwTestContainerView testContainerView =
42 createAwTestContainerViewOnMainSync(contentsClient);
43 final AwContents awContents = testContainerView.getAwContents();
44 loadDataSync(awContents, contentsClient.getOnPageFinishedHelper(), data,
46 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
50 @Feature({"AndroidWebView"})
51 public void testDataUrlBase64() throws Throwable {
52 final String expectedTitle = "dataUrlTestBase64";
53 final String data = "PGh0bWw+PGhlYWQ+PHRpdGxlPmRhdGFVcmxUZXN0QmFzZTY0PC90aXRsZT48" +
54 "L2hlYWQ+PC9odG1sPg==";
56 final TestAwContentsClient contentsClient = new TestAwContentsClient();
57 final AwTestContainerView testContainerView =
58 createAwTestContainerViewOnMainSync(contentsClient);
59 final AwContents awContents = testContainerView.getAwContents();
60 loadDataSync(awContents, contentsClient.getOnPageFinishedHelper(), data,
62 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
66 @Feature({"AndroidWebView"})
67 public void testDataUrlCharset() throws Throwable {
68 // Note that the \u00a3 (pound sterling) is the important character in the following
69 // string as it's not in the US_ASCII character set.
70 final String expectedTitle = "You win \u00a3100!";
72 "<html><head><title>" + expectedTitle + "</title></head><body>foo</body></html>";
73 final TestAwContentsClient contentsClient = new TestAwContentsClient();
74 final AwTestContainerView testContainerView =
75 createAwTestContainerViewOnMainSync(contentsClient);
76 final AwContents awContents = testContainerView.getAwContents();
77 loadDataSyncWithCharset(awContents, contentsClient.getOnPageFinishedHelper(), data,
78 "text/html", false, "UTF-8");
79 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
83 * Loads url on the UI thread and blocks until onPageFinished is called.
85 protected void loadUrlWithExtraHeadersSync(
86 final AwContents awContents,
87 CallbackHelper onPageFinishedHelper,
89 final Map<String, String> extraHeaders) throws Throwable {
90 int currentCallCount = onPageFinishedHelper.getCallCount();
91 runTestOnUiThread(new Runnable() {
94 LoadUrlParams params = new LoadUrlParams(url);
95 params.setExtraHeaders(extraHeaders);
96 awContents.loadUrl(params);
99 onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_MS,
100 TimeUnit.MILLISECONDS);
103 private static List<Pair<String, String>> createHeadersList(String[] namesAndValues) {
104 List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
105 for (int i = 0; i < namesAndValues.length; i += 2)
106 result.add(Pair.create(namesAndValues[i], namesAndValues[i + 1]));
110 private static Map<String, String> createHeadersMap(String[] namesAndValues) {
111 Map<String, String> result = new HashMap<String, String>();
112 for (int i = 0; i < namesAndValues.length; i += 2)
113 result.put(namesAndValues[i], namesAndValues[i + 1]);
117 private void validateRequestHeaders(String[] refNamesAndValues,
118 HttpRequest request) {
119 for (int i = 0; i < refNamesAndValues.length; i += 2) {
120 Header[] matchingHeaders = request.getHeaders(refNamesAndValues[i]);
121 assertEquals(1, matchingHeaders.length);
123 Header header = matchingHeaders[0];
124 assertEquals(refNamesAndValues[i].toLowerCase(Locale.ENGLISH), header.getName());
125 assertEquals(refNamesAndValues[i + 1], header.getValue());
129 private void validateNoRequestHeaders(String[] refNamesAndValues,
130 HttpRequest request) {
131 for (int i = 0; i < refNamesAndValues.length; i += 2) {
132 Header[] matchingHeaders = request.getHeaders(refNamesAndValues[i]);
133 assertEquals(0, matchingHeaders.length);
138 @Feature({"AndroidWebView"})
139 public void testLoadUrlWithExtraHeaders() throws Throwable {
140 final TestAwContentsClient contentsClient = new TestAwContentsClient();
141 final AwTestContainerView testContainerView =
142 createAwTestContainerViewOnMainSync(contentsClient);
143 final AwContents awContents = testContainerView.getAwContents();
145 TestWebServer webServer = null;
147 webServer = new TestWebServer(false);
148 final String imagePath = "/" + CommonResources.FAVICON_FILENAME;
149 webServer.setResponseBase64(imagePath,
150 CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(true));
151 final String path = "/load_url_with_extra_headers_test.html";
152 final String url = webServer.setResponse(
154 CommonResources.getOnImageLoadedHtml(CommonResources.FAVICON_FILENAME),
156 String[] extraHeaders = {
157 "X-ExtraHeaders1", "extra-header-data1",
158 "x-extraHeaders2", "EXTRA-HEADER-DATA2"
161 loadUrlWithExtraHeadersSync(awContents,
162 contentsClient.getOnPageFinishedHelper(),
164 createHeadersMap(extraHeaders));
165 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
166 // Verify that extra headers are only passed for the main resource.
167 validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(imagePath));
169 if (webServer != null) webServer.shutdown();
174 @Feature({"AndroidWebView"})
175 public void testNoOverridingOfExistingHeaders() throws Throwable {
176 final TestAwContentsClient contentsClient = new TestAwContentsClient();
177 final AwTestContainerView testContainerView =
178 createAwTestContainerViewOnMainSync(contentsClient);
179 final AwContents awContents = testContainerView.getAwContents();
181 TestWebServer webServer = null;
183 webServer = new TestWebServer(false);
184 final String path = "/no_overriding_of_existing_headers_test.html";
185 final String url = webServer.setResponse(
187 "<html><body>foo</body></html>",
189 String[] extraHeaders = {
193 loadUrlWithExtraHeadersSync(awContents,
194 contentsClient.getOnPageFinishedHelper(),
196 createHeadersMap(extraHeaders));
197 Header[] matchingHeaders = webServer.getLastRequest(path).getHeaders(extraHeaders[0]);
198 assertEquals(1, matchingHeaders.length);
199 Header header = matchingHeaders[0];
200 assertEquals(extraHeaders[0].toLowerCase(Locale.ENGLISH),
201 header.getName().toLowerCase(Locale.ENGLISH));
202 // Just check that the value is there, and it's not the one we provided.
203 assertTrue(header.getValue().length() > 0);
204 assertFalse(extraHeaders[1].equals(header.getValue()));
206 if (webServer != null) webServer.shutdown();
211 @Feature({"AndroidWebView"})
212 public void testReloadWithExtraHeaders() throws Throwable {
213 final TestAwContentsClient contentsClient = new TestAwContentsClient();
214 final AwTestContainerView testContainerView =
215 createAwTestContainerViewOnMainSync(contentsClient);
216 final AwContents awContents = testContainerView.getAwContents();
218 TestWebServer webServer = null;
220 webServer = new TestWebServer(false);
221 final String path = "/reload_with_extra_headers_test.html";
222 final String url = webServer.setResponse(path,
223 "<html><body>foo</body></html>",
224 createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
225 String[] extraHeaders = {
226 "X-ExtraHeaders1", "extra-header-data1",
227 "x-extraHeaders2", "EXTRA-HEADER-DATA2"
230 loadUrlWithExtraHeadersSync(awContents,
231 contentsClient.getOnPageFinishedHelper(),
233 createHeadersMap(extraHeaders));
234 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
236 reloadSync(awContents, contentsClient.getOnPageFinishedHelper());
237 assertEquals(2, webServer.getRequestCount(path));
238 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
240 if (webServer != null) webServer.shutdown();
245 @Feature({"AndroidWebView"})
246 public void testRedirectAndReloadWithExtraHeaders() throws Throwable {
247 final TestAwContentsClient contentsClient = new TestAwContentsClient();
248 final AwTestContainerView testContainerView =
249 createAwTestContainerViewOnMainSync(contentsClient);
250 final AwContents awContents = testContainerView.getAwContents();
252 TestWebServer webServer = null;
254 webServer = new TestWebServer(false);
255 final String path = "/redirect_and_reload_with_extra_headers_test.html";
256 final String url = webServer.setResponse(path,
257 "<html><body>foo</body></html>",
258 createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
259 final String redirectedPath = "/redirected.html";
260 final String redirectedUrl = webServer.setRedirect(redirectedPath, path);
261 String[] extraHeaders = {
262 "X-ExtraHeaders1", "extra-header-data1",
263 "x-extraHeaders2", "EXTRA-HEADER-DATA2"
266 loadUrlWithExtraHeadersSync(awContents,
267 contentsClient.getOnPageFinishedHelper(),
269 createHeadersMap(extraHeaders));
270 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
271 validateRequestHeaders(extraHeaders, webServer.getLastRequest(redirectedPath));
273 // WebView will only reload the main page.
274 reloadSync(awContents, contentsClient.getOnPageFinishedHelper());
275 assertEquals(2, webServer.getRequestCount(path));
276 // No extra headers. This is consistent with legacy behavior.
277 validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(path));
279 if (webServer != null) webServer.shutdown();
284 @Feature({"AndroidWebView"})
285 public void testRendererNavigationAndGoBackWithExtraHeaders() throws Throwable {
286 final TestAwContentsClient contentsClient = new TestAwContentsClient();
287 final AwTestContainerView testContainerView =
288 createAwTestContainerViewOnMainSync(contentsClient);
289 final AwContents awContents = testContainerView.getAwContents();
290 final AwSettings settings = getAwSettingsOnUiThread(awContents);
291 settings.setJavaScriptEnabled(true);
293 TestWebServer webServer = null;
295 webServer = new TestWebServer(false);
296 final String nextPath = "/next.html";
297 final String nextUrl = webServer.setResponse(nextPath,
298 "<html><body>Next!</body></html>",
300 final String path = "/renderer_nav_and_go_back_with_extra_headers_test.html";
301 final String url = webServer.setResponse(path,
302 "<html><body><a id=\"next\" href=\"next.html\">Next!</a></body></html>",
303 createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
304 String[] extraHeaders = {
305 "X-ExtraHeaders1", "extra-header-data1",
306 "x-extraHeaders2", "EXTRA-HEADER-DATA2"
309 loadUrlWithExtraHeadersSync(awContents,
310 contentsClient.getOnPageFinishedHelper(),
312 createHeadersMap(extraHeaders));
313 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
315 int currentCallCount = contentsClient.getOnPageFinishedHelper().getCallCount();
316 JSUtils.clickOnLinkUsingJs(this,
318 contentsClient.getOnEvaluateJavaScriptResultHelper(),
320 contentsClient.getOnPageFinishedHelper().waitForCallback(
321 currentCallCount, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
322 // No extra headers for the page navigated via clicking.
323 validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(nextPath));
325 HistoryUtils.goBackSync(getInstrumentation(),
326 awContents.getWebContents(),
327 contentsClient.getOnPageFinishedHelper());
328 assertEquals(2, webServer.getRequestCount(path));
329 validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
331 if (webServer != null) webServer.shutdown();