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) 158f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdochvoid ResourceLoader::MarkAsTransferring(const GURL& target_url) { 159f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch CHECK_EQ(GetRequestInfo()->GetResourceType(), ResourceType::MAIN_FRAME) 160f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch << "Cannot transfer non-main frame navigations"; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_transferring_ = true; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch // When transferring a request to another process, the renderer doesn't get 164f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch // a chance to update the cookie policy URL. Do it here instead. 165f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch request()->set_first_party_for_cookies(target_url); 166f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When an URLRequest is transferred to a new RenderViewHost, its 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ResourceHandler should not receive any notifications because it may depend 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the state of the old RVH. We set a ResourceHandler that only allows 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // canceling requests, because on shutdown of the RDH all pending requests 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are canceled. The RVH of requests that are being transferred may be gone 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by that time. In CompleteTransfer, the ResoureHandlers are substituted 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_.reset(new DoomedResourceHandler(handler_.Pass())); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::WillCompleteTransfer() { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_.reset(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteTransfer(scoped_ptr<ResourceHandler> new_handler) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DEFERRED_REDIRECT, deferred_stage_); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!handler_.get()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_ = new_handler.Pass(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_->SetController(this); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_transferring_ = false; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resume(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ResourceRequestInfoImpl::ForRequest(request_.get()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ClearLoginDelegate() { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = NULL; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ClearSSLClientAuthHandler() { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = NULL; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnUploadProgressACK() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_for_upload_progress_ack_ = false; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceLoader::ResourceLoader( 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::URLRequest> request, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceHandler> handler, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceLoaderDelegate* delegate, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::ClientCertStore> client_cert_store) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : weak_ptr_factory_(this) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Init(request.Pass(), handler.Pass(), delegate, client_cert_store.Pass()); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceLoader::Init(scoped_ptr<net::URLRequest> request, 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceHandler> handler, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceLoaderDelegate* delegate, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::ClientCertStore> client_cert_store) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) deferred_stage_ = DEFERRED_NONE; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ = request.Pass(); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler_ = handler.Pass(); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_ = delegate; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_upload_position_ = 0; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_upload_progress_ack_ = false; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_transferring_ = false; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_cert_store_ = client_cert_store.Pass(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->set_delegate(this); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler_->SetController(this); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_url, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->status().is_success()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->process_type() != PROCESS_TYPE_PLUGIN && 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ChildProcessSecurityPolicyImpl::GetInstance()-> 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CanRequestURL(info->GetChildID(), new_url)) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Denied unauthorized request for " 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_url.possibly_invalid_spec(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the renderer that this request was disallowed. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidReceiveRedirect(this, new_url); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_->HandleExternalProtocol(this, new_url)) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request is complete so we can remove it. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelAndIgnore(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ResourceResponse> response(new ResourceResponse()); 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PopulateResourceResponse(request_.get(), response.get()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!handler_->OnRequestRedirected( 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) info->GetRequestID(), new_url, response.get(), defer)) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (*defer) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnAuthRequired(net::URLRequest* unused, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthChallengeInfo* auth_info) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delegate_->AcceptAuthRequest(this, auth_info)) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a login dialog on the UI thread to get authentication data, or pull 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from cache and continue on the IO thread. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!login_delegate_.get()) 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "OnAuthRequired called with login_delegate pending"; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = delegate_->CreateLoginDelegate(this, auth_info); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!login_delegate_.get()) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelAuth(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnCertificateRequested( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* unused, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::SSLCertRequestInfo* cert_info) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delegate_->AcceptSSLClientCertificateRequest(this, cert_info)) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Cancel(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(USE_OPENSSL) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_cert_store_->GetClientCerts(*cert_info, &cert_info->client_certs); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_info->client_certs.empty()) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to query the user if there are no certs to choose from. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ContinueWithCertificate(NULL); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!ssl_client_auth_handler_.get()) 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "OnCertificateRequested called with ssl_client_auth_handler pending"; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = new SSLClientAuthHandler(request_.get(), 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_info); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_->SelectCertificate(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnSSLCertificateError(net::URLRequest* request, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo& ssl_info, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fatal) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_view_id; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLManager::OnSSLCertificateError( 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetGlobalRequestID(), 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetResourceType(), 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_process_id, 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_id, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_info, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fatal); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnResponseStarted: " << request_->url().spec(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The CanLoadPage check should take place after any server redirects have 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // finished, at the point in time that we know a page will commit in the 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // renderer process. 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChildProcessSecurityPolicyImpl* policy = 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChildProcessSecurityPolicyImpl::GetInstance(); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!policy->CanLoadPage(info->GetChildID(), 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->url(), 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info->GetResourceType())) { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Cancel(); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_->status().is_success()) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to send a final upload progress message prior to sending the 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response complete message even if we're waiting for an ack to to a 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous upload progress message. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_for_upload_progress_ack_ = false; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportUploadProgress(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteResponseStarted(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_deferred()) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success()) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(false); // Read the first chunk. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_.get(), unused); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " bytes_read = " << bytes_read; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes_read == -1 always implies an error. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_read == -1 || !request_->status().is_success()) { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteRead(bytes_read); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_deferred()) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success() && bytes_read > 0) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(true); // Read the next chunk. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelSSLRequest(const GlobalRequestID& id, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo* ssl_info) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request can be NULL if it was cancelled by the renderer (as the 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request of the user navigating to a new page from the location bar). 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_->is_pending()) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "CancelSSLRequest() url: " << request_->url().spec(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_info) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithSSLError(error, *ssl_info); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithError(error); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ContinueSSLRequest(const GlobalRequestID& id) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "ContinueSSLRequest() url: " << request_->url().spec(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ContinueDespiteLastError(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::Resume() { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_transferring_); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeferredStage stage = deferred_stage_; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_NONE; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (stage) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_NONE: 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_START: 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartRequestInternal(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_REDIRECT: 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->FollowDeferredRedirect(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_READ: 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::ResumeReading, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEFERRED_FINISH: 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delay self-destruction since we don't know how we were reached. 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::CallDidFinishLoading, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::Cancel() { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelRequest(false); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::StartRequestInternal() { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_->is_pending()); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidStartRequest(this); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebKit will send us a cancel for downloads since it no longer handles 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them. In this case, ignore the cancel since we handle downloads in the 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // browser. 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (from_renderer && (info->is_download() || info->is_stream())) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): Perhaps we should really be looking to see if the status is 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IO_PENDING? 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_pending = request_->is_pending(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (login_delegate_.get()) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_->OnRequestCancelled(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_delegate_ = NULL; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_client_auth_handler_.get()) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_->OnRequestCancelled(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_client_auth_handler_ = NULL; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->CancelWithError(error); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_pending) { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request isn't in flight, then we won't get an asynchronous 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification from the request, so we have to signal ourselves to finish 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this request. 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ResourceLoader::ResponseCompleted, 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteResponseStarted() { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ResourceResponse> response(new ResourceResponse()); 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PopulateResourceResponse(request_.get(), response.get()); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The --site-per-process flag enables an out-of-process iframes 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // prototype. It works by changing the MIME type of cross-site subframe 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // responses to a Chrome specific one. This new type causes the subframe 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be replaced by a <webview> tag with the same URL, which results in 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // using a renderer in a different process. 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For prototyping purposes, we will use a small hack to ensure same site 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // iframes are not changed. We can compare the URL for the subframe 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // request with the referrer. If the two don't match, then it should be a 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cross-site iframe. 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Also, we don't do the MIME type change for chrome:// URLs, as those 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // require different privileges and are not allowed in regular renderers. 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The usage of SiteInstance::IsSameWebSite is safe on the IO thread, 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the browser_context parameter is NULL. This does not work for hosted 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // apps, but should be fine for prototyping. 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(nasko): Once the SiteInstance check is fixed, ensure we do the 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // right thing here. http://crbug.com/160576 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line.HasSwitch(switches::kSitePerProcess) && 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestInfo()->GetResourceType() == ResourceType::SUB_FRAME && 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response->head.mime_type == "text/html" && 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !request_->url().SchemeIs(chrome::kChromeUIScheme) && 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !SiteInstance::IsSameWebSite(NULL, request_->url(), 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL(request_->referrer()))) { 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response->head.mime_type = "application/browser-plugin"; 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (request_->ssl_info().cert.get()) { 549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cert_id = CertStore::GetInstance()->StoreCert( 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->ssl_info().cert.get(), info->GetChildID()); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.security_info = SerializeSecurityInfo( 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_id, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().cert_status, 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().security_bits, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().connection_status); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should not have any SSL state. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_->ssl_info().cert_status && 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ssl_info().security_bits == -1 && 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !request_->ssl_info().connection_status); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidReceiveResponse(this); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool defer = false; 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!handler_->OnResponseStarted( 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) info->GetRequestID(), response.get(), &defer)) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (defer) { 5704311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch read_deferral_start_time_ = base::TimeTicks::Now(); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::StartReading(bool is_continuation) { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadMore(&bytes_read); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If IO is pending, wait for the URLRequest to call OnReadCompleted. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_io_pending()) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_continuation || bytes_read <= 0) { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadCompleted(request_.get(), bytes_read); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Else, trigger OnReadCompleted asynchronously to avoid starving the IO 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread in case the URLRequest can provide data synchronously. 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ResourceLoader::OnReadCompleted, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.get(), 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bytes_read)); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ResumeReading() { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_deferred()); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6004311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (!read_deferral_start_time_.is_null()) { 6014311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", 6024311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::TimeTicks::Now() - read_deferral_start_time_); 6034311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch read_deferral_start_time_ = base::TimeTicks(); 6044311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success()) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartReading(false); // Read the next chunk (OK to complete synchronously). 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCompleted(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ReadMore(int* bytes_read) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_deferred()); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf_size > 0); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Read(buf, buf_size, bytes_read); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to check the return value here as we'll detect errors by 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inspecting the URLRequest's status. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CompleteRead(int bytes_read) { 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read >= 0); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->status().is_success()); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool defer = false; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (defer) { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_READ; // Read next chunk when resumed. 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::ResponseCompleted() { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "ResponseCompleted: " << request_->url().spec(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRequestInfoImpl* info = GetRequestInfo(); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string security_info; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::SSLInfo& ssl_info = request_->ssl_info(); 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_info.cert.get() != NULL) { 653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert.get(), 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetChildID()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) security_info = SerializeSecurityInfo( 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_id, ssl_info.cert_status, ssl_info.security_bits, 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_info.connection_status); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) security_info)) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will result in our destruction. 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallDidFinishLoading(); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The handler is not ready to die yet. We will call DidFinishLoading when 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we resume. 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_stage_ = DEFERRED_FINISH; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceLoader::CallDidFinishLoading() { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DidFinishLoading(this); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 676