summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/LoadListener.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/webkit/LoadListener.java')
-rw-r--r--core/java/android/webkit/LoadListener.java108
1 files changed, 69 insertions, 39 deletions
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 4c17f99..938df95 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -78,7 +78,7 @@ class LoadListener extends Handler implements EventHandler {
private static int sNativeLoaderCount;
- private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(8192);
+ private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder();
private String mUrl;
private WebAddress mUri;
@@ -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<Message>();
}
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;
@@ -522,17 +530,18 @@ class LoadListener extends Handler implements EventHandler {
* IMPORTANT: as this is called from network thread, can't call native
* directly
* XXX: Unlike the other network thread methods, this method can do the
- * work of decoding the data and appending it to the data builder because
- * mDataBuilder is a thread-safe structure.
+ * work of decoding the data and appending it to the data builder.
*/
public void data(byte[] data, int length) {
if (DebugFlags.LOAD_LISTENER) {
Log.v(LOGTAG, "LoadListener.data(): url: " + url());
}
- // Synchronize on mData because commitLoad may write mData to WebCore
- // and we don't want to replace mData or mDataLength at the same time
- // as a write.
+ // The reason isEmpty() and append() need to synchronized together is
+ // because it is possible for getFirstChunk() to be called multiple
+ // times between isEmpty() and append(). This could cause commitLoad()
+ // to finish before processing the newly appended data and no message
+ // will be sent.
boolean sendMessage = false;
synchronized (mDataBuilder) {
sendMessage = mDataBuilder.isEmpty();
@@ -636,7 +645,7 @@ class LoadListener extends Handler implements EventHandler {
*/
boolean checkCache(Map<String, String> 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
@@ -861,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(): " +
@@ -907,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);
@@ -1009,28 +1023,34 @@ class LoadListener extends Handler implements EventHandler {
if (mIsMainPageLoader) {
String type = sCertificateTypeMap.get(mMimeType);
if (type != null) {
- // In the case of downloading certificate, we will save it to
- // the KeyStore and stop the current loading so that it will not
- // generate a new history page
- byte[] cert = new byte[mDataBuilder.getByteSize()];
- int offset = 0;
- while (true) {
- ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk();
- if (c == null) break;
-
- if (c.mLength != 0) {
- System.arraycopy(c.mArray, 0, cert, offset, c.mLength);
- offset += c.mLength;
+ // This must be synchronized so that no more data can be added
+ // after getByteSize returns.
+ synchronized (mDataBuilder) {
+ // In the case of downloading certificate, we will save it
+ // to the KeyStore and stop the current loading so that it
+ // will not generate a new history page
+ byte[] cert = new byte[mDataBuilder.getByteSize()];
+ int offset = 0;
+ while (true) {
+ ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk();
+ if (c == null) break;
+
+ if (c.mLength != 0) {
+ System.arraycopy(c.mArray, 0, cert, offset, c.mLength);
+ offset += c.mLength;
+ }
+ c.release();
}
- mDataBuilder.releaseChunk(c);
+ CertTool.addCertificate(mContext, type, cert);
+ mBrowserFrame.stopLoading();
+ return;
}
- CertTool.addCertificate(mContext, type, cert);
- mBrowserFrame.stopLoading();
- return;
}
}
- // Give the data to WebKit now
+ // Give the data to WebKit now. We don't have to synchronize on
+ // mDataBuilder here because pulling each chunk removes it from the
+ // internal list so it cannot be modified.
PerfChecker checker = new PerfChecker();
ByteArrayBuilder.Chunk c;
while (true) {
@@ -1047,7 +1067,7 @@ class LoadListener extends Handler implements EventHandler {
}
nativeAddData(c.mArray, c.mLength);
}
- mDataBuilder.releaseChunk(c);
+ c.release();
checker.responseAlert("res nativeAddData");
}
}
@@ -1059,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
@@ -1187,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;
}
@@ -1210,8 +1231,17 @@ class LoadListener extends Handler implements EventHandler {
// mRequestHandle can be null when the request was satisfied
// by the cache, and the cache returned a redirect
if (mRequestHandle != null) {
- mRequestHandle.setupRedirect(mUrl, mStatusCode,
- mRequestHeaders);
+ try {
+ mRequestHandle.setupRedirect(mUrl, mStatusCode,
+ mRequestHeaders);
+ } catch(RuntimeException e) {
+ Log.e(LOGTAG, e.getMessage());
+ // Signal a bad url error if we could not load the
+ // redirection.
+ handleError(EventHandler.ERROR_BAD_URL,
+ mContext.getString(R.string.httpErrorBadUrl));
+ return;
+ }
} else {
// If the original request came from the cache, there is no
// RequestHandle, we have to create a new one through