Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1638)

Unified Diff: net/http/http_cache.cc

Issue 174039: Http cache: Fix the code that handles 206s when revalidating... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_cache.cc
===================================================================
--- net/http/http_cache.cc (revision 23679)
+++ net/http/http_cache.cc (working copy)
@@ -1126,6 +1126,23 @@
return true;
}
+// We just received some headers from the server. We may have asked for a range,
+// in which case partial_ has an object. This could be the first network request
+// we make to fulfill the original request, or we may be already reading (from
+// the net and / or the cache). If we are not expecting a certain response, we
+// just bypass the cache for this request (but again, maybe we are reading), and
+// delete partial_ (so we are not able to "fix" the headers that we return to
+// the user). This results in either a weird response for the caller (we don't
+// expect it after all), or maybe a range that was not exactly what it was asked
+// for.
+//
+// For example, if the original request is for 30KB and we have the last 20KB,
+// we ask the server for the first 10KB. If the resourse has changed, we'll
+// end up forwarding the 200 back to the user (so far so good). However, if
+// we have instead the first 10KB, we end up sending back a byte range response
+// for the first 10KB, because we never asked the server for the last part. It's
+// just too complicated to restart the whole request from this point; and of
+// course, maybe we already returned the headers.
bool HttpCache::Transaction::ValidatePartialResponse(
const HttpResponseHeaders* headers) {
int response_code = headers->response_code();
@@ -1148,30 +1165,38 @@
return false;
}
- // TODO(rvargas): Handle 206 when the current range is already cached.
- bool failure = false;
- if (!partial_content) {
- if (!partial_.get())
- return false;
+ if (!partial_.get()) {
+ // We are not expecting 206 but we may have one.
+ if (partial_content)
+ IgnoreRangeRequest();
- // TODO(rvargas): Do we need to consider other results here?.
- if (response_code == 200 || response_code == 416)
+ return false;
+ }
+
+ // TODO(rvargas): Do we need to consider other results here?.
+ bool failure = response_code == 200 || response_code == 416;
+
+ if (partial_->IsCurrentRangeCached()) {
+ // We asked for "If-None-Match: " so a 206 means a new object.
+ if (partial_content)
failure = true;
- if (!reading_ && failure) {
- // We are expecting 206 or 304 because we asked for a range. Given that
- // the server is refusing the request we'll remove the sparse entry.
- DoomPartialEntry(true);
- mode_ = NONE;
+ if (response_code == 304 && partial_->ResponseHeadersOK(headers))
return false;
- }
+ } else {
+ // We asked for "If-Range: " so a 206 means just another range.
+ if (partial_content && partial_->ResponseHeadersOK(headers))
+ return true;
- if (response_code == 304 && partial_->ResponseHeadersOK(headers))
- return false;
+ // 304 is not expected here, but we'll spare the entry.
}
- if (!failure && partial_.get() && partial_->ResponseHeadersOK(headers))
- return true;
+ if (failure) {
+ // We cannot truncate this entry, it has to be deleted.
+ DoomPartialEntry(true);
+ mode_ = NONE;
+ return false;
+ }
IgnoreRangeRequest();
return false;
@@ -1350,7 +1375,10 @@
if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
cache_->DoomEntry(cache_key_);
} else {
- WriteResponseInfoToEntry();
+ // If we are already reading, we already updated the headers for
+ // this request; doing it again will change Content-Length.
+ if (!reading_)
+ WriteResponseInfoToEntry();
}
if (mode_ == UPDATE) {
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698