Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/loader/async_resource_handler.h" | 5 #include "content/browser/loader/async_resource_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "content/common/resource_messages.h" | 25 #include "content/common/resource_messages.h" |
| 26 #include "content/common/view_messages.h" | 26 #include "content/common/view_messages.h" |
| 27 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 27 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 28 #include "content/public/common/resource_response.h" | 28 #include "content/public/common/resource_response.h" |
| 29 #include "net/base/io_buffer.h" | 29 #include "net/base/io_buffer.h" |
| 30 #include "net/base/load_flags.h" | 30 #include "net/base/load_flags.h" |
| 31 #include "net/base/net_util.h" | 31 #include "net/base/net_util.h" |
| 32 #include "net/log/net_log.h" | 32 #include "net/log/net_log.h" |
| 33 #include "net/url_request/redirect_info.h" | 33 #include "net/url_request/redirect_info.h" |
| 34 | 34 |
| 35 using base::TimeDelta; | |
| 35 using base::TimeTicks; | 36 using base::TimeTicks; |
| 36 | 37 |
| 37 namespace content { | 38 namespace content { |
| 38 namespace { | 39 namespace { |
| 39 | 40 |
| 40 static int kBufferSize = 1024 * 512; | 41 static int kBufferSize = 1024 * 512; |
| 41 static int kMinAllocationSize = 1024 * 4; | 42 static int kMinAllocationSize = 1024 * 4; |
| 42 static int kMaxAllocationSize = 1024 * 32; | 43 static int kMaxAllocationSize = 1024 * 32; |
| 44 // The interval for calls to ReportUploadProgress. | |
| 45 static int kUploadProgressIntervalMsec = 10; | |
| 43 | 46 |
| 44 void GetNumericArg(const std::string& name, int* result) { | 47 void GetNumericArg(const std::string& name, int* result) { |
| 45 const std::string& value = | 48 const std::string& value = |
| 46 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name); | 49 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name); |
| 47 if (!value.empty()) | 50 if (!value.empty()) |
| 48 base::StringToInt(value, result); | 51 base::StringToInt(value, result); |
| 49 } | 52 } |
| 50 | 53 |
| 51 void InitializeResourceBufferConstants() { | 54 void InitializeResourceBufferConstants() { |
| 52 static bool did_init = false; | 55 static bool did_init = false; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 77 ResourceDispatcherHostImpl* rdh) | 80 ResourceDispatcherHostImpl* rdh) |
| 78 : ResourceHandler(request), | 81 : ResourceHandler(request), |
| 79 ResourceMessageDelegate(request), | 82 ResourceMessageDelegate(request), |
| 80 rdh_(rdh), | 83 rdh_(rdh), |
| 81 pending_data_count_(0), | 84 pending_data_count_(0), |
| 82 allocation_size_(0), | 85 allocation_size_(0), |
| 83 did_defer_(false), | 86 did_defer_(false), |
| 84 has_checked_for_sufficient_resources_(false), | 87 has_checked_for_sufficient_resources_(false), |
| 85 sent_received_response_msg_(false), | 88 sent_received_response_msg_(false), |
| 86 sent_first_data_msg_(false), | 89 sent_first_data_msg_(false), |
| 90 last_upload_position_(0), | |
| 91 waiting_for_upload_progress_ack_(false), | |
| 87 reported_transfer_size_(0) { | 92 reported_transfer_size_(0) { |
| 88 InitializeResourceBufferConstants(); | 93 InitializeResourceBufferConstants(); |
| 89 } | 94 } |
| 90 | 95 |
| 91 AsyncResourceHandler::~AsyncResourceHandler() { | 96 AsyncResourceHandler::~AsyncResourceHandler() { |
| 92 if (has_checked_for_sufficient_resources_) | 97 if (has_checked_for_sufficient_resources_) |
| 93 rdh_->FinishedWithResourcesForRequest(request()); | 98 rdh_->FinishedWithResourcesForRequest(request()); |
| 94 } | 99 } |
| 95 | 100 |
| 96 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 101 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
| 97 bool handled = true; | 102 bool handled = true; |
| 98 IPC_BEGIN_MESSAGE_MAP(AsyncResourceHandler, message) | 103 IPC_BEGIN_MESSAGE_MAP(AsyncResourceHandler, message) |
| 99 IPC_MESSAGE_HANDLER(ResourceHostMsg_FollowRedirect, OnFollowRedirect) | 104 IPC_MESSAGE_HANDLER(ResourceHostMsg_FollowRedirect, OnFollowRedirect) |
| 100 IPC_MESSAGE_HANDLER(ResourceHostMsg_DataReceived_ACK, OnDataReceivedACK) | 105 IPC_MESSAGE_HANDLER(ResourceHostMsg_DataReceived_ACK, OnDataReceivedACK) |
| 106 IPC_MESSAGE_HANDLER(ResourceHostMsg_UploadProgress_ACK, OnUploadProgressACK) | |
| 101 IPC_MESSAGE_UNHANDLED(handled = false) | 107 IPC_MESSAGE_UNHANDLED(handled = false) |
| 102 IPC_END_MESSAGE_MAP() | 108 IPC_END_MESSAGE_MAP() |
| 103 return handled; | 109 return handled; |
| 104 } | 110 } |
| 105 | 111 |
| 106 void AsyncResourceHandler::OnFollowRedirect(int request_id) { | 112 void AsyncResourceHandler::OnFollowRedirect(int request_id) { |
| 107 if (!request()->status().is_success()) { | 113 if (!request()->status().is_success()) { |
| 108 DVLOG(1) << "OnFollowRedirect for invalid request"; | 114 DVLOG(1) << "OnFollowRedirect for invalid request"; |
| 109 return; | 115 return; |
| 110 } | 116 } |
| 111 | 117 |
| 112 ResumeIfDeferred(); | 118 ResumeIfDeferred(); |
| 113 } | 119 } |
| 114 | 120 |
| 115 void AsyncResourceHandler::OnDataReceivedACK(int request_id) { | 121 void AsyncResourceHandler::OnDataReceivedACK(int request_id) { |
| 116 if (pending_data_count_) { | 122 if (pending_data_count_) { |
| 117 --pending_data_count_; | 123 --pending_data_count_; |
| 118 | 124 |
| 119 buffer_->RecycleLeastRecentlyAllocated(); | 125 buffer_->RecycleLeastRecentlyAllocated(); |
| 120 if (buffer_->CanAllocate()) | 126 if (buffer_->CanAllocate()) |
| 121 ResumeIfDeferred(); | 127 ResumeIfDeferred(); |
| 122 } | 128 } |
| 123 } | 129 } |
| 124 | 130 |
| 125 bool AsyncResourceHandler::OnUploadProgress(uint64 position, | 131 void AsyncResourceHandler::OnUploadProgressACK(int request_id) { |
| 126 uint64 size) { | 132 waiting_for_upload_progress_ack_ = false; |
| 127 ResourceMessageFilter* filter = GetFilter(); | 133 } |
| 128 if (!filter) | 134 |
| 129 return false; | 135 void AsyncResourceHandler::ReportUploadProgress() { |
| 130 return filter->Send( | 136 DCHECK(GetRequestInfo()->is_upload_progress_enabled()); |
| 131 new ResourceMsg_UploadProgress(GetRequestID(), position, size)); | 137 if (waiting_for_upload_progress_ack_) |
| 138 return; // Send one progress event at a time. | |
| 139 | |
| 140 net::UploadProgress progress = request()->GetUploadProgress(); | |
| 141 if (!progress.size()) | |
| 142 return; // Nothing to upload. | |
| 143 | |
| 144 if (progress.position() == last_upload_position_) | |
| 145 return; // No progress made since last time. | |
| 146 | |
| 147 const uint64 kHalfPercentIncrements = 200; | |
| 148 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); | |
| 149 | |
| 150 uint64 amt_since_last = progress.position() - last_upload_position_; | |
| 151 TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; | |
| 152 | |
| 153 bool is_finished = (progress.size() == progress.position()); | |
| 154 bool enough_new_progress = | |
| 155 (amt_since_last > (progress.size() / kHalfPercentIncrements)); | |
| 156 bool too_much_time_passed = time_since_last > kOneSecond; | |
| 157 | |
| 158 if (is_finished || enough_new_progress || too_much_time_passed) { | |
| 159 ResourceMessageFilter* filter = GetFilter(); | |
| 160 if (filter) { | |
|
mmenke
2015/08/27 17:21:28
A bit unrelated to this CL, but if filter is false
| |
| 161 filter->Send( | |
| 162 new ResourceMsg_UploadProgress(GetRequestID(), | |
| 163 progress.position(), | |
| 164 progress.size())); | |
| 165 } | |
| 166 waiting_for_upload_progress_ack_ = true; | |
| 167 last_upload_ticks_ = TimeTicks::Now(); | |
| 168 last_upload_position_ = progress.position(); | |
| 169 } | |
| 132 } | 170 } |
| 133 | 171 |
| 134 bool AsyncResourceHandler::OnRequestRedirected( | 172 bool AsyncResourceHandler::OnRequestRedirected( |
| 135 const net::RedirectInfo& redirect_info, | 173 const net::RedirectInfo& redirect_info, |
| 136 ResourceResponse* response, | 174 ResourceResponse* response, |
| 137 bool* defer) { | 175 bool* defer) { |
| 138 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 176 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 139 if (!info->filter()) | 177 if (!info->filter()) |
| 140 return false; | 178 return false; |
| 141 | 179 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 161 } | 199 } |
| 162 | 200 |
| 163 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 201 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 164 bool* defer) { | 202 bool* defer) { |
| 165 // For changes to the main frame, inform the renderer of the new URL's | 203 // For changes to the main frame, inform the renderer of the new URL's |
| 166 // per-host settings before the request actually commits. This way the | 204 // per-host settings before the request actually commits. This way the |
| 167 // renderer will be able to set these precisely at the time the | 205 // renderer will be able to set these precisely at the time the |
| 168 // request commits, avoiding the possibility of e.g. zooming the old content | 206 // request commits, avoiding the possibility of e.g. zooming the old content |
| 169 // or of having to layout the new content twice. | 207 // or of having to layout the new content twice. |
| 170 | 208 |
| 209 progress_timer_.Stop(); | |
| 171 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 210 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 172 if (!info->filter()) | 211 if (!info->filter()) |
| 173 return false; | 212 return false; |
| 174 | 213 |
| 214 // We want to send a final upload progress message prior to sending the | |
| 215 // response complete message even if we're waiting for an ack to to a | |
| 216 // previous upload progress message. | |
| 217 if (info->is_upload_progress_enabled()) { | |
| 218 waiting_for_upload_progress_ack_ = false; | |
| 219 ReportUploadProgress(); | |
| 220 } | |
| 221 | |
| 175 if (rdh_->delegate()) { | 222 if (rdh_->delegate()) { |
| 176 rdh_->delegate()->OnResponseStarted( | 223 rdh_->delegate()->OnResponseStarted( |
| 177 request(), info->GetContext(), response, info->filter()); | 224 request(), info->GetContext(), response, info->filter()); |
| 178 } | 225 } |
| 179 | 226 |
| 180 DevToolsNetLogObserver::PopulateResponseInfo(request(), response); | 227 DevToolsNetLogObserver::PopulateResponseInfo(request(), response); |
| 181 | 228 |
| 182 const HostZoomMapImpl* host_zoom_map = | 229 const HostZoomMapImpl* host_zoom_map = |
| 183 static_cast<const HostZoomMapImpl*>(info->filter()->GetHostZoomMap()); | 230 static_cast<const HostZoomMapImpl*>(info->filter()->GetHostZoomMap()); |
| 184 | 231 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 213 request()->response_info().metadata->data() + | 260 request()->response_info().metadata->data() + |
| 214 request()->response_info().metadata->size()); | 261 request()->response_info().metadata->size()); |
| 215 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 262 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
| 216 copy)); | 263 copy)); |
| 217 } | 264 } |
| 218 | 265 |
| 219 return true; | 266 return true; |
| 220 } | 267 } |
| 221 | 268 |
| 222 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 269 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
| 270 if (GetRequestInfo()->is_upload_progress_enabled() && | |
| 271 request()->has_upload()) { | |
| 272 ReportUploadProgress(); | |
| 273 progress_timer_.Start( | |
| 274 FROM_HERE, | |
| 275 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | |
| 276 this, | |
| 277 &AsyncResourceHandler::ReportUploadProgress); | |
| 278 } | |
| 223 return true; | 279 return true; |
| 224 } | 280 } |
| 225 | 281 |
| 226 bool AsyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { | 282 bool AsyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { |
| 227 return true; | 283 return true; |
| 228 } | 284 } |
| 229 | 285 |
| 230 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 286 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 231 int* buf_size, | 287 int* buf_size, |
| 232 int min_size) { | 288 int min_size) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 request()->LogUnblocked(); | 430 request()->LogUnblocked(); |
| 375 controller()->Resume(); | 431 controller()->Resume(); |
| 376 } | 432 } |
| 377 } | 433 } |
| 378 | 434 |
| 379 void AsyncResourceHandler::OnDefer() { | 435 void AsyncResourceHandler::OnDefer() { |
| 380 request()->LogBlockedBy("AsyncResourceHandler"); | 436 request()->LogBlockedBy("AsyncResourceHandler"); |
| 381 } | 437 } |
| 382 | 438 |
| 383 } // namespace content | 439 } // namespace content |
| OLD | NEW |