diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index d1db35e8151a0..e6e26fa8a0f0d 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -541,6 +541,7 @@ class BrowserFrame extends Handler { String method, HashMap headers, byte[] postData, + long postDataIdentifier, int cacheMode, boolean synchronous) { PerfChecker checker = new PerfChecker(); @@ -612,8 +613,9 @@ class BrowserFrame extends Handler { } // Create a LoadListener - LoadListener loadListener = LoadListener.getLoadListener(mContext, this, url, - loaderHandle, synchronous, isMainFramePage); + LoadListener loadListener = LoadListener.getLoadListener(mContext, + this, url, loaderHandle, synchronous, isMainFramePage, + postDataIdentifier); mCallbackProxy.onLoadResource(url); diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 75028deac943e..910d7b2cfe773 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -283,16 +283,24 @@ public final class CacheManager { // only called from WebCore thread public static CacheResult getCacheFile(String url, Map headers) { + return getCacheFile(url, 0, headers); + } + + // only called from WebCore thread + static CacheResult getCacheFile(String url, long postIdentifier, + Map headers) { if (mDisabled) { return null; } - CacheResult result = mDataBase.getCache(url); + String databaseKey = getDatabaseKey(url, postIdentifier); + + CacheResult result = mDataBase.getCache(databaseKey); if (result != null) { if (result.contentLength == 0) { if (!checkCacheRedirect(result.httpStatusCode)) { // this should not happen. If it does, remove it. - mDataBase.removeCache(url); + mDataBase.removeCache(databaseKey); return null; } } else { @@ -304,7 +312,7 @@ public final class CacheManager { } catch (FileNotFoundException e) { // the files in the cache directory can be removed by the // system. If it is gone, clean up the database - mDataBase.removeCache(url); + mDataBase.removeCache(databaseKey); return null; } } @@ -352,14 +360,24 @@ public final class CacheManager { // only called from WebCore thread public static CacheResult createCacheFile(String url, int statusCode, Headers headers, String mimeType, boolean forceCache) { + return createCacheFile(url, statusCode, headers, mimeType, 0, + forceCache); + } + + // only called from WebCore thread + static CacheResult createCacheFile(String url, int statusCode, + Headers headers, String mimeType, long postIdentifier, + boolean forceCache) { if (!forceCache && mDisabled) { return null; } + String databaseKey = getDatabaseKey(url, postIdentifier); + // according to the rfc 2616, the 303 response MUST NOT be cached. if (statusCode == 303) { // remove the saved cache if there is any - mDataBase.removeCache(url); + mDataBase.removeCache(databaseKey); return null; } @@ -367,7 +385,7 @@ public final class CacheManager { // header. if (checkCacheRedirect(statusCode) && !headers.getSetCookie().isEmpty()) { // remove the saved cache if there is any - mDataBase.removeCache(url); + mDataBase.removeCache(databaseKey); return null; } @@ -375,9 +393,9 @@ public final class CacheManager { if (ret == null) { // this should only happen if the headers has "no-store" in the // cache-control. remove the saved cache if there is any - mDataBase.removeCache(url); + mDataBase.removeCache(databaseKey); } else { - setupFiles(url, ret); + setupFiles(databaseKey, ret); try { ret.outStream = new FileOutputStream(ret.outFile); } catch (FileNotFoundException e) { @@ -408,6 +426,12 @@ public final class CacheManager { */ // only called from WebCore thread public static void saveCacheFile(String url, CacheResult cacheRet) { + saveCacheFile(url, 0, cacheRet); + } + + // only called from WebCore thread + static void saveCacheFile(String url, long postIdentifier, + CacheResult cacheRet) { try { cacheRet.outStream.close(); } catch (IOException e) { @@ -434,7 +458,7 @@ public final class CacheManager { return; } - mDataBase.addCache(url, cacheRet); + mDataBase.addCache(getDatabaseKey(url, postIdentifier), cacheRet); if (DebugFlags.CACHE_MANAGER) { Log.v(LOGTAG, "saveCacheFile for url " + url); @@ -513,6 +537,11 @@ public final class CacheManager { } } + private static String getDatabaseKey(String url, long postIdentifier) { + if (postIdentifier == 0) return url; + return postIdentifier + url; + } + @SuppressWarnings("deprecation") private static void setupFiles(String url, CacheResult cacheRet) { if (true) { diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java index c1eeb3b2a0b70..c3dac6e0bc89d 100644 --- a/core/java/android/webkit/FrameLoader.java +++ b/core/java/android/webkit/FrameLoader.java @@ -242,7 +242,7 @@ class FrameLoader { // to load POST content in a history navigation. case WebSettings.LOAD_CACHE_ONLY: { CacheResult result = CacheManager.getCacheFile(mListener.url(), - null); + mListener.postIdentifier(), null); if (result != null) { startCacheLoad(result); } else { @@ -270,7 +270,7 @@ class FrameLoader { // 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); + mListener.postIdentifier(), null); if (result != null) { startCacheLoad(result); return true; diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 5c0ce3c08faf4..938df9583dadf 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -104,6 +104,7 @@ class LoadListener extends Handler implements EventHandler { private SslError mSslError; private RequestHandle mRequestHandle; private RequestHandle mSslErrorRequestHandle; + private long mPostIdentifier; // Request data. It is only valid when we are doing a load from the // cache. It is needed if the cache returns a redirect @@ -123,13 +124,13 @@ class LoadListener extends Handler implements EventHandler { // Public functions // ========================================================================= - public static LoadListener getLoadListener( - Context context, BrowserFrame frame, String url, - int nativeLoader, boolean synchronous, boolean isMainPageLoader) { + public static LoadListener getLoadListener(Context context, + BrowserFrame frame, String url, int nativeLoader, + boolean synchronous, boolean isMainPageLoader, long postIdentifier) { sNativeLoaderCount += 1; - return new LoadListener( - context, frame, url, nativeLoader, synchronous, isMainPageLoader); + return new LoadListener(context, frame, url, nativeLoader, synchronous, + isMainPageLoader, postIdentifier); } public static int getNativeLoaderCount() { @@ -137,7 +138,8 @@ class LoadListener extends Handler implements EventHandler { } LoadListener(Context context, BrowserFrame frame, String url, - int nativeLoader, boolean synchronous, boolean isMainPageLoader) { + int nativeLoader, boolean synchronous, boolean isMainPageLoader, + long postIdentifier) { if (DebugFlags.LOAD_LISTENER) { Log.v(LOGTAG, "LoadListener constructor url=" + url); } @@ -150,6 +152,7 @@ class LoadListener extends Handler implements EventHandler { mMessageQueue = new Vector(); } mIsMainPageLoader = isMainPageLoader; + mPostIdentifier = postIdentifier; } /** @@ -408,9 +411,14 @@ class LoadListener extends Handler implements EventHandler { mStatusCode == HTTP_MOVED_PERMANENTLY || mStatusCode == HTTP_TEMPORARY_REDIRECT) && mNativeLoader != 0) { - if (!mFromCache && mRequestHandle != null) { + // for POST request, only cache the result if there is an identifier + // associated with it. postUrl() or form submission should set the + // identifier while XHR POST doesn't. + if (!mFromCache && mRequestHandle != null + && (!mRequestHandle.getMethod().equals("POST") + || mPostIdentifier != 0)) { mCacheResult = CacheManager.createCacheFile(mUrl, mStatusCode, - headers, mMimeType, false); + headers, mMimeType, mPostIdentifier, false); } if (mCacheResult != null) { mCacheResult.encoding = mEncoding; @@ -637,7 +645,7 @@ class LoadListener extends Handler implements EventHandler { */ boolean checkCache(Map headers) { // Get the cache file name for the current URL - CacheResult result = CacheManager.getCacheFile(url(), + CacheResult result = CacheManager.getCacheFile(url(), mPostIdentifier, headers); // Go ahead and set the cache loader to null in case the result is @@ -862,6 +870,10 @@ class LoadListener extends Handler implements EventHandler { } } + long postIdentifier() { + return mPostIdentifier; + } + void attachRequestHandle(RequestHandle requestHandle) { if (DebugFlags.LOAD_LISTENER) { Log.v(LOGTAG, "LoadListener.attachRequestHandle(): " + @@ -908,8 +920,9 @@ class LoadListener extends Handler implements EventHandler { * be used. This is just for forward/back navigation to a POST * URL. */ - static boolean willLoadFromCache(String url) { - boolean inCache = CacheManager.getCacheFile(url, null) != null; + static boolean willLoadFromCache(String url, long identifier) { + boolean inCache = + CacheManager.getCacheFile(url, identifier, null) != null; if (DebugFlags.LOAD_LISTENER) { Log.v(LOGTAG, "willLoadFromCache: " + url + " in cache: " + inCache); @@ -1066,7 +1079,7 @@ class LoadListener extends Handler implements EventHandler { void tearDown() { if (mCacheResult != null) { if (getErrorID() == OK) { - CacheManager.saveCacheFile(mUrl, mCacheResult); + CacheManager.saveCacheFile(mUrl, mPostIdentifier, mCacheResult); } // we need to reset mCacheResult to be null @@ -1194,7 +1207,8 @@ class LoadListener extends Handler implements EventHandler { // Cache the redirect response if (mCacheResult != null) { if (getErrorID() == OK) { - CacheManager.saveCacheFile(mUrl, mCacheResult); + CacheManager.saveCacheFile(mUrl, mPostIdentifier, + mCacheResult); } mCacheResult = null; }