diff --git a/netwerk/protocol/http/src/nsHttpChannel.cpp b/netwerk/protocol/http/src/nsHttpChannel.cpp index 03563b9da69d..22b494ab962f 100644 --- a/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -449,12 +449,10 @@ nsHttpChannel::ProcessNotModified() rv = mCachedResponseHead->UpdateHeaders(mResponseHead->Headers()); if (NS_FAILED(rv)) return rv; - // update the cached response headers - nsCAutoString headers; - rv = mCachedResponseHead->Flatten(headers, PR_TRUE); - if (NS_FAILED(rv)) return rv; - - rv = mCacheEntry->SetMetaDataElement("http-headers", headers.get()); + // update the cached response head + nsCAutoString head; + mCachedResponseHead->Flatten(head, PR_TRUE); + rv = mCacheEntry->SetMetaDataElement("response-head", head.get()); if (NS_FAILED(rv)) return rv; // make the cached response be the current response @@ -632,13 +630,24 @@ nsHttpChannel::CheckCache() if (!mCacheEntry || !(mCacheAccess & nsICache::ACCESS_READ)) return NS_OK; - // Get the cached HTTP response headers nsXPIDLCString buf; - rv = mCacheEntry->GetMetaDataElement("http-headers", getter_Copies(buf)); - if (NS_FAILED(rv)) { - NS_WARNING("cache entry does not contain http headers!"); - return rv; + + // Get the method that was used to generate the cached response + rv = mCacheEntry->GetMetaDataElement("request-method", getter_Copies(buf)); + if (NS_FAILED(rv)) return rv; + + nsHttpAtom method = nsHttp::ResolveAtom(buf); + if (method == nsHttp::Head) { + // The cached response does not contain an entity. We can only reuse + // the response if the current request is also HEAD. + if (mRequestHead.Method() != nsHttp::Head) + return NS_OK; } + buf = 0; + + // Get the cached HTTP response headers + rv = mCacheEntry->GetMetaDataElement("response-head", getter_Copies(buf)); + if (NS_FAILED(rv)) return rv; // Parse the cached HTTP response headers NS_ASSERTION(!mCachedResponseHead, "memory leak detected"); @@ -647,8 +656,6 @@ nsHttpChannel::CheckCache() return NS_ERROR_OUT_OF_MEMORY; rv = mCachedResponseHead->Parse((char *) buf.get()); if (NS_FAILED(rv)) return rv; - - // we're done with the header buf buf = 0; // If we were only granted read access, then assume the entry is valid. @@ -920,14 +927,16 @@ nsHttpChannel::CacheReceivedResponse() rv = UpdateExpirationTime(); if (NS_FAILED(rv)) return rv; - // Store the received HTTP headers with the cache entry as an element of - // the meta data. - - nsCAutoString headers; - rv = mResponseHead->Flatten(headers, PR_TRUE); + // Store the HTTP request method with the cache entry so we can distinguish + // for example GET and HEAD responses. + rv = mCacheEntry->SetMetaDataElement("request-method", mRequestHead.Method().get()); if (NS_FAILED(rv)) return rv; - rv = mCacheEntry->SetMetaDataElement("http-headers", headers.get()); + // Store the received HTTP head with the cache entry as an element of + // the meta data. + nsCAutoString head; + mResponseHead->Flatten(head, PR_TRUE); + rv = mCacheEntry->SetMetaDataElement("response-head", head.get()); if (NS_FAILED(rv)) return rv; // Open an output stream to the cache entry and insert a listener tee into diff --git a/netwerk/protocol/http/src/nsHttpHeaderArray.cpp b/netwerk/protocol/http/src/nsHttpHeaderArray.cpp index 89eb064b526e..fb9f18152677 100644 --- a/netwerk/protocol/http/src/nsHttpHeaderArray.cpp +++ b/netwerk/protocol/http/src/nsHttpHeaderArray.cpp @@ -102,7 +102,7 @@ nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor) return NS_OK; } -nsresult +void nsHttpHeaderArray::Flatten(nsACString &buf) { PRInt32 i, count = mHeaders.Count(); @@ -113,7 +113,6 @@ nsHttpHeaderArray::Flatten(nsACString &buf) buf.Append(entry->value); buf.Append("\r\n"); } - return NS_OK; } const char * diff --git a/netwerk/protocol/http/src/nsHttpHeaderArray.h b/netwerk/protocol/http/src/nsHttpHeaderArray.h index 03df11c1b5a7..8502e340c7dc 100644 --- a/netwerk/protocol/http/src/nsHttpHeaderArray.h +++ b/netwerk/protocol/http/src/nsHttpHeaderArray.h @@ -43,7 +43,7 @@ public: nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor); - nsresult Flatten(nsACString &); + void Flatten(nsACString &); PRUint32 Count() { return (PRUint32) mHeaders.Count(); } diff --git a/netwerk/protocol/http/src/nsHttpRequestHead.cpp b/netwerk/protocol/http/src/nsHttpRequestHead.cpp index 0fbbf1d373e9..b9dbbb0b1466 100644 --- a/netwerk/protocol/http/src/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/src/nsHttpRequestHead.cpp @@ -27,7 +27,7 @@ // nsHttpRequestHead //----------------------------------------------------------------------------- -nsresult +void nsHttpRequestHead::Flatten(nsACString &buf) { // note: the first append is intentional. @@ -51,7 +51,4 @@ nsHttpRequestHead::Flatten(nsACString &buf) buf.Append("\r\n"); mHeaders.Flatten(buf); - - // do not append the final \r\n - return NS_OK; } diff --git a/netwerk/protocol/http/src/nsHttpRequestHead.h b/netwerk/protocol/http/src/nsHttpRequestHead.h index c7f62f48a3d2..dc7479d8c169 100644 --- a/netwerk/protocol/http/src/nsHttpRequestHead.h +++ b/netwerk/protocol/http/src/nsHttpRequestHead.h @@ -51,9 +51,9 @@ public: const char *PeekHeader(nsHttpAtom h) { return mHeaders.PeekHeader(h); } nsresult SetHeader(nsHttpAtom h, const char *v) { return mHeaders.SetHeader(h, v); } nsresult GetHeader(nsHttpAtom h, char **v) { return mHeaders.GetHeader(h, v); } - void ClearHeaders() { mHeaders.Clear(); } + void ClearHeaders() { mHeaders.Clear(); } - nsresult Flatten(nsACString &); + void Flatten(nsACString &); private: nsHttpHeaderArray mHeaders; diff --git a/netwerk/protocol/http/src/nsHttpResponseHead.cpp b/netwerk/protocol/http/src/nsHttpResponseHead.cpp index d95d2ce7d70a..12715709563d 100644 --- a/netwerk/protocol/http/src/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/src/nsHttpResponseHead.cpp @@ -30,11 +30,11 @@ // nsHttpResponseHead //----------------------------------------------------------------------------- -nsresult +void nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients) { if (mVersion == NS_HTTP_VERSION_0_9) - return NS_OK; + return; buf.Append("HTTP/"); if (mVersion == NS_HTTP_VERSION_1_1) @@ -50,8 +50,10 @@ nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients) buf.Append(mStatusText); buf.Append("\r\n"); - if (!pruneTransients) - return mHeaders.Flatten(buf); + if (!pruneTransients) { + mHeaders.Flatten(buf); + return; + } // otherwise, we need to iterate over the headers and only flatten // those that are appropriate. @@ -79,7 +81,6 @@ nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients) buf.Append(value); buf.Append("\r\n"); } - return NS_OK; } nsresult diff --git a/netwerk/protocol/http/src/nsHttpResponseHead.h b/netwerk/protocol/http/src/nsHttpResponseHead.h index 7bc3759cbcab..9dd982b11be6 100644 --- a/netwerk/protocol/http/src/nsHttpResponseHead.h +++ b/netwerk/protocol/http/src/nsHttpResponseHead.h @@ -59,7 +59,7 @@ public: // write out the response status line and headers as a single text block, // optionally pruning out transient headers (ie. headers that only make // sense the first time the response is handled). - nsresult Flatten(nsACString &, PRBool pruneTransients); + void Flatten(nsACString &, PRBool pruneTransients); // parse flattened response head. block must be null terminated. parsing is // destructive. diff --git a/netwerk/protocol/http/src/nsHttpTransaction.cpp b/netwerk/protocol/http/src/nsHttpTransaction.cpp index 94bbc3920ad8..62c0cb812c75 100644 --- a/netwerk/protocol/http/src/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/src/nsHttpTransaction.cpp @@ -84,9 +84,7 @@ nsHttpTransaction::SetupRequest(nsHttpRequestHead *requestHead, mNoContent = PR_TRUE; mReqHeaderBuf.SetLength(0); - - rv = requestHead->Flatten(mReqHeaderBuf); - if (NS_FAILED(rv)) return rv; + requestHead->Flatten(mReqHeaderBuf); LOG2(("http request [\n%s]\n", mReqHeaderBuf.get()));