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/async_resource_handler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/alias.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/devtools/devtools_netlog_observer.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/host_zoom_map_impl.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_buffer.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_dispatcher_host_impl.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_message_filter.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_request_info_impl.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/resource_context_impl.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/resource_messages.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/global_request_id.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_dispatcher_host_delegate.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/resource_response.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kBufferSize = 1024 * 512; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kMinAllocationSize = 1024 * 4; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kMaxAllocationSize = 1024 * 32; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetNumericArg(const std::string& name, int* result) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.empty()) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToInt(value, result); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeResourceBufferConstants() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool did_init = false; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (did_init) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_init = true; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNumericArg("resource-buffer-size", &kBufferSize); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNumericArg("resource-buffer-min-allocation-size", &kMinAllocationSize); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNumericArg("resource-buffer-max-allocation-size", &kMaxAllocationSize); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CalcUsedPercentage(int bytes_read, int buffer_size) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double ratio = static_cast<double>(bytes_read) / buffer_size; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(ratio * 100.0 + 0.5); // Round to nearest integer. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DependentIOBuffer : public net::WrappedIOBuffer { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DependentIOBuffer(ResourceBuffer* backing, char* memory) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::WrappedIOBuffer(memory), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backing_(backing) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DependentIOBuffer() {} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ResourceBuffer> backing_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AsyncResourceHandler::AsyncResourceHandler( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceDispatcherHostImpl* rdh) 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : ResourceHandler(request), 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ResourceMessageDelegate(request), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rdh_(rdh), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_data_count_(0), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocation_size_(0), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_defer_(false), 88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) has_checked_for_sufficient_resources_(false), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_received_response_msg_(false), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_first_data_msg_(false) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeResourceBufferConstants(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AsyncResourceHandler::~AsyncResourceHandler() { 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (has_checked_for_sufficient_resources_) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) rdh_->FinishedWithResourcesForRequest(request()); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* message_was_ok) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool handled = true; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP_EX(AsyncResourceHandler, message, *message_was_ok) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(ResourceHostMsg_FollowRedirect, OnFollowRedirect) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(ResourceHostMsg_DataReceived_ACK, OnDataReceivedACK) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_END_MESSAGE_MAP_EX() 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return handled; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncResourceHandler::OnFollowRedirect( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_new_first_party_for_cookies, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_first_party_for_cookies) { 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!request()->status().is_success()) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "OnFollowRedirect for invalid request"; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_new_first_party_for_cookies) 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request()->set_first_party_for_cookies(new_first_party_for_cookies); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResumeIfDeferred(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncResourceHandler::OnDataReceivedACK(int request_id) { 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_data_count_) { 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) --pending_data_count_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buffer_->RecycleLeastRecentlyAllocated(); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (buffer_->CanAllocate()) 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ResumeIfDeferred(); 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::OnUploadProgress(int request_id, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 position, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 size) { 1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ResourceMessageFilter* filter = GetFilter(); 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!filter) 1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return filter->Send( 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new ResourceMsg_UploadProgress(request_id, position, size)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::OnRequestRedirected(int request_id, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_url, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceResponse* response, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const ResourceRequestInfoImpl* info = GetRequestInfo(); 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!info->filter()) 1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *defer = did_defer_ = true; 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnDefer(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rdh_->delegate()) { 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rdh_->delegate()->OnRequestRedirected( 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_url, request(), info->GetContext(), response); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DevToolsNetLogObserver::PopulateResponseInfo(request(), response); 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) response->head.request_start = request()->creation_time(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.response_start = TimeTicks::Now(); 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return info->filter()->Send(new ResourceMsg_ReceivedRedirect( 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_id, new_url, response->head)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::OnResponseStarted(int request_id, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceResponse* response, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For changes to the main frame, inform the renderer of the new URL's 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // per-host settings before the request actually commits. This way the 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer will be able to set these precisely at the time the 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request commits, avoiding the possibility of e.g. zooming the old content 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or of having to layout the new content twice. 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const ResourceRequestInfoImpl* info = GetRequestInfo(); 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!info->filter()) 1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rdh_->delegate()) { 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rdh_->delegate()->OnResponseStarted( 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request(), info->GetContext(), response, info->filter()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DevToolsNetLogObserver::PopulateResponseInfo(request(), response); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostZoomMap* host_zoom_map = 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetHostZoomMapForResourceContext(info->GetContext()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->GetResourceType() == ResourceType::MAIN_FRAME && host_zoom_map) { 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& request_url = request()->url(); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->filter()->Send(new ViewMsg_SetZoomLevelForLoadingURL( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetRouteID(), 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_url, host_zoom_map->GetZoomLevelForHostAndScheme( 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_url.scheme(), 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::GetHostOrSpecFromURL(request_url)))); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) response->head.request_start = request()->creation_time(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->head.response_start = TimeTicks::Now(); 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->filter()->Send(new ResourceMsg_ReceivedResponse(request_id, 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) response->head)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_received_response_msg_ = true; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (request()->response_info().metadata.get()) { 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<char> copy(request()->response_info().metadata->data(), 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request()->response_info().metadata->data() + 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request()->response_info().metadata->size()); 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(request_id, 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) copy)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::OnWillStart(int request_id, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool AsyncResourceHandler::OnWillRead(int request_id, 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<net::IOBuffer>* buf, 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* buf_size, 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int min_size) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(-1, min_size); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EnsureResourceBufferIsInitialized()) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buffer_->CanAllocate()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* memory = buffer_->Allocate(&allocation_size_); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(memory); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *buf = new DependentIOBuffer(buffer_.get(), memory); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf_size = allocation_size_; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Net.AsyncResourceHandler_SharedIOBuffer_Alloc", 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf_size, 0, kMaxAllocationSize, 100); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::OnReadCompleted(int request_id, int bytes_read, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) { 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_GE(bytes_read, 0); 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bytes_read) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ResourceMessageFilter* filter = GetFilter(); 2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!filter) 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_->ShrinkLastAllocation(bytes_read); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Net.AsyncResourceHandler_SharedIOBuffer_Used", 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read, 0, kMaxAllocationSize, 100); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_PERCENTAGE( 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Net.AsyncResourceHandler_SharedIOBuffer_UsedPercentage", 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalcUsedPercentage(bytes_read, allocation_size_)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sent_first_data_msg_) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle handle; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!buffer_->ShareToProcess(filter->PeerHandle(), &handle, &size)) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) filter->Send(new ResourceMsg_SetDataBuffer( 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request_id, handle, size, filter->peer_pid())); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_first_data_msg_ = true; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_offset = buffer_->GetLastAllocationOffset(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int encoded_data_length = 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DevToolsNetLogObserver::GetAndResetEncodedDataLength(request()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) filter->Send(new ResourceMsg_DataReceived( 28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_id, data_offset, bytes_read, encoded_data_length)); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++pending_data_count_; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Net.AsyncResourceHandler_PendingDataCount", 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_data_count_, 0, 100, 100); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!buffer_->CanAllocate()) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Net.AsyncResourceHandler_PendingDataCount_WhenFull", 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_data_count_, 0, 100, 100); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *defer = did_defer_ = true; 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnDefer(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncResourceHandler::OnDataDownloaded( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_id, int bytes_downloaded) { 29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int encoded_data_length = 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DevToolsNetLogObserver::GetAndResetEncodedDataLength(request()); 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ResourceMessageFilter* filter = GetFilter(); 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (filter) { 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) filter->Send(new ResourceMsg_DataDownloaded( 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_id, bytes_downloaded, encoded_data_length)); 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AsyncResourceHandler::OnResponseCompleted( 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_id, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequestStatus& status, 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& security_info, 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool* defer) { 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const ResourceRequestInfoImpl* info = GetRequestInfo(); 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!info->filter()) 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 31768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we crash here, figure out what URL the renderer was requesting. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/107692 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char url_buf[128]; 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::Alias(url_buf); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gavinp): Remove this CHECK when we figure out the cause of 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/124680 . This check mirrors closely check in 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ResourceHandleInternal which asserts on its state and crashes. By crashing 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when the message is sent, we should get better crash reports. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(status.status() != net::URLRequestStatus::SUCCESS || 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_received_response_msg_); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks completion_time = TimeTicks::Now(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = status.error(); 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool was_ignored_by_handler = info->WasIgnoredByHandler(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(status.status() != net::URLRequestStatus::IO_PENDING); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this check fails, then we're in an inconsistent state because all 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests ignored by the handler should be canceled (which should result in 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the ERR_ABORTED error code). 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mkosiba): Fix up cases where we create a URLRequestStatus 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with a status() != SUCCESS and an error_code() == net::OK. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status.status() == net::URLRequestStatus::CANCELED && 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_code == net::OK) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_code = net::ERR_ABORTED; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (status.status() == net::URLRequestStatus::FAILED && 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_code == net::OK) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_code = net::ERR_FAILED; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->filter()->Send( 35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new ResourceMsg_RequestComplete(request_id, 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) error_code, 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) was_ignored_by_handler, 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) security_info, 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) completion_time)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (buffer_.get() && buffer_->IsInitialized()) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!has_checked_for_sufficient_resources_) { 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) has_checked_for_sufficient_resources_ = true; 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!rdh_->HasSufficientResourcesForRequest(request())) { 368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); 369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = new ResourceBuffer(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_->Initialize(kBufferSize, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinAllocationSize, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMaxAllocationSize); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncResourceHandler::ResumeIfDeferred() { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (did_defer_) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_defer_ = false; 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request()->LogUnblocked(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller()->Resume(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AsyncResourceHandler::OnDefer() { 388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request()->LogBlockedBy("AsyncResourceHandler"); 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 392