Chromium Code Reviews| Index: content/browser/loader/content_size_resource_handler.cc |
| diff --git a/content/browser/loader/content_size_resource_handler.cc b/content/browser/loader/content_size_resource_handler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..88d0468eacc6a5b4272c92a82cfba200ed20fd5b |
| --- /dev/null |
| +++ b/content/browser/loader/content_size_resource_handler.cc |
| @@ -0,0 +1,100 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/loader/content_size_resource_handler.h" |
| + |
| +#include "base/bind.h" |
| +#include "content/browser/loader/loader_io_thread_notifier.h" |
| +#include "content/browser/loader/resource_request_info_impl.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "net/url_request/url_request.h" |
| + |
| +namespace content { |
| + |
| +ContentSizeResourceHandlerManager::ContentSizeResourceHandlerManager() |
| + : pending_updates_(new std::map<GlobalFrameRoutingId, int>) {} |
| +ContentSizeResourceHandlerManager::~ContentSizeResourceHandlerManager() {} |
| + |
| +std::unique_ptr<ResourceHandler> |
| +ContentSizeResourceHandlerManager::MaybeAddHandler( |
| + std::unique_ptr<ResourceHandler> next_handler, |
| + net::URLRequest* request) { |
| + ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); |
| + DCHECK(info); |
| + if (info->IsMainFrame()) |
| + return next_handler; |
| + |
| + const auto& it = frame_limits_.find(info->GetGlobalFrameRoutingId()); |
| + if (it != frame_limits_.end()) { |
| + next_handler.reset(new ContentSizeResourceHandler(std::move(next_handler), |
| + request, this, it)); |
| + } |
| + return next_handler; |
| +} |
| + |
| +void ContentSizeResourceHandlerManager::NotifyRead( |
| + ResourceRequestInfoImpl* request_info, |
| + int bytes_read) { |
| + (*pending_updates_)[request_info->GetGlobalFrameRoutingId()] += bytes_read; |
| +} |
| + |
| +void ContentSizeResourceHandlerManager::NotifyUIThreadReadUpdates() { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&LoaderIOThreadNotifier::UpdateGlobalDataAccounting, |
| + base::Passed(std::move(pending_updates_)))); |
| + pending_updates_.reset(new std::map<GlobalFrameRoutingId, int>); |
| +} |
| + |
| +void ContentSizeResourceHandlerManager::FrameHasSizeLimit( |
| + const GlobalFrameRoutingId& id, int limit) { |
| + frame_limits_[id] = limit; |
|
mmenke
2016/08/02 18:02:11
How useful is this? This seems best-effort-y, giv
Charlie Harrison
2016/08/02 18:35:36
It's pretty useful. I don't exact numbers but I co
|
| +} |
| + |
| +void ContentSizeResourceHandlerManager::FramesWentOverSizeLimits( |
| + std::unique_ptr<std::set<GlobalFrameRoutingId>> ids) { |
| + for (const auto& it : *ids) { |
| + frame_limits_[it] = 0; |
| + } |
| +} |
| + |
| +void ContentSizeResourceHandlerManager::FrameDeleted( |
| + const GlobalFrameRoutingId& id) { |
| + frame_limits_.erase(id); |
| +} |
| + |
| +ContentSizeResourceHandler::ContentSizeResourceHandler( |
| + std::unique_ptr<ResourceHandler> next_handler, |
| + net::URLRequest* request, |
| + ContentSizeResourceHandlerManager* manager, |
| + std::map<GlobalFrameRoutingId, int>::iterator frame_limit_iterator) |
| + : LayeredResourceHandler(request, std::move(next_handler)), |
| + manager_(manager), |
| + frame_limit_iterator_(frame_limit_iterator) {} |
| + |
| +ContentSizeResourceHandler::~ContentSizeResourceHandler() {} |
| + |
| +bool ContentSizeResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
| + if (frame_limit_iterator_->second <= 0) |
| + return false; |
| + return next_handler_->OnWillStart(url, defer); |
| +} |
| + |
| +bool ContentSizeResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
| + frame_limit_iterator_->second -= bytes_read; |
| + manager_->NotifyRead(GetRequestInfo(), bytes_read); |
| + if (frame_limit_iterator_->second <= 0) |
| + return false; |
| + return next_handler_->OnReadCompleted(bytes_read, defer); |
| +} |
| + |
| +void ContentSizeResourceHandler::OnResponseCompleted( |
| + const net::URLRequestStatus& status, |
| + const std::string& security_info, |
| + bool* defer) { |
| + manager_->NotifyUIThreadReadUpdates(); |
| + next_handler_->OnResponseCompleted(status, security_info, defer); |
| +} |
| + |
| +} // namespace content |