resource_loader.cc revision 4311e82a78ceafbe0585f51d4c8a86df9f21aa0d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_loader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 94311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include "base/metrics/histogram.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/doomed_resource_handler.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_loader_delegate.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_request_info_impl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/ssl/ssl_client_auth_handler.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/ssl/ssl_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/ssl_status_serialization.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/cert_store.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_dispatcher_host_login_delegate.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/site_instance.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/process_type.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/resource_response.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/client_cert_store.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/client_cert_store_impl.h" 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_interceptor.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PopulateResourceResponse(net::URLRequest* request, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceResponse* response) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.error_code = request->status().error(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.request_time = request->request_time(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.response_time = request->response_time(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.headers = request->response_headers(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->GetCharset(&response->head.charset); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.content_length = request->GetExpectedContentSize(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->GetMimeType(&response->head.mime_type); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpResponseInfo response_info = request->response_info(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.was_fetched_via_spdy = response_info.was_fetched_via_spdy; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.was_npn_negotiated = response_info.was_npn_negotiated; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.npn_negotiated_protocol = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info.npn_negotiated_protocol; 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response->head.connection_info = response_info.connection_info; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.was_fetched_via_proxy = request->was_fetched_via_proxy(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.socket_address = request->GetSocketAddress(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appcache::AppCacheInterceptor::GetExtraResponseInfo( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response->head.appcache_id, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response->head.appcache_manifest_url); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(mmenke): Figure out if LOAD_ENABLE_LOAD_TIMING is safe to remove. 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (request->load_flags() & net::LOAD_ENABLE_LOAD_TIMING) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->GetLoadTimingInfo(&response->head.load_timing); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ResourceHandler> handler, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceLoaderDelegate* delegate) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : weak_ptr_factory_(this) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::ClientCertStore> client_cert_store; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(USE_OPENSSL) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_cert_store.reset(new net::ClientCertStoreImpl()); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Init(request.Pass(), handler.Pass(), delegate, client_cert_store.Pass()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceLoader::~ResourceLoader() { 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (login_delegate_.get()) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_->OnRequestCancelled(); 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_client_auth_handler_.get()) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_->OnRequestCancelled(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run ResourceHandler destructor before we tear-down the rest of our state 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the ResourceHandler may want to inspect the URLRequest and other state. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_.reset(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::StartRequest() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_->HandleExternalProtocol(this, request_->url())) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelAndIgnore(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Give the handler a chance to delay the URLRequest from being started. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool defer_start = false; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handler_->OnWillStart(GetRequestInfo()->GetRequestID(), request_->url(), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &defer_start)) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (defer_start) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_START; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartRequestInternal(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelRequest(bool from_renderer) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelRequestInternal(net::ERR_ABORTED, from_renderer); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelAndIgnore() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->set_was_ignored_by_handler(true); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelRequest(false); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelWithError(int error_code) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelRequestInternal(error_code, false); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ReportUploadProgress() { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_for_upload_progress_ack_) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Send one progress event at a time. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::UploadProgress progress = request_->GetUploadProgress(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!progress.size()) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Nothing to upload. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (progress.position() == last_upload_position_) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // No progress made since last time. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint64 kHalfPercentIncrements = 200; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 amt_since_last = progress.position() - last_upload_position_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_finished = (progress.size() == progress.position()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enough_new_progress = 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (amt_since_last > (progress.size() / kHalfPercentIncrements)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool too_much_time_passed = time_since_last > kOneSecond; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_finished || enough_new_progress || too_much_time_passed) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_->OnUploadProgress( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetRequestID(), progress.position(), progress.size()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_for_upload_progress_ack_ = true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_upload_ticks_ = TimeTicks::Now(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_upload_position_ = progress.position(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::MarkAsTransferring() { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_transferring_ = true; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When an URLRequest is transferred to a new RenderViewHost, its 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ResourceHandler should not receive any notifications because it may depend 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the state of the old RVH. We set a ResourceHandler that only allows 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // canceling requests, because on shutdown of the RDH all pending requests 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are canceled. The RVH of requests that are being transferred may be gone 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by that time. In CompleteTransfer, the ResoureHandlers are substituted 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_.reset(new DoomedResourceHandler(handler_.Pass())); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::WillCompleteTransfer() { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_.reset(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteTransfer(scoped_ptr<ResourceHandler> new_handler) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DEFERRED_REDIRECT, deferred_stage_); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!handler_.get()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_ = new_handler.Pass(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_->SetController(this); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_transferring_ = false; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resume(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ResourceRequestInfoImpl::ForRequest(request_.get()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ClearLoginDelegate() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = NULL; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ClearSSLClientAuthHandler() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = NULL; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnUploadProgressACK() { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_for_upload_progress_ack_ = false; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceLoader::ResourceLoader( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::URLRequest> request, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceHandler> handler, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceLoaderDelegate* delegate, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::ClientCertStore> client_cert_store) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : weak_ptr_factory_(this) { 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Init(request.Pass(), handler.Pass(), delegate, client_cert_store.Pass()); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceLoader::Init(scoped_ptr<net::URLRequest> request, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceHandler> handler, 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceLoaderDelegate* delegate, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::ClientCertStore> client_cert_store) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) deferred_stage_ = DEFERRED_NONE; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ = request.Pass(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler_ = handler.Pass(); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_ = delegate; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_upload_position_ = 0; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_upload_progress_ack_ = false; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_transferring_ = false; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_cert_store_ = client_cert_store.Pass(); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->set_delegate(this); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler_->SetController(this); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_url, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->status().is_success()); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->process_type() != PROCESS_TYPE_PLUGIN && 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ChildProcessSecurityPolicyImpl::GetInstance()-> 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CanRequestURL(info->GetChildID(), new_url)) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Denied unauthorized request for " 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_url.possibly_invalid_spec(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the renderer that this request was disallowed. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidReceiveRedirect(this, new_url); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_->HandleExternalProtocol(this, new_url)) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request is complete so we can remove it. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelAndIgnore(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ResourceResponse> response(new ResourceResponse()); 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PopulateResourceResponse(request_.get(), response.get()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!handler_->OnRequestRedirected( 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) info->GetRequestID(), new_url, response.get(), defer)) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (*defer) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnAuthRequired(net::URLRequest* unused, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthChallengeInfo* auth_info) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delegate_->AcceptAuthRequest(this, auth_info)) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a login dialog on the UI thread to get authentication data, or pull 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from cache and continue on the IO thread. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!login_delegate_.get()) 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "OnAuthRequired called with login_delegate pending"; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = delegate_->CreateLoginDelegate(this, auth_info); 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!login_delegate_.get()) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnCertificateRequested( 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* unused, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::SSLCertRequestInfo* cert_info) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delegate_->AcceptSSLClientCertificateRequest(this, cert_info)) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Cancel(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(USE_OPENSSL) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_cert_store_->GetClientCerts(*cert_info, &cert_info->client_certs); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_info->client_certs.empty()) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to query the user if there are no certs to choose from. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ContinueWithCertificate(NULL); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!ssl_client_auth_handler_.get()) 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "OnCertificateRequested called with ssl_client_auth_handler pending"; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = new SSLClientAuthHandler(request_.get(), 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_info); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_->SelectCertificate(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnSSLCertificateError(net::URLRequest* request, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo& ssl_info, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fatal) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_view_id; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLManager::OnSSLCertificateError( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetGlobalRequestID(), 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetResourceType(), 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_process_id, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_id, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_info, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fatal); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnResponseStarted: " << request_->url().spec(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The CanLoadPage check should take place after any server redirects have 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // finished, at the point in time that we know a page will commit in the 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // renderer process. 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChildProcessSecurityPolicyImpl* policy = 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChildProcessSecurityPolicyImpl::GetInstance(); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!policy->CanLoadPage(info->GetChildID(), 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->url(), 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info->GetResourceType())) { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Cancel(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_->status().is_success()) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to send a final upload progress message prior to sending the 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response complete message even if we're waiting for an ack to to a 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous upload progress message. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_for_upload_progress_ack_ = false; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportUploadProgress(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteResponseStarted(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_deferred()) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success()) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(false); // Read the first chunk. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " bytes_read = " << bytes_read; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes_read == -1 always implies an error. 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_read == -1 || !request_->status().is_success()) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteRead(bytes_read); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_deferred()) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success() && bytes_read > 0) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(true); // Read the next chunk. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelSSLRequest(const GlobalRequestID& id, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo* ssl_info) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request can be NULL if it was cancelled by the renderer (as the 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request of the user navigating to a new page from the location bar). 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_->is_pending()) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "CancelSSLRequest() url: " << request_->url().spec(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_info) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithSSLError(error, *ssl_info); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithError(error); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ContinueSSLRequest(const GlobalRequestID& id) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "ContinueSSLRequest() url: " << request_->url().spec(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ContinueDespiteLastError(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::Resume() { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_transferring_); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeferredStage stage = deferred_stage_; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_NONE; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (stage) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_NONE: 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_START: 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartRequestInternal(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_REDIRECT: 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->FollowDeferredRedirect(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_READ: 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::ResumeReading, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_FINISH: 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delay self-destruction since we don't know how we were reached. 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::CallDidFinishLoading, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::Cancel() { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelRequest(false); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::StartRequestInternal() { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_->is_pending()); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidStartRequest(this); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebKit will send us a cancel for downloads since it no longer handles 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them. In this case, ignore the cancel since we handle downloads in the 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // browser. 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (from_renderer && (info->is_download() || info->is_stream())) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): Perhaps we should really be looking to see if the status is 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IO_PENDING? 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_pending = request_->is_pending(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (login_delegate_.get()) { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_->OnRequestCancelled(); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = NULL; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_client_auth_handler_.get()) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_->OnRequestCancelled(); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = NULL; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithError(error); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_pending) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request isn't in flight, then we won't get an asynchronous 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification from the request, so we have to signal ourselves to finish 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this request. 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ResourceLoader::ResponseCompleted, 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteResponseStarted() { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ResourceResponse> response(new ResourceResponse()); 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PopulateResourceResponse(request_.get(), response.get()); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The --site-per-process flag enables an out-of-process iframes 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // prototype. It works by changing the MIME type of cross-site subframe 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // responses to a Chrome specific one. This new type causes the subframe 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be replaced by a <webview> tag with the same URL, which results in 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // using a renderer in a different process. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For prototyping purposes, we will use a small hack to ensure same site 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // iframes are not changed. We can compare the URL for the subframe 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // request with the referrer. If the two don't match, then it should be a 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cross-site iframe. 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Also, we don't do the MIME type change for chrome:// URLs, as those 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // require different privileges and are not allowed in regular renderers. 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The usage of SiteInstance::IsSameWebSite is safe on the IO thread, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the browser_context parameter is NULL. This does not work for hosted 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // apps, but should be fine for prototyping. 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(nasko): Once the SiteInstance check is fixed, ensure we do the 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // right thing here. http://crbug.com/160576 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line.HasSwitch(switches::kSitePerProcess) && 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestInfo()->GetResourceType() == ResourceType::SUB_FRAME && 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response->head.mime_type == "text/html" && 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !request_->url().SchemeIs(chrome::kChromeUIScheme) && 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !SiteInstance::IsSameWebSite(NULL, request_->url(), 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL(request_->referrer()))) { 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response->head.mime_type = "application/browser-plugin"; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (request_->ssl_info().cert.get()) { 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cert_id = CertStore::GetInstance()->StoreCert( 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->ssl_info().cert.get(), info->GetChildID()); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.security_info = SerializeSecurityInfo( 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_id, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().cert_status, 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().security_bits, 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().connection_status); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should not have any SSL state. 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_->ssl_info().cert_status && 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().security_bits == -1 && 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !request_->ssl_info().connection_status); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidReceiveResponse(this); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool defer = false; 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!handler_->OnResponseStarted( 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) info->GetRequestID(), response.get(), &defer)) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (defer) { 5644311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch read_deferral_start_time_ = base::TimeTicks::Now(); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::StartReading(bool is_continuation) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadMore(&bytes_read); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If IO is pending, wait for the URLRequest to call OnReadCompleted. 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_io_pending()) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_continuation || bytes_read <= 0) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadCompleted(request_.get(), bytes_read); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Else, trigger OnReadCompleted asynchronously to avoid starving the IO 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread in case the URLRequest can provide data synchronously. 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::OnReadCompleted, 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.get(), 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bytes_read)); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ResumeReading() { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_deferred()); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5944311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (!read_deferral_start_time_.is_null()) { 5954311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", 5964311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::TimeTicks::Now() - read_deferral_start_time_); 5974311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch read_deferral_start_time_ = base::TimeTicks(); 5984311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch } 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success()) { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(false); // Read the next chunk (OK to complete synchronously). 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ReadMore(int* bytes_read) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_deferred()); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf_size > 0); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Read(buf, buf_size, bytes_read); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to check the return value here as we'll detect errors by 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inspecting the URLRequest's status. 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteRead(int bytes_read) { 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read >= 0); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->status().is_success()); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool defer = false; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (defer) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_READ; // Read next chunk when resumed. 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ResponseCompleted() { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "ResponseCompleted: " << request_->url().spec(); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string security_info; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo& ssl_info = request_->ssl_info(); 646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_info.cert.get() != NULL) { 647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert.get(), 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetChildID()); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) security_info = SerializeSecurityInfo( 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_id, ssl_info.cert_status, ssl_info.security_bits, 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_info.connection_status); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) security_info)) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will result in our destruction. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallDidFinishLoading(); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The handler is not ready to die yet. We will call DidFinishLoading when 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we resume. 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_FINISH; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CallDidFinishLoading() { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidFinishLoading(this); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 670