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. 4 5 package org.chromium.content.browser; 6 7 import org.chromium.base.CalledByNative; 8 import org.chromium.base.JNINamespace; 9 import org.chromium.content_public.Referrer; 10 11 import java.util.Locale; 12 import java.util.Map; 13 14 /** 15 * Holds parameters for ContentViewCore.LoadUrl. Parameters should match 16 * counterparts in NavigationController::LoadURLParams, including default 17 * values. 18 */ 19 @JNINamespace("content") 20 public class LoadUrlParams { 21 // Should match NavigationController::LoadUrlType exactly. See comments 22 // there for proper usage. initializeConstants() checks that the values 23 // are correct. 24 public static final int LOAD_TYPE_DEFAULT = 0; 25 public static final int LOAD_TYPE_BROWSER_INITIATED_HTTP_POST = 1; 26 public static final int LOAD_TYPE_DATA = 2; 27 28 // Should match NavigationController::UserAgentOverrideOption exactly. 29 // See comments there for proper usage. initializeConstants() checks that 30 // the values are correct. 31 public static final int UA_OVERRIDE_INHERIT = 0; 32 public static final int UA_OVERRIDE_FALSE = 1; 33 public static final int UA_OVERRIDE_TRUE = 2; 34 35 // Fields with counterparts in NavigationController::LoadURLParams. 36 // Package private so that ContentViewCore.loadUrl can pass them down to 37 // native code. Should not be accessed directly anywhere else outside of 38 // this class. 39 String mUrl; 40 int mLoadUrlType; 41 int mTransitionType; 42 Referrer mReferrer; 43 private Map<String, String> mExtraHeaders; 44 private String mVerbatimHeaders; 45 int mUaOverrideOption; 46 byte[] mPostData; 47 String mBaseUrlForDataUrl; 48 String mVirtualUrlForDataUrl; 49 boolean mCanLoadLocalResources; 50 boolean mIsRendererInitiated; 51 52 /** 53 * Creates an instance with default page transition type. 54 * @param url the url to be loaded 55 */ LoadUrlParams(String url)56 public LoadUrlParams(String url) { 57 this(url, PageTransitionTypes.PAGE_TRANSITION_LINK); 58 } 59 60 /** 61 * Creates an instance with the given page transition type. 62 * @param url the url to be loaded 63 * @param transitionType the PageTransitionType constant corresponding to the load 64 */ LoadUrlParams(String url, int transitionType)65 public LoadUrlParams(String url, int transitionType) { 66 mUrl = url; 67 mTransitionType = transitionType; 68 69 // Initialize other fields to defaults matching defaults of the native 70 // NavigationController::LoadUrlParams. 71 mLoadUrlType = LOAD_TYPE_DEFAULT; 72 mUaOverrideOption = UA_OVERRIDE_INHERIT; 73 mPostData = null; 74 mBaseUrlForDataUrl = null; 75 mVirtualUrlForDataUrl = null; 76 } 77 78 /** 79 * Helper method to create a LoadUrlParams object for data url. 80 * @param data Data to be loaded. 81 * @param mimeType Mime type of the data. 82 * @param isBase64Encoded True if the data is encoded in Base 64 format. 83 */ createLoadDataParams( String data, String mimeType, boolean isBase64Encoded)84 public static LoadUrlParams createLoadDataParams( 85 String data, String mimeType, boolean isBase64Encoded) { 86 return createLoadDataParams(data, mimeType, isBase64Encoded, null); 87 } 88 89 /** 90 * Helper method to create a LoadUrlParams object for data url. 91 * @param data Data to be loaded. 92 * @param mimeType Mime type of the data. 93 * @param isBase64Encoded True if the data is encoded in Base 64 format. 94 * @param charset The character set for the data. Pass null if the mime type 95 * does not require a special charset. 96 */ createLoadDataParams( String data, String mimeType, boolean isBase64Encoded, String charset)97 public static LoadUrlParams createLoadDataParams( 98 String data, String mimeType, boolean isBase64Encoded, String charset) { 99 StringBuilder dataUrl = new StringBuilder("data:"); 100 dataUrl.append(mimeType); 101 if (charset != null && !charset.isEmpty()) { 102 dataUrl.append(";charset=" + charset); 103 } 104 if (isBase64Encoded) { 105 dataUrl.append(";base64"); 106 } 107 dataUrl.append(","); 108 dataUrl.append(data); 109 110 LoadUrlParams params = new LoadUrlParams(dataUrl.toString()); 111 params.setLoadType(LoadUrlParams.LOAD_TYPE_DATA); 112 params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_TYPED); 113 return params; 114 } 115 116 /** 117 * Helper method to create a LoadUrlParams object for data url with base 118 * and virtual url. 119 * @param data Data to be loaded. 120 * @param mimeType Mime type of the data. 121 * @param isBase64Encoded True if the data is encoded in Base 64 format. 122 * @param baseUrl Base url of this data load. Note that for WebView compatibility, 123 * baseUrl and historyUrl are ignored if this is a data: url. 124 * Defaults to about:blank if null. 125 * @param historyUrl History url for this data load. Note that for WebView compatibility, 126 * this is ignored if baseUrl is a data: url. Defaults to about:blank 127 * if null. 128 */ createLoadDataParamsWithBaseUrl( String data, String mimeType, boolean isBase64Encoded, String baseUrl, String historyUrl)129 public static LoadUrlParams createLoadDataParamsWithBaseUrl( 130 String data, String mimeType, boolean isBase64Encoded, 131 String baseUrl, String historyUrl) { 132 return createLoadDataParamsWithBaseUrl(data, mimeType, isBase64Encoded, 133 baseUrl, historyUrl, null); 134 } 135 136 /** 137 * Helper method to create a LoadUrlParams object for data url with base 138 * and virtual url. 139 * @param data Data to be loaded. 140 * @param mimeType Mime type of the data. 141 * @param isBase64Encoded True if the data is encoded in Base 64 format. 142 * @param baseUrl Base url of this data load. Note that for WebView compatibility, 143 * baseUrl and historyUrl are ignored if this is a data: url. 144 * Defaults to about:blank if null. 145 * @param historyUrl History url for this data load. Note that for WebView compatibility, 146 * this is ignored if baseUrl is a data: url. Defaults to about:blank 147 * if null. 148 * @param charset The character set for the data. Pass null if the mime type 149 * does not require a special charset. 150 */ createLoadDataParamsWithBaseUrl( String data, String mimeType, boolean isBase64Encoded, String baseUrl, String historyUrl, String charset)151 public static LoadUrlParams createLoadDataParamsWithBaseUrl( 152 String data, String mimeType, boolean isBase64Encoded, 153 String baseUrl, String historyUrl, String charset) { 154 LoadUrlParams params = createLoadDataParams(data, mimeType, isBase64Encoded, charset); 155 // For WebView compatibility, when the base URL has the 'data:' 156 // scheme, we treat it as a regular data URL load and skip setting 157 // baseUrl and historyUrl. 158 // TODO(joth): we should just append baseURL and historyURL here, and move the 159 // WebView specific transform up to a wrapper factory function in android_webview/. 160 if (baseUrl == null || !baseUrl.toLowerCase(Locale.US).startsWith("data:")) { 161 params.setBaseUrlForDataUrl(baseUrl != null ? baseUrl : "about:blank"); 162 params.setVirtualUrlForDataUrl(historyUrl != null ? historyUrl : "about:blank"); 163 } 164 return params; 165 } 166 167 /** 168 * Helper method to create a LoadUrlParams object for an HTTP POST load. 169 * @param url URL of the load. 170 * @param postData Post data of the load. Can be null. 171 */ createLoadHttpPostParams( String url, byte[] postData)172 public static LoadUrlParams createLoadHttpPostParams( 173 String url, byte[] postData) { 174 LoadUrlParams params = new LoadUrlParams(url); 175 params.setLoadType(LOAD_TYPE_BROWSER_INITIATED_HTTP_POST); 176 params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_TYPED); 177 params.setPostData(postData); 178 return params; 179 } 180 181 /** 182 * Sets the url. 183 */ setUrl(String url)184 public void setUrl(String url) { 185 mUrl = url; 186 } 187 188 /** 189 * Return the url. 190 */ getUrl()191 public String getUrl() { 192 return mUrl; 193 } 194 195 /** 196 * Return the base url for a data url, otherwise null. 197 */ getBaseUrl()198 public String getBaseUrl() { 199 return mBaseUrlForDataUrl; 200 } 201 202 /** 203 * Set load type of this load. Defaults to LOAD_TYPE_DEFAULT. 204 * @param loadType One of LOAD_TYPE static constants above. 205 */ setLoadType(int loadType)206 public void setLoadType(int loadType) { 207 mLoadUrlType = loadType; 208 } 209 210 /** 211 * Set transition type of this load. Defaults to PAGE_TRANSITION_LINK. 212 * @param transitionType One of PAGE_TRANSITION static constants in ContentView. 213 */ setTransitionType(int transitionType)214 public void setTransitionType(int transitionType) { 215 mTransitionType = transitionType; 216 } 217 218 /** 219 * Return the transition type. 220 */ getTransitionType()221 public int getTransitionType() { 222 return mTransitionType; 223 } 224 225 /** 226 * @return the referrer of this load 227 */ setReferrer(Referrer referrer)228 public void setReferrer(Referrer referrer) { 229 mReferrer = referrer; 230 } 231 232 /** 233 * Sets the referrer of this load. 234 */ getReferrer()235 public Referrer getReferrer() { 236 return mReferrer; 237 } 238 239 /** 240 * Set extra headers for this load. 241 * @param extraHeaders Extra HTTP headers for this load. Note that these 242 * headers will never overwrite existing ones set by Chromium. 243 */ setExtraHeaders(Map<String, String> extraHeaders)244 public void setExtraHeaders(Map<String, String> extraHeaders) { 245 mExtraHeaders = extraHeaders; 246 } 247 248 /** 249 * Return the extra headers as a map. 250 */ getExtraHeaders()251 public Map<String, String> getExtraHeaders() { 252 return mExtraHeaders; 253 } 254 255 /** 256 * Return the extra headers as a single String separated by "\n", or null if no extra header is 257 * set. This form is suitable for passing to native 258 * NavigationController::LoadUrlParams::extra_headers. This will return the headers set in an 259 * exploded form through setExtraHeaders(). Embedders that work with extra headers in opaque 260 * collapsed form can use the setVerbatimHeaders() / getVerbatimHeaders() instead. 261 */ getExtraHeadersString()262 String getExtraHeadersString() { 263 return getExtraHeadersString("\n", false); 264 } 265 266 /** 267 * Return the extra headers as a single String separated by "\r\n", or null if no extra header 268 * is set. This form is suitable for passing to native 269 * net::HttpRequestHeaders::AddHeadersFromString. 270 */ getExtraHttpRequestHeadersString()271 public String getExtraHttpRequestHeadersString() { 272 return getExtraHeadersString("\r\n", true); 273 } 274 getExtraHeadersString(String delimiter, boolean addTerminator)275 private String getExtraHeadersString(String delimiter, boolean addTerminator) { 276 if (mExtraHeaders == null) return null; 277 278 StringBuilder headerBuilder = new StringBuilder(); 279 for (Map.Entry<String, String> header : mExtraHeaders.entrySet()) { 280 if (headerBuilder.length() > 0) headerBuilder.append(delimiter); 281 282 // Header name should be lower case. 283 headerBuilder.append(header.getKey().toLowerCase(Locale.US)); 284 headerBuilder.append(":"); 285 headerBuilder.append(header.getValue()); 286 } 287 if (addTerminator) 288 headerBuilder.append(delimiter); 289 290 return headerBuilder.toString(); 291 } 292 293 /** 294 * Sets the verbatim extra headers string. This is an alternative to storing the headers in 295 * a map (setExtraHeaders()) for the embedders that use collapsed headers strings. 296 */ setVerbatimHeaders(String headers)297 public void setVerbatimHeaders(String headers) { 298 mVerbatimHeaders = headers; 299 } 300 301 /** 302 * @return the verbatim extra headers string 303 */ getVerbatimHeaders()304 public String getVerbatimHeaders() { 305 return mVerbatimHeaders; 306 } 307 308 /** 309 * Set user agent override option of this load. Defaults to UA_OVERRIDE_INHERIT. 310 * @param uaOption One of UA_OVERRIDE static constants above. 311 */ setOverrideUserAgent(int uaOption)312 public void setOverrideUserAgent(int uaOption) { 313 mUaOverrideOption = uaOption; 314 } 315 316 /** 317 * Set the post data of this load. This field is ignored unless load type is 318 * LOAD_TYPE_BROWSER_INITIATED_HTTP_POST. 319 * @param postData Post data for this http post load. 320 */ setPostData(byte[] postData)321 public void setPostData(byte[] postData) { 322 mPostData = postData; 323 } 324 325 /** 326 * @return the data to be sent through POST 327 */ getPostData()328 public byte[] getPostData() { 329 return mPostData; 330 } 331 332 /** 333 * Set the base url for data load. It is used both to resolve relative URLs 334 * and when applying JavaScript's same origin policy. It is ignored unless 335 * load type is LOAD_TYPE_DATA. 336 * @param baseUrl The base url for this data load. 337 */ setBaseUrlForDataUrl(String baseUrl)338 public void setBaseUrlForDataUrl(String baseUrl) { 339 mBaseUrlForDataUrl = baseUrl; 340 } 341 342 /** 343 * Set the virtual url for data load. It is the url displayed to the user. 344 * It is ignored unless load type is LOAD_TYPE_DATA. 345 * @param virtualUrl The virtual url for this data load. 346 */ setVirtualUrlForDataUrl(String virtualUrl)347 public void setVirtualUrlForDataUrl(String virtualUrl) { 348 mVirtualUrlForDataUrl = virtualUrl; 349 } 350 351 /** 352 * Set whether the load should be able to access local resources. This 353 * defaults to false. 354 */ setCanLoadLocalResources(boolean canLoad)355 public void setCanLoadLocalResources(boolean canLoad) { 356 mCanLoadLocalResources = canLoad; 357 } 358 getLoadUrlType()359 public int getLoadUrlType() { 360 return mLoadUrlType; 361 } 362 363 /** 364 * @param rendererInitiated Whether or not this load was initiated from a renderer. 365 */ setIsRendererInitiated(boolean rendererInitiated)366 public void setIsRendererInitiated(boolean rendererInitiated) { 367 mIsRendererInitiated = rendererInitiated; 368 } 369 370 /** 371 * @return Whether or not this load was initiated from a renderer or not. 372 */ getIsRendererInitiated()373 public boolean getIsRendererInitiated() { 374 return mIsRendererInitiated; 375 } 376 isBaseUrlDataScheme()377 public boolean isBaseUrlDataScheme() { 378 // If there's no base url set, but this is a data load then 379 // treat the scheme as data:. 380 if (mBaseUrlForDataUrl == null && mLoadUrlType == LOAD_TYPE_DATA) { 381 return true; 382 } 383 return nativeIsDataScheme(mBaseUrlForDataUrl); 384 } 385 386 @SuppressWarnings("unused") 387 @CalledByNative initializeConstants( int load_type_default, int load_type_browser_initiated_http_post, int load_type_data, int ua_override_inherit, int ua_override_false, int ua_override_true)388 private static void initializeConstants( 389 int load_type_default, 390 int load_type_browser_initiated_http_post, 391 int load_type_data, 392 int ua_override_inherit, 393 int ua_override_false, 394 int ua_override_true) { 395 assert LOAD_TYPE_DEFAULT == load_type_default; 396 assert LOAD_TYPE_BROWSER_INITIATED_HTTP_POST == load_type_browser_initiated_http_post; 397 assert LOAD_TYPE_DATA == load_type_data; 398 assert UA_OVERRIDE_INHERIT == ua_override_inherit; 399 assert UA_OVERRIDE_FALSE == ua_override_false; 400 assert UA_OVERRIDE_TRUE == ua_override_true; 401 } 402 403 /** 404 * Parses |url| as a GURL on the native side, and 405 * returns true if it's scheme is data:. 406 */ nativeIsDataScheme(String url)407 private static native boolean nativeIsDataScheme(String url); 408 } 409