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 |
| 131 void AsyncResourceHandler::OnUploadProgressACK(int request_id) { | |
|
mmenke
2015/08/26 19:13:12
Definition order should match declaration order in
| |
| 132 waiting_for_upload_progress_ack_ = false; | |
| 133 } | |
| 134 | |
| 135 void AsyncResourceHandler::ReportUploadProgress() { | |
| 136 DCHECK(GetRequestInfo()->is_upload_progress_enabled()); | |
| 137 | |
| 138 if (waiting_for_upload_progress_ack_) | |
| 139 return; // Send one progress event at a time. | |
| 140 | |
| 141 net::UploadProgress progress = request()->GetUploadProgress(); | |
| 142 if (!progress.size()) | |
| 143 return; // Nothing to upload. | |
| 144 | |
| 145 if (progress.position() == last_upload_position_) | |
| 146 return; // No progress made since last time. | |
| 147 | |
| 148 const uint64 kHalfPercentIncrements = 200; | |
| 149 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); | |
| 150 | |
| 151 uint64 amt_since_last = progress.position() - last_upload_position_; | |
| 152 TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; | |
| 153 | |
| 154 bool is_finished = (progress.size() == progress.position()); | |
| 155 bool enough_new_progress = | |
| 156 (amt_since_last > (progress.size() / kHalfPercentIncrements)); | |
| 157 bool too_much_time_passed = time_since_last > kOneSecond; | |
| 158 | |
| 159 if (is_finished || enough_new_progress || too_much_time_passed) { | |
| 160 OnUploadProgress(progress.position(), progress.size()); | |
| 161 waiting_for_upload_progress_ack_ = true; | |
| 162 last_upload_ticks_ = TimeTicks::Now(); | |
| 163 last_upload_position_ = progress.position(); | |
| 164 } | |
| 165 } | |
| 166 | |
| 125 bool AsyncResourceHandler::OnUploadProgress(uint64 position, | 167 bool AsyncResourceHandler::OnUploadProgress(uint64 position, |
| 126 uint64 size) { | 168 uint64 size) { |
| 127 ResourceMessageFilter* filter = GetFilter(); | 169 ResourceMessageFilter* filter = GetFilter(); |
| 128 if (!filter) | 170 if (!filter) |
| 129 return false; | 171 return false; |
| 130 return filter->Send( | 172 return filter->Send( |
| 131 new ResourceMsg_UploadProgress(GetRequestID(), position, size)); | 173 new ResourceMsg_UploadProgress(GetRequestID(), position, size)); |
| 132 } | 174 } |
| 133 | 175 |
| 134 bool AsyncResourceHandler::OnRequestRedirected( | 176 bool AsyncResourceHandler::OnRequestRedirected( |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 161 } | 203 } |
| 162 | 204 |
| 163 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 205 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 164 bool* defer) { | 206 bool* defer) { |
| 165 // For changes to the main frame, inform the renderer of the new URL's | 207 // 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 | 208 // per-host settings before the request actually commits. This way the |
| 167 // renderer will be able to set these precisely at the time the | 209 // 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 | 210 // request commits, avoiding the possibility of e.g. zooming the old content |
| 169 // or of having to layout the new content twice. | 211 // or of having to layout the new content twice. |
| 170 | 212 |
| 213 progress_timer_.Stop(); | |
| 171 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 214 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 172 if (!info->filter()) | 215 if (!info->filter()) |
| 173 return false; | 216 return false; |
| 174 | 217 |
| 218 // We want to send a final upload progress message prior to sending the | |
| 219 // response complete message even if we're waiting for an ack to to a | |
| 220 // previous upload progress message. | |
| 221 if (info->is_upload_progress_enabled()) { | |
| 222 waiting_for_upload_progress_ack_ = false; | |
| 223 ReportUploadProgress(); | |
| 224 } | |
| 225 | |
| 175 if (rdh_->delegate()) { | 226 if (rdh_->delegate()) { |
| 176 rdh_->delegate()->OnResponseStarted( | 227 rdh_->delegate()->OnResponseStarted( |
| 177 request(), info->GetContext(), response, info->filter()); | 228 request(), info->GetContext(), response, info->filter()); |
| 178 } | 229 } |
| 179 | 230 |
| 180 DevToolsNetLogObserver::PopulateResponseInfo(request(), response); | 231 DevToolsNetLogObserver::PopulateResponseInfo(request(), response); |
| 181 | 232 |
| 182 const HostZoomMapImpl* host_zoom_map = | 233 const HostZoomMapImpl* host_zoom_map = |
| 183 static_cast<const HostZoomMapImpl*>(info->filter()->GetHostZoomMap()); | 234 static_cast<const HostZoomMapImpl*>(info->filter()->GetHostZoomMap()); |
| 184 | 235 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 213 request()->response_info().metadata->data() + | 264 request()->response_info().metadata->data() + |
| 214 request()->response_info().metadata->size()); | 265 request()->response_info().metadata->size()); |
| 215 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 266 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
| 216 copy)); | 267 copy)); |
| 217 } | 268 } |
| 218 | 269 |
| 219 return true; | 270 return true; |
| 220 } | 271 } |
| 221 | 272 |
| 222 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 273 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
| 274 if (GetRequestInfo()->is_upload_progress_enabled() && | |
| 275 request()->has_upload()) { | |
| 276 | |
|
mmenke
2015/08/26 19:13:12
nit: Remove blank line.
| |
| 277 ReportUploadProgress(); | |
| 278 progress_timer_.Start( | |
| 279 FROM_HERE, | |
| 280 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | |
| 281 this, | |
| 282 &AsyncResourceHandler::ReportUploadProgress); | |
| 283 } | |
| 223 return true; | 284 return true; |
| 224 } | 285 } |
| 225 | 286 |
| 226 bool AsyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { | 287 bool AsyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { |
| 227 return true; | 288 return true; |
| 228 } | 289 } |
| 229 | 290 |
| 230 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 291 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 231 int* buf_size, | 292 int* buf_size, |
| 232 int min_size) { | 293 int min_size) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 request()->LogUnblocked(); | 435 request()->LogUnblocked(); |
| 375 controller()->Resume(); | 436 controller()->Resume(); |
| 376 } | 437 } |
| 377 } | 438 } |
| 378 | 439 |
| 379 void AsyncResourceHandler::OnDefer() { | 440 void AsyncResourceHandler::OnDefer() { |
| 380 request()->LogBlockedBy("AsyncResourceHandler"); | 441 request()->LogBlockedBy("AsyncResourceHandler"); |
| 381 } | 442 } |
| 382 | 443 |
| 383 } // namespace content | 444 } // namespace content |
| OLD | NEW |