Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/appcache/appcache_update_job.h" | 5 #include "content/browser/appcache/appcache_update_job.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 } | 177 } |
| 178 | 178 |
| 179 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( | 179 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( |
| 180 net::URLRequest* request, | 180 net::URLRequest* request, |
| 181 const net::RedirectInfo& redirect_info, | 181 const net::RedirectInfo& redirect_info, |
| 182 bool* defer_redirect) { | 182 bool* defer_redirect) { |
| 183 DCHECK_EQ(request_.get(), request); | 183 DCHECK_EQ(request_.get(), request); |
| 184 // Redirect is not allowed by the update process. | 184 // Redirect is not allowed by the update process. |
| 185 job_->MadeProgress(); | 185 job_->MadeProgress(); |
| 186 redirect_response_code_ = request->GetResponseCode(); | 186 redirect_response_code_ = request->GetResponseCode(); |
| 187 request->Cancel(); | 187 int result = request->Cancel(); |
| 188 result_ = REDIRECT_ERROR; | 188 result_ = REDIRECT_ERROR; |
| 189 OnResponseCompleted(); | 189 OnResponseCompleted(result); |
|
michaeln
2016/09/07 20:49:39
I think i'd prefer to see net::ERR_ABORTED explici
maksims (do not use this acc)
2016/09/12 12:45:58
I can use net::ERR_ABORTED here, but if there were
michaeln
2016/09/12 20:14:02
Thnx
This class is explicitly choosing to abort t
| |
| 190 } | 190 } |
| 191 | 191 |
| 192 void AppCacheUpdateJob::URLFetcher::OnResponseStarted( | 192 void AppCacheUpdateJob::URLFetcher::OnResponseStarted(net::URLRequest* request, |
| 193 net::URLRequest *request) { | 193 int net_error) { |
| 194 DCHECK_EQ(request_.get(), request); | 194 DCHECK_EQ(request_.get(), request); |
| 195 DCHECK_NE(net::ERR_IO_PENDING, net_error); | |
| 196 | |
| 195 int response_code = -1; | 197 int response_code = -1; |
| 196 if (request->status().is_success()) { | 198 if (net_error == net::OK) { |
| 197 response_code = request->GetResponseCode(); | 199 response_code = request->GetResponseCode(); |
| 198 job_->MadeProgress(); | 200 job_->MadeProgress(); |
| 199 } | 201 } |
| 200 | 202 |
| 201 if ((response_code / 100) != 2) { | 203 if ((response_code / 100) != 2) { |
| 202 if (response_code > 0) | 204 if (response_code > 0) |
| 203 result_ = SERVER_ERROR; | 205 result_ = SERVER_ERROR; |
| 204 else | 206 else |
| 205 result_ = NETWORK_ERROR; | 207 result_ = NETWORK_ERROR; |
| 206 OnResponseCompleted(); | 208 OnResponseCompleted(net_error); |
| 207 return; | 209 return; |
| 208 } | 210 } |
| 209 | 211 |
| 210 if (url_.SchemeIsCryptographic()) { | 212 if (url_.SchemeIsCryptographic()) { |
| 211 // Do not cache content with cert errors. | 213 // Do not cache content with cert errors. |
| 212 // Also, we willfully violate the HTML5 spec at this point in order | 214 // Also, we willfully violate the HTML5 spec at this point in order |
| 213 // to support the appcaching of cross-origin HTTPS resources. | 215 // to support the appcaching of cross-origin HTTPS resources. |
| 214 // We've opted for a milder constraint and allow caching unless | 216 // We've opted for a milder constraint and allow caching unless |
| 215 // the resource has a "no-store" header. A spec change has been | 217 // the resource has a "no-store" header. A spec change has been |
| 216 // requested on the whatwg list. | 218 // requested on the whatwg list. |
| 217 // See http://code.google.com/p/chromium/issues/detail?id=69594 | 219 // See http://code.google.com/p/chromium/issues/detail?id=69594 |
| 218 // TODO(michaeln): Consider doing this for cross-origin HTTP too. | 220 // TODO(michaeln): Consider doing this for cross-origin HTTP too. |
| 219 const net::HttpNetworkSession::Params* session_params = | 221 const net::HttpNetworkSession::Params* session_params = |
| 220 request->context()->GetNetworkSessionParams(); | 222 request->context()->GetNetworkSessionParams(); |
| 221 bool ignore_cert_errors = session_params && | 223 bool ignore_cert_errors = session_params && |
| 222 session_params->ignore_certificate_errors; | 224 session_params->ignore_certificate_errors; |
| 223 if ((net::IsCertStatusError(request->ssl_info().cert_status) && | 225 if ((net::IsCertStatusError(request->ssl_info().cert_status) && |
| 224 !ignore_cert_errors) || | 226 !ignore_cert_errors) || |
| 225 (url_.GetOrigin() != job_->manifest_url_.GetOrigin() && | 227 (url_.GetOrigin() != job_->manifest_url_.GetOrigin() && |
| 226 request->response_headers()-> | 228 request->response_headers()-> |
| 227 HasHeaderValue("cache-control", "no-store"))) { | 229 HasHeaderValue("cache-control", "no-store"))) { |
| 228 DCHECK_EQ(-1, redirect_response_code_); | 230 DCHECK_EQ(-1, redirect_response_code_); |
| 229 request->Cancel(); | 231 int result = request->Cancel(); |
| 230 result_ = SECURITY_ERROR; | 232 result_ = SECURITY_ERROR; |
| 231 OnResponseCompleted(); | 233 OnResponseCompleted(result); |
|
michaeln
2016/09/07 20:49:39
ditto preference for net::ERR_ABORTED
maksims (do not use this acc)
2016/09/12 12:45:58
Done.
| |
| 232 return; | 234 return; |
| 233 } | 235 } |
| 234 } | 236 } |
| 235 | 237 |
| 236 // Write response info to storage for URL fetches. Wait for async write | 238 // Write response info to storage for URL fetches. Wait for async write |
| 237 // completion before reading any response data. | 239 // completion before reading any response data. |
| 238 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { | 240 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { |
| 239 response_writer_.reset(job_->CreateResponseWriter()); | 241 response_writer_.reset(job_->CreateResponseWriter()); |
| 240 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 242 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
| 241 new HttpResponseInfoIOBuffer( | 243 new HttpResponseInfoIOBuffer( |
| 242 new net::HttpResponseInfo(request->response_info()))); | 244 new net::HttpResponseInfo(request->response_info()))); |
| 243 response_writer_->WriteInfo( | 245 response_writer_->WriteInfo( |
| 244 io_buffer.get(), | 246 io_buffer.get(), |
| 245 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); | 247 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
| 246 } else { | 248 } else { |
| 247 ReadResponseData(); | 249 ReadResponseData(); |
| 248 } | 250 } |
| 249 } | 251 } |
| 250 | 252 |
| 251 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( | 253 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( |
| 252 net::URLRequest* request, int bytes_read) { | 254 net::URLRequest* request, int bytes_read) { |
|
michaeln
2016/09/07 20:49:39
maybe DCHECK_NE(net::ERR_IO_PENDING, bytes_read) f
maksims (do not use this acc)
2016/09/12 12:45:58
Done.
| |
| 253 DCHECK_EQ(request_.get(), request); | 255 DCHECK_EQ(request_.get(), request); |
| 254 bool data_consumed = true; | 256 bool data_consumed = true; |
| 255 if (request->status().is_success() && bytes_read > 0) { | 257 if (bytes_read > 0) { |
| 256 job_->MadeProgress(); | 258 job_->MadeProgress(); |
| 257 data_consumed = ConsumeResponseData(bytes_read); | 259 data_consumed = ConsumeResponseData(bytes_read); |
| 258 if (data_consumed) { | 260 if (data_consumed) { |
| 259 bytes_read = 0; | 261 bytes_read = 0; |
| 260 while (request->Read(buffer_.get(), kBufferSize, &bytes_read)) { | 262 while (bytes_read > 0) { |
|
michaeln
2016/09/07 20:49:39
somethings off here, the body of the while loop wh
maksims (do not use this acc)
2016/09/12 12:45:58
Yes, I've forgotten to remove that line. Thanks!
| |
| 263 bytes_read = request->Read(buffer_.get(), kBufferSize); | |
| 261 if (bytes_read > 0) { | 264 if (bytes_read > 0) { |
| 262 data_consumed = ConsumeResponseData(bytes_read); | 265 data_consumed = ConsumeResponseData(bytes_read); |
| 263 if (!data_consumed) | 266 if (!data_consumed) |
| 264 break; // wait for async data processing, then read more | 267 break; // wait for async data processing, then read more |
| 265 } else { | |
| 266 break; | |
| 267 } | 268 } |
| 268 } | 269 } |
| 269 } | 270 } |
| 270 } | 271 } |
| 271 if (data_consumed && !request->status().is_io_pending()) { | 272 |
| 273 if (data_consumed && bytes_read != net::ERR_IO_PENDING) { | |
| 272 DCHECK_EQ(UPDATE_OK, result_); | 274 DCHECK_EQ(UPDATE_OK, result_); |
| 273 OnResponseCompleted(); | 275 OnResponseCompleted(bytes_read); |
| 274 } | 276 } |
| 275 } | 277 } |
| 276 | 278 |
| 277 void AppCacheUpdateJob::URLFetcher::AddConditionalHeaders( | 279 void AppCacheUpdateJob::URLFetcher::AddConditionalHeaders( |
| 278 const net::HttpResponseHeaders* headers) { | 280 const net::HttpResponseHeaders* headers) { |
| 279 DCHECK(request_); | 281 DCHECK(request_); |
| 280 DCHECK(headers); | 282 DCHECK(headers); |
| 281 net::HttpRequestHeaders extra_headers; | 283 net::HttpRequestHeaders extra_headers; |
| 282 | 284 |
| 283 // Add If-Modified-Since header if response info has Last-Modified header. | 285 // Add If-Modified-Since header if response info has Last-Modified header. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 296 if (!etag_value.empty()) { | 298 if (!etag_value.empty()) { |
| 297 extra_headers.SetHeader(net::HttpRequestHeaders::kIfNoneMatch, | 299 extra_headers.SetHeader(net::HttpRequestHeaders::kIfNoneMatch, |
| 298 etag_value); | 300 etag_value); |
| 299 } | 301 } |
| 300 if (!extra_headers.IsEmpty()) | 302 if (!extra_headers.IsEmpty()) |
| 301 request_->SetExtraRequestHeaders(extra_headers); | 303 request_->SetExtraRequestHeaders(extra_headers); |
| 302 } | 304 } |
| 303 | 305 |
| 304 void AppCacheUpdateJob::URLFetcher::OnWriteComplete(int result) { | 306 void AppCacheUpdateJob::URLFetcher::OnWriteComplete(int result) { |
| 305 if (result < 0) { | 307 if (result < 0) { |
| 306 request_->Cancel(); | 308 int result = request_->Cancel(); |
| 307 result_ = DISKCACHE_ERROR; | 309 result_ = DISKCACHE_ERROR; |
| 308 OnResponseCompleted(); | 310 OnResponseCompleted(result); |
|
michaeln
2016/09/07 20:49:39
ditto pref for net::ERR_ABORTED
maksims (do not use this acc)
2016/09/12 12:45:58
Done.
| |
| 309 return; | 311 return; |
| 310 } | 312 } |
| 311 ReadResponseData(); | 313 ReadResponseData(); |
| 312 } | 314 } |
| 313 | 315 |
| 314 void AppCacheUpdateJob::URLFetcher::ReadResponseData() { | 316 void AppCacheUpdateJob::URLFetcher::ReadResponseData() { |
| 315 InternalUpdateState state = job_->internal_state_; | 317 InternalUpdateState state = job_->internal_state_; |
| 316 if (state == CACHE_FAILURE || state == CANCELLED || state == COMPLETED) | 318 if (state == CACHE_FAILURE || state == CANCELLED || state == COMPLETED) |
| 317 return; | 319 return; |
| 318 int bytes_read = 0; | 320 int bytes_read = request_->Read(buffer_.get(), kBufferSize); |
| 319 request_->Read(buffer_.get(), kBufferSize, &bytes_read); | |
| 320 OnReadCompleted(request_.get(), bytes_read); | 321 OnReadCompleted(request_.get(), bytes_read); |
|
michaeln
2016/09/07 20:49:39
maybe avoid calling this if byte_read == IO_PENDIN
maksims (do not use this acc)
2016/09/12 12:45:58
Yes, sure. You're right. But as I noticed not all
| |
| 321 } | 322 } |
| 322 | 323 |
| 323 // Returns false if response data is processed asynchronously, in which | 324 // Returns false if response data is processed asynchronously, in which |
| 324 // case ReadResponseData will be invoked when it is safe to continue | 325 // case ReadResponseData will be invoked when it is safe to continue |
| 325 // reading more response data from the request. | 326 // reading more response data from the request. |
| 326 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { | 327 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { |
| 327 DCHECK_GT(bytes_read, 0); | 328 DCHECK_GT(bytes_read, 0); |
| 328 switch (fetch_type_) { | 329 switch (fetch_type_) { |
| 329 case MANIFEST_FETCH: | 330 case MANIFEST_FETCH: |
| 330 case MANIFEST_REFETCH: | 331 case MANIFEST_REFETCH: |
| 331 manifest_data_.append(buffer_->data(), bytes_read); | 332 manifest_data_.append(buffer_->data(), bytes_read); |
| 332 break; | 333 break; |
| 333 case URL_FETCH: | 334 case URL_FETCH: |
| 334 case MASTER_ENTRY_FETCH: | 335 case MASTER_ENTRY_FETCH: |
| 335 DCHECK(response_writer_.get()); | 336 DCHECK(response_writer_.get()); |
| 336 response_writer_->WriteData( | 337 response_writer_->WriteData( |
| 337 buffer_.get(), | 338 buffer_.get(), |
| 338 bytes_read, | 339 bytes_read, |
| 339 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); | 340 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
| 340 return false; // wait for async write completion to continue reading | 341 return false; // wait for async write completion to continue reading |
| 341 default: | 342 default: |
| 342 NOTREACHED(); | 343 NOTREACHED(); |
| 343 } | 344 } |
| 344 return true; | 345 return true; |
| 345 } | 346 } |
| 346 | 347 |
| 347 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { | 348 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted(int net_error) { |
| 348 if (request_->status().is_success()) | 349 if (net_error == net::OK) |
| 349 job_->MadeProgress(); | 350 job_->MadeProgress(); |
| 350 | 351 |
| 351 // Retry for 503s where retry-after is 0. | 352 // Retry for 503s where retry-after is 0. |
| 352 if (request_->status().is_success() && | 353 if (net_error == net::OK && request_->GetResponseCode() == 503 && |
| 353 request_->GetResponseCode() == 503 && | |
| 354 MaybeRetryRequest()) { | 354 MaybeRetryRequest()) { |
| 355 return; | 355 return; |
| 356 } | 356 } |
| 357 | 357 |
| 358 switch (fetch_type_) { | 358 switch (fetch_type_) { |
| 359 case MANIFEST_FETCH: | 359 case MANIFEST_FETCH: |
| 360 job_->HandleManifestFetchCompleted(this); | 360 job_->HandleManifestFetchCompleted(this, net_error); |
| 361 break; | 361 break; |
| 362 case URL_FETCH: | 362 case URL_FETCH: |
| 363 job_->HandleUrlFetchCompleted(this); | 363 job_->HandleUrlFetchCompleted(this, net_error); |
| 364 break; | 364 break; |
| 365 case MASTER_ENTRY_FETCH: | 365 case MASTER_ENTRY_FETCH: |
| 366 job_->HandleMasterEntryFetchCompleted(this); | 366 job_->HandleMasterEntryFetchCompleted(this, net_error); |
| 367 break; | 367 break; |
| 368 case MANIFEST_REFETCH: | 368 case MANIFEST_REFETCH: |
| 369 job_->HandleManifestRefetchCompleted(this); | 369 job_->HandleManifestRefetchCompleted(this, net_error); |
| 370 break; | 370 break; |
| 371 default: | 371 default: |
| 372 NOTREACHED(); | 372 NOTREACHED(); |
| 373 } | 373 } |
| 374 | 374 |
| 375 delete this; | 375 delete this; |
| 376 } | 376 } |
| 377 | 377 |
| 378 bool AppCacheUpdateJob::URLFetcher::MaybeRetryRequest() { | 378 bool AppCacheUpdateJob::URLFetcher::MaybeRetryRequest() { |
| 379 if (retry_503_attempts_ >= kMax503Retries || | 379 if (retry_503_attempts_ >= kMax503Retries || |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 return; | 572 return; |
| 573 } | 573 } |
| 574 | 574 |
| 575 DCHECK(internal_state_ == REFETCH_MANIFEST); | 575 DCHECK(internal_state_ == REFETCH_MANIFEST); |
| 576 DCHECK(manifest_response_info_.get()); | 576 DCHECK(manifest_response_info_.get()); |
| 577 manifest_fetcher_->set_existing_response_headers( | 577 manifest_fetcher_->set_existing_response_headers( |
| 578 manifest_response_info_->headers.get()); | 578 manifest_response_info_->headers.get()); |
| 579 manifest_fetcher_->Start(); | 579 manifest_fetcher_->Start(); |
| 580 } | 580 } |
| 581 | 581 |
| 582 | 582 void AppCacheUpdateJob::HandleManifestFetchCompleted(URLFetcher* fetcher, |
| 583 void AppCacheUpdateJob::HandleManifestFetchCompleted( | 583 int net_error) { |
| 584 URLFetcher* fetcher) { | |
| 585 DCHECK_EQ(internal_state_, FETCH_MANIFEST); | 584 DCHECK_EQ(internal_state_, FETCH_MANIFEST); |
| 586 DCHECK_EQ(manifest_fetcher_, fetcher); | 585 DCHECK_EQ(manifest_fetcher_, fetcher); |
| 586 | |
| 587 manifest_fetcher_ = NULL; | 587 manifest_fetcher_ = NULL; |
| 588 | 588 |
| 589 net::URLRequest* request = fetcher->request(); | 589 net::URLRequest* request = fetcher->request(); |
| 590 int response_code = -1; | 590 int response_code = -1; |
| 591 bool is_valid_response_code = false; | 591 bool is_valid_response_code = false; |
| 592 if (request->status().is_success()) { | 592 if (net_error == net::OK) { |
| 593 response_code = request->GetResponseCode(); | 593 response_code = request->GetResponseCode(); |
| 594 is_valid_response_code = (response_code / 100 == 2); | 594 is_valid_response_code = (response_code / 100 == 2); |
| 595 | 595 |
| 596 std::string mime_type; | 596 std::string mime_type; |
| 597 request->GetMimeType(&mime_type); | 597 request->GetMimeType(&mime_type); |
| 598 manifest_has_valid_mime_type_ = (mime_type == "text/cache-manifest"); | 598 manifest_has_valid_mime_type_ = (mime_type == "text/cache-manifest"); |
| 599 } | 599 } |
| 600 | 600 |
| 601 if (is_valid_response_code) { | 601 if (is_valid_response_code) { |
| 602 manifest_data_ = fetcher->manifest_data(); | 602 manifest_data_ = fetcher->manifest_data(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 LogConsoleMessageToAll(message); | 710 LogConsoleMessageToAll(message); |
| 711 } | 711 } |
| 712 | 712 |
| 713 group_->SetUpdateAppCacheStatus(AppCacheGroup::DOWNLOADING); | 713 group_->SetUpdateAppCacheStatus(AppCacheGroup::DOWNLOADING); |
| 714 NotifyAllAssociatedHosts(APPCACHE_DOWNLOADING_EVENT); | 714 NotifyAllAssociatedHosts(APPCACHE_DOWNLOADING_EVENT); |
| 715 FetchUrls(); | 715 FetchUrls(); |
| 716 FetchMasterEntries(); | 716 FetchMasterEntries(); |
| 717 MaybeCompleteUpdate(); // if not done, continues when async fetches complete | 717 MaybeCompleteUpdate(); // if not done, continues when async fetches complete |
| 718 } | 718 } |
| 719 | 719 |
| 720 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { | 720 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher, |
| 721 int net_error) { | |
| 721 DCHECK(internal_state_ == DOWNLOADING); | 722 DCHECK(internal_state_ == DOWNLOADING); |
| 722 | 723 |
| 723 net::URLRequest* request = fetcher->request(); | 724 net::URLRequest* request = fetcher->request(); |
| 724 const GURL& url = request->original_url(); | 725 const GURL& url = request->original_url(); |
| 725 pending_url_fetches_.erase(url); | 726 pending_url_fetches_.erase(url); |
| 726 NotifyAllProgress(url); | 727 NotifyAllProgress(url); |
| 727 ++url_fetches_completed_; | 728 ++url_fetches_completed_; |
| 728 | 729 |
| 729 int response_code = request->status().is_success() | 730 int response_code = net_error == net::OK ? request->GetResponseCode() |
| 730 ? request->GetResponseCode() | 731 : fetcher->redirect_response_code(); |
| 731 : fetcher->redirect_response_code(); | |
| 732 | 732 |
| 733 AppCacheEntry& entry = url_file_list_.find(url)->second; | 733 AppCacheEntry& entry = url_file_list_.find(url)->second; |
| 734 | 734 |
| 735 if (response_code / 100 == 2) { | 735 if (response_code / 100 == 2) { |
| 736 // Associate storage with the new entry. | 736 // Associate storage with the new entry. |
| 737 DCHECK(fetcher->response_writer()); | 737 DCHECK(fetcher->response_writer()); |
| 738 entry.set_response_id(fetcher->response_writer()->response_id()); | 738 entry.set_response_id(fetcher->response_writer()->response_id()); |
| 739 entry.set_response_size(fetcher->response_writer()->amount_written()); | 739 entry.set_response_size(fetcher->response_writer()->amount_written()); |
| 740 if (!inprogress_cache_->AddOrModifyEntry(url, entry)) | 740 if (!inprogress_cache_->AddOrModifyEntry(url, entry)) |
| 741 duplicate_response_ids_.push_back(entry.response_id()); | 741 duplicate_response_ids_.push_back(entry.response_id()); |
| 742 | 742 |
| 743 // TODO(michaeln): Check for <html manifest=xxx> | 743 // TODO(michaeln): Check for <html manifest=xxx> |
| 744 // See http://code.google.com/p/chromium/issues/detail?id=97930 | 744 // See http://code.google.com/p/chromium/issues/detail?id=97930 |
| 745 // if (entry.IsMaster() && !(entry.IsExplicit() || fallback || intercept)) | 745 // if (entry.IsMaster() && !(entry.IsExplicit() || fallback || intercept)) |
| 746 // if (!manifestAttribute) skip it | 746 // if (!manifestAttribute) skip it |
| 747 | 747 |
| 748 // Foreign entries will be detected during cache selection. | 748 // Foreign entries will be detected during cache selection. |
| 749 // Note: 6.9.4, step 17.9 possible optimization: if resource is HTML or XML | 749 // Note: 6.9.4, step 17.9 possible optimization: if resource is HTML or XML |
| 750 // file whose root element is an html element with a manifest attribute | 750 // file whose root element is an html element with a manifest attribute |
| 751 // whose value doesn't match the manifest url of the application cache | 751 // whose value doesn't match the manifest url of the application cache |
| 752 // being processed, mark the entry as being foreign. | 752 // being processed, mark the entry as being foreign. |
| 753 } else { | 753 } else { |
| 754 VLOG(1) << "Request status: " << request->status().status() | 754 VLOG(1) << "Request error: " << net_error |
| 755 << " error: " << request->status().error() | |
| 756 << " response code: " << response_code; | 755 << " response code: " << response_code; |
| 757 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { | 756 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { |
| 758 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { | 757 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { |
| 759 // Keep the existing response. | 758 // Keep the existing response. |
| 760 entry.set_response_id(fetcher->existing_entry().response_id()); | 759 entry.set_response_id(fetcher->existing_entry().response_id()); |
| 761 entry.set_response_size(fetcher->existing_entry().response_size()); | 760 entry.set_response_size(fetcher->existing_entry().response_size()); |
| 762 inprogress_cache_->AddOrModifyEntry(url, entry); | 761 inprogress_cache_->AddOrModifyEntry(url, entry); |
| 763 } else { | 762 } else { |
| 764 const char kFormatString[] = "Resource fetch failed (%d) %s"; | 763 const char kFormatString[] = "Resource fetch failed (%d) %s"; |
| 765 std::string message = FormatUrlErrorMessage( | 764 std::string message = FormatUrlErrorMessage( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 inprogress_cache_->AddOrModifyEntry(url, entry); | 806 inprogress_cache_->AddOrModifyEntry(url, entry); |
| 808 } | 807 } |
| 809 } | 808 } |
| 810 | 809 |
| 811 // Fetch another URL now that one request has completed. | 810 // Fetch another URL now that one request has completed. |
| 812 DCHECK(internal_state_ != CACHE_FAILURE); | 811 DCHECK(internal_state_ != CACHE_FAILURE); |
| 813 FetchUrls(); | 812 FetchUrls(); |
| 814 MaybeCompleteUpdate(); | 813 MaybeCompleteUpdate(); |
| 815 } | 814 } |
| 816 | 815 |
| 817 void AppCacheUpdateJob::HandleMasterEntryFetchCompleted( | 816 void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(URLFetcher* fetcher, |
| 818 URLFetcher* fetcher) { | 817 int net_error) { |
| 819 DCHECK(internal_state_ == NO_UPDATE || internal_state_ == DOWNLOADING); | 818 DCHECK(internal_state_ == NO_UPDATE || internal_state_ == DOWNLOADING); |
| 820 | 819 |
| 821 // TODO(jennb): Handle downloads completing during cache failure when update | 820 // TODO(jennb): Handle downloads completing during cache failure when update |
| 822 // no longer fetches master entries directly. For now, we cancel all pending | 821 // no longer fetches master entries directly. For now, we cancel all pending |
| 823 // master entry fetches when entering cache failure state so this will never | 822 // master entry fetches when entering cache failure state so this will never |
| 824 // be called in CACHE_FAILURE state. | 823 // be called in CACHE_FAILURE state. |
| 825 | 824 |
| 826 net::URLRequest* request = fetcher->request(); | 825 net::URLRequest* request = fetcher->request(); |
| 827 const GURL& url = request->original_url(); | 826 const GURL& url = request->original_url(); |
| 828 master_entry_fetches_.erase(url); | 827 master_entry_fetches_.erase(url); |
| 829 ++master_entries_completed_; | 828 ++master_entries_completed_; |
| 830 | 829 |
| 831 int response_code = request->status().is_success() | 830 int response_code = net_error == net::OK ? request->GetResponseCode() : -1; |
| 832 ? request->GetResponseCode() : -1; | |
| 833 | 831 |
| 834 PendingMasters::iterator found = pending_master_entries_.find(url); | 832 PendingMasters::iterator found = pending_master_entries_.find(url); |
| 835 DCHECK(found != pending_master_entries_.end()); | 833 DCHECK(found != pending_master_entries_.end()); |
| 836 PendingHosts& hosts = found->second; | 834 PendingHosts& hosts = found->second; |
| 837 | 835 |
| 838 // Section 6.9.4. No update case: step 7.3, else step 22. | 836 // Section 6.9.4. No update case: step 7.3, else step 22. |
| 839 if (response_code / 100 == 2) { | 837 if (response_code / 100 == 2) { |
| 840 // Add fetched master entry to the appropriate cache. | 838 // Add fetched master entry to the appropriate cache. |
| 841 AppCache* cache = inprogress_cache_.get() ? inprogress_cache_.get() | 839 AppCache* cache = inprogress_cache_.get() ? inprogress_cache_.get() |
| 842 : group_->newest_complete_cache(); | 840 : group_->newest_complete_cache(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 904 return; | 902 return; |
| 905 } | 903 } |
| 906 } | 904 } |
| 907 } | 905 } |
| 908 | 906 |
| 909 DCHECK(internal_state_ != CACHE_FAILURE); | 907 DCHECK(internal_state_ != CACHE_FAILURE); |
| 910 FetchMasterEntries(); | 908 FetchMasterEntries(); |
| 911 MaybeCompleteUpdate(); | 909 MaybeCompleteUpdate(); |
| 912 } | 910 } |
| 913 | 911 |
| 914 void AppCacheUpdateJob::HandleManifestRefetchCompleted( | 912 void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLFetcher* fetcher, |
| 915 URLFetcher* fetcher) { | 913 int net_error) { |
| 916 DCHECK(internal_state_ == REFETCH_MANIFEST); | 914 DCHECK(internal_state_ == REFETCH_MANIFEST); |
| 917 DCHECK(manifest_fetcher_ == fetcher); | 915 DCHECK(manifest_fetcher_ == fetcher); |
| 918 manifest_fetcher_ = NULL; | 916 manifest_fetcher_ = NULL; |
| 919 | 917 |
| 920 net::URLRequest* request = fetcher->request(); | 918 int response_code = |
| 921 int response_code = request->status().is_success() | 919 net_error == net::OK ? fetcher->request()->GetResponseCode() : -1; |
| 922 ? request->GetResponseCode() : -1; | |
| 923 if (response_code == 304 || manifest_data_ == fetcher->manifest_data()) { | 920 if (response_code == 304 || manifest_data_ == fetcher->manifest_data()) { |
| 924 // Only need to store response in storage if manifest is not already | 921 // Only need to store response in storage if manifest is not already |
| 925 // an entry in the cache. | 922 // an entry in the cache. |
| 926 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); | 923 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); |
| 927 if (entry) { | 924 if (entry) { |
| 928 entry->add_types(AppCacheEntry::MANIFEST); | 925 entry->add_types(AppCacheEntry::MANIFEST); |
| 929 StoreGroupAndCache(); | 926 StoreGroupAndCache(); |
| 930 } else { | 927 } else { |
| 931 manifest_response_writer_.reset(CreateResponseWriter()); | 928 manifest_response_writer_.reset(CreateResponseWriter()); |
| 932 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 929 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
| 933 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); | 930 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); |
| 934 manifest_response_writer_->WriteInfo( | 931 manifest_response_writer_->WriteInfo( |
| 935 io_buffer.get(), | 932 io_buffer.get(), |
| 936 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, | 933 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, |
| 937 base::Unretained(this))); | 934 base::Unretained(this))); |
| 938 } | 935 } |
| 939 } else { | 936 } else { |
| 940 VLOG(1) << "Request status: " << request->status().status() | 937 VLOG(1) << "Request error: " << net_error |
| 941 << " error: " << request->status().error() | |
| 942 << " response code: " << response_code; | 938 << " response code: " << response_code; |
| 943 ScheduleUpdateRetry(kRerunDelayMs); | 939 ScheduleUpdateRetry(kRerunDelayMs); |
| 944 if (response_code == 200) { | 940 if (response_code == 200) { |
| 945 HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update", | 941 HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update", |
| 946 APPCACHE_CHANGED_ERROR, | 942 APPCACHE_CHANGED_ERROR, |
| 947 GURL(), | 943 GURL(), |
| 948 0, | 944 0, |
| 949 false /*is_cross_origin*/), | 945 false /*is_cross_origin*/), |
| 950 MANIFEST_ERROR, | 946 MANIFEST_ERROR, |
| 951 GURL()); | 947 GURL()); |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1708 // on this object after we've posted a task to delete ourselves. | 1704 // on this object after we've posted a task to delete ourselves. |
| 1709 if (group_) { | 1705 if (group_) { |
| 1710 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); | 1706 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); |
| 1711 group_ = NULL; | 1707 group_ = NULL; |
| 1712 } | 1708 } |
| 1713 | 1709 |
| 1714 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | 1710 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); |
| 1715 } | 1711 } |
| 1716 | 1712 |
| 1717 } // namespace content | 1713 } // namespace content |
| OLD | NEW |