/* * This function is used by handleUrlInterecpt and handleCache to * setup a load from the byte stream in a CacheResult. */ private void startCacheLoad(CacheResult result) { if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: loading from cache: " + mListener.url()); } // Tell the Listener respond with the cache file CacheLoader cacheLoader = new CacheLoader(mListener, result); mListener.setCacheLoader(cacheLoader); cacheLoader.load(); }
/* * This function is used by handleHTTPLoad to allow URL * interception. This can be used to provide alternative load * methods such as locally stored versions or for debugging. * * Returns true if the response was handled by UrlIntercept. */ private boolean handleUrlIntercept() { // Check if the URL can be served from UrlIntercept. If // successful, return the data just like a cache hit. PluginData data = UrlInterceptRegistry.getPluginData(mListener.url(), mHeaders); if (data != null) { PluginContentLoader loader = new PluginContentLoader(mListener, data); loader.load(); return true; } // Not intercepted. Carry on as normal. return false; }
/** * Issues the load request. * * <p>Return value does not indicate if the load was successful or not. It simply indicates that * the load request is reasonable. * * @return true if the load is reasonable. */ public boolean executeLoad() { String url = mListener.url(); // Attempt to decode the percent-encoded url. try { url = new String(URLUtil.decode(url.getBytes())); } catch (IllegalArgumentException e) { // Fail with a bad url error if the decode fails. mListener.error( EventHandler.ERROR_BAD_URL, mListener.getContext().getString(com.android.internal.R.string.httpErrorBadUrl)); return false; } if (URLUtil.isNetworkUrl(url)) { if (mSettings.getBlockNetworkLoads()) { mListener.error( EventHandler.ERROR_BAD_URL, mListener.getContext().getString(com.android.internal.R.string.httpErrorBadUrl)); return false; } mNetwork = Network.getInstance(mListener.getContext()); return handleHTTPLoad(); } else if (handleLocalFile(url, mListener, mSettings)) { return true; } if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader.executeLoad: url protocol not supported:" + mListener.url()); } mListener.error( EventHandler.ERROR_UNSUPPORTED_SCHEME, mListener .getContext() .getText(com.android.internal.R.string.httpErrorUnsupportedScheme) .toString()); return false; }
private boolean handleHTTPLoad() { if (mHeaders == null) { mHeaders = new HashMap<String, String>(); } populateStaticHeaders(); populateHeaders(); // response was handled by UrlIntercept, don't issue HTTP request if (handleUrlIntercept()) return true; // response was handled by Cache, don't issue HTTP request if (handleCache()) { // push the request data down to the LoadListener // as response from the cache could be a redirect // and we may need to initiate a network request if the cache // can't satisfy redirect URL mListener.setRequestData(mMethod, mHeaders, mPostData, mIsHighPriority); return true; } if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: http " + mMethod + " load for: " + mListener.url()); } boolean ret = false; int error = EventHandler.ERROR_UNSUPPORTED_SCHEME; try { ret = mNetwork.requestURL(mMethod, mHeaders, mPostData, mListener, mIsHighPriority); } catch (android.net.ParseException ex) { error = EventHandler.ERROR_BAD_URL; } catch (java.lang.RuntimeException ex) { /* probably an empty header set by javascript. We want the same result as bad URL */ error = EventHandler.ERROR_BAD_URL; } if (!ret) { mListener.error( error, mListener .getContext() .getText(EventHandler.errorStringResources[Math.abs(error)]) .toString()); return false; } return true; }
/* package */ static boolean handleLocalFile(String url, LoadListener loadListener, WebSettings settings) { if (URLUtil.isAssetUrl(url)) { FileLoader.requestUrl( url, loadListener, loadListener.getContext(), true, settings.getAllowFileAccess()); return true; } else if (URLUtil.isFileUrl(url)) { FileLoader.requestUrl( url, loadListener, loadListener.getContext(), false, settings.getAllowFileAccess()); return true; } else if (URLUtil.isContentUrl(url)) { // Send the raw url to the ContentLoader because it will do a // permission check and the url has to match.. ContentLoader.requestUrl(loadListener.url(), loadListener, loadListener.getContext()); return true; } else if (URLUtil.isDataUrl(url)) { DataLoader.requestUrl(url, loadListener); return true; } else if (URLUtil.isAboutUrl(url)) { loadListener.data(mAboutBlank.getBytes(), mAboutBlank.length()); loadListener.endData(); return true; } return false; }
/* * This function is used by the handleHTTPLoad to setup the cache headers * correctly. * Returns true if the response was handled from the cache */ private boolean handleCache() { switch (mCacheMode) { // This mode is normally used for a reload, it instructs the http // loader to not use the cached content. case WebSettings.LOAD_NO_CACHE: break; // This mode is used when the content should only be loaded from // the cache. If it is not there, then fail the load. This is used // to load POST content in a history navigation. case WebSettings.LOAD_CACHE_ONLY: { CacheResult result = CacheManager.getCacheFile(mListener.url(), null); if (result != null) { startCacheLoad(result); } else { // This happens if WebCore was first told that the POST // response was in the cache, then when we try to use it // it has gone. // Generate a file not found error int err = EventHandler.FILE_NOT_FOUND_ERROR; mListener.error( err, mListener .getContext() .getText(EventHandler.errorStringResources[Math.abs(err)]) .toString()); } return true; } // This mode is for when the user is doing a history navigation // in the browser and should returned cached content regardless // of it's state. If it is not in the cache, then go to the // network. case WebSettings.LOAD_CACHE_ELSE_NETWORK: { if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: checking cache: " + mListener.url()); } // Get the cache file name for the current URL, passing null for // the validation headers causes no validation to occur CacheResult result = CacheManager.getCacheFile(mListener.url(), null); if (result != null) { startCacheLoad(result); return true; } break; } // This is the default case, which is to check to see if the // content in the cache can be used. If it can be used, then // use it. If it needs revalidation then the relevant headers // are added to the request. default: case WebSettings.LOAD_NORMAL: return mListener.checkCache(mHeaders); } // end of switch return false; }