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