Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: content/browser/renderer_host/async_resource_handler.cc

Issue 10644011: Revert r143458 (which re-applies r143341 and r142979). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/renderer_host/async_resource_handler.h" 5 #include "content/browser/renderer_host/async_resource_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
11 #include "base/hash_tables.h" 11 #include "base/hash_tables.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/shared_memory.h" 13 #include "base/shared_memory.h"
14 #include "content/browser/debugger/devtools_netlog_observer.h" 14 #include "content/browser/debugger/devtools_netlog_observer.h"
15 #include "content/browser/host_zoom_map_impl.h" 15 #include "content/browser/host_zoom_map_impl.h"
16 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 16 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
17 #include "content/browser/renderer_host/resource_message_filter.h" 17 #include "content/browser/renderer_host/resource_message_filter.h"
18 #include "content/browser/renderer_host/resource_request_info_impl.h"
18 #include "content/browser/resource_context_impl.h" 19 #include "content/browser/resource_context_impl.h"
19 #include "content/common/resource_messages.h" 20 #include "content/common/resource_messages.h"
20 #include "content/common/view_messages.h" 21 #include "content/common/view_messages.h"
21 #include "content/public/browser/global_request_id.h" 22 #include "content/public/browser/global_request_id.h"
22 #include "content/public/browser/resource_dispatcher_host_delegate.h" 23 #include "content/public/browser/resource_dispatcher_host_delegate.h"
23 #include "content/public/browser/resource_request_info.h"
24 #include "content/public/common/resource_response.h" 24 #include "content/public/common/resource_response.h"
25 #include "net/base/io_buffer.h" 25 #include "net/base/io_buffer.h"
26 #include "net/base/load_flags.h" 26 #include "net/base/load_flags.h"
27 #include "net/base/net_log.h" 27 #include "net/base/net_log.h"
28 #include "webkit/glue/resource_loader_bridge.h" 28 #include "webkit/glue/resource_loader_bridge.h"
29 29
30 using base::TimeTicks; 30 using base::TimeTicks;
31 31
32 namespace content { 32 namespace content {
33 33
34 namespace { 34 namespace {
35 35
36 // When reading, we don't know if we are going to get EOF (0 bytes read), so 36 // When reading, we don't know if we are going to get EOF (0 bytes read), so
37 // we typically have a buffer that we allocated but did not use. We keep 37 // we typically have a buffer that we allocated but did not use. We keep
38 // this buffer around for the next read as a small optimization. 38 // this buffer around for the next read as a small optimization.
39 SharedIOBuffer* g_spare_read_buffer = NULL; 39 SharedIOBuffer* g_spare_read_buffer = NULL;
40 40
41 // The initial size of the shared memory buffer. (32 kilobytes). 41 // The initial size of the shared memory buffer. (32 kilobytes).
42 const int kInitialReadBufSize = 32768; 42 const int kInitialReadBufSize = 32768;
43 43
44 // The maximum size of the shared memory buffer. (512 kilobytes). 44 // The maximum size of the shared memory buffer. (512 kilobytes).
45 const int kMaxReadBufSize = 524288; 45 const int kMaxReadBufSize = 524288;
46 46
47 // Maximum number of pending data messages sent to the renderer at any
48 // given time for a given request.
49 const int kMaxPendingDataMessages = 20;
50
47 } // namespace 51 } // namespace
48 52
49 // Our version of IOBuffer that uses shared memory. 53 // Our version of IOBuffer that uses shared memory.
50 class SharedIOBuffer : public net::IOBuffer { 54 class SharedIOBuffer : public net::IOBuffer {
51 public: 55 public:
52 explicit SharedIOBuffer(int buffer_size) 56 explicit SharedIOBuffer(int buffer_size)
53 : net::IOBuffer(), 57 : net::IOBuffer(),
54 ok_(false), 58 ok_(false),
55 buffer_size_(buffer_size) {} 59 buffer_size_(buffer_size) {}
56 60
(...skipping 17 matching lines...) Expand all
74 } 78 }
75 79
76 base::SharedMemory shared_memory_; 80 base::SharedMemory shared_memory_;
77 bool ok_; 81 bool ok_;
78 int buffer_size_; 82 int buffer_size_;
79 }; 83 };
80 84
81 AsyncResourceHandler::AsyncResourceHandler( 85 AsyncResourceHandler::AsyncResourceHandler(
82 ResourceMessageFilter* filter, 86 ResourceMessageFilter* filter,
83 int routing_id, 87 int routing_id,
84 const GURL& url, 88 net::URLRequest* request,
85 ResourceDispatcherHostImpl* rdh) 89 ResourceDispatcherHostImpl* rdh)
86 : filter_(filter), 90 : filter_(filter),
87 routing_id_(routing_id), 91 routing_id_(routing_id),
92 request_(request),
88 rdh_(rdh), 93 rdh_(rdh),
89 next_buffer_size_(kInitialReadBufSize), 94 next_buffer_size_(kInitialReadBufSize),
90 url_(url) { 95 pending_data_count_(0),
96 did_defer_(false) {
97 // Set a back-pointer from ResourceRequestInfoImpl to |this|, so that the
98 // ResourceDispatcherHostImpl can send us IPC messages.
99 // TODO(darin): Implement an IPC message filter instead?
100 ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(this);
91 } 101 }
92 102
93 AsyncResourceHandler::~AsyncResourceHandler() { 103 AsyncResourceHandler::~AsyncResourceHandler() {
104 // Cleanup back-pointer stored on the request info.
105 ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(NULL);
106 }
107
108 void AsyncResourceHandler::OnFollowRedirect(
109 bool has_new_first_party_for_cookies,
110 const GURL& new_first_party_for_cookies) {
111 if (!request_->status().is_success()) {
112 DVLOG(1) << "OnFollowRedirect for invalid request";
113 return;
114 }
115
116 if (has_new_first_party_for_cookies)
117 request_->set_first_party_for_cookies(new_first_party_for_cookies);
118
119 ResumeIfDeferred();
120 }
121
122 void AsyncResourceHandler::OnDataReceivedACK() {
123 // If the pending data count was higher than the max, resume the request.
124 if (--pending_data_count_ == kMaxPendingDataMessages) {
125 // Decrement the pending data count one more time because we also
126 // incremented it before deferring the request.
127 --pending_data_count_;
128
129 // Resume the request.
130 ResumeIfDeferred();
131 }
94 } 132 }
95 133
96 bool AsyncResourceHandler::OnUploadProgress(int request_id, 134 bool AsyncResourceHandler::OnUploadProgress(int request_id,
97 uint64 position, 135 uint64 position,
98 uint64 size) { 136 uint64 size) {
99 return filter_->Send(new ResourceMsg_UploadProgress(routing_id_, request_id, 137 return filter_->Send(new ResourceMsg_UploadProgress(routing_id_, request_id,
100 position, size)); 138 position, size));
101 } 139 }
102 140
103 bool AsyncResourceHandler::OnRequestRedirected(int request_id, 141 bool AsyncResourceHandler::OnRequestRedirected(int request_id,
104 const GURL& new_url, 142 const GURL& new_url,
105 ResourceResponse* response, 143 ResourceResponse* response,
106 bool* defer) { 144 bool* defer) {
107 *defer = true; 145 *defer = did_defer_ = true;
108 net::URLRequest* request = rdh_->GetURLRequest( 146
109 GlobalRequestID(filter_->child_id(), request_id));
110 if (rdh_->delegate()) 147 if (rdh_->delegate())
111 rdh_->delegate()->OnRequestRedirected(request, response); 148 rdh_->delegate()->OnRequestRedirected(request_, response);
112 149
113 DevToolsNetLogObserver::PopulateResponseInfo(request, response); 150 DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
114 response->request_start = request->creation_time(); 151 response->request_start = request_->creation_time();
115 response->response_start = TimeTicks::Now(); 152 response->response_start = TimeTicks::Now();
116 return filter_->Send(new ResourceMsg_ReceivedRedirect( 153 return filter_->Send(new ResourceMsg_ReceivedRedirect(
117 routing_id_, request_id, new_url, *response)); 154 routing_id_, request_id, new_url, *response));
118 } 155 }
119 156
120 bool AsyncResourceHandler::OnResponseStarted(int request_id, 157 bool AsyncResourceHandler::OnResponseStarted(int request_id,
121 ResourceResponse* response, 158 ResourceResponse* response,
122 bool* defer) { 159 bool* defer) {
123 // For changes to the main frame, inform the renderer of the new URL's 160 // For changes to the main frame, inform the renderer of the new URL's
124 // per-host settings before the request actually commits. This way the 161 // per-host settings before the request actually commits. This way the
125 // renderer will be able to set these precisely at the time the 162 // renderer will be able to set these precisely at the time the
126 // request commits, avoiding the possibility of e.g. zooming the old content 163 // request commits, avoiding the possibility of e.g. zooming the old content
127 // or of having to layout the new content twice. 164 // or of having to layout the new content twice.
128 net::URLRequest* request = rdh_->GetURLRequest(
129 GlobalRequestID(filter_->child_id(), request_id));
130 165
131 if (rdh_->delegate()) 166 if (rdh_->delegate())
132 rdh_->delegate()->OnResponseStarted(request, response, filter_); 167 rdh_->delegate()->OnResponseStarted(request_, response, filter_);
133 168
134 DevToolsNetLogObserver::PopulateResponseInfo(request, response); 169 DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
135 170
136 ResourceContext* resource_context = filter_->resource_context(); 171 ResourceContext* resource_context = filter_->resource_context();
137 HostZoomMap* host_zoom_map = 172 HostZoomMap* host_zoom_map =
138 GetHostZoomMapForResourceContext(resource_context); 173 GetHostZoomMapForResourceContext(resource_context);
139 174
140 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 175 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
141 if (info->GetResourceType() == ResourceType::MAIN_FRAME && host_zoom_map) { 176 if (info->GetResourceType() == ResourceType::MAIN_FRAME && host_zoom_map) {
142 GURL request_url(request->url()); 177 const GURL& request_url = request_->url();
143 filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL( 178 filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(
144 info->GetRouteID(), 179 info->GetRouteID(),
145 request_url, host_zoom_map->GetZoomLevel(net::GetHostOrSpecFromURL( 180 request_url, host_zoom_map->GetZoomLevel(net::GetHostOrSpecFromURL(
146 request_url)))); 181 request_url))));
147 } 182 }
148 183
149 response->request_start = request->creation_time(); 184 response->request_start = request_->creation_time();
150 response->response_start = TimeTicks::Now(); 185 response->response_start = TimeTicks::Now();
151 filter_->Send(new ResourceMsg_ReceivedResponse( 186 filter_->Send(new ResourceMsg_ReceivedResponse(
152 routing_id_, request_id, *response)); 187 routing_id_, request_id, *response));
153 188
154 if (request->response_info().metadata) { 189 if (request_->response_info().metadata) {
155 std::vector<char> copy(request->response_info().metadata->data(), 190 std::vector<char> copy(request_->response_info().metadata->data(),
156 request->response_info().metadata->data() + 191 request_->response_info().metadata->data() +
157 request->response_info().metadata->size()); 192 request_->response_info().metadata->size());
158 filter_->Send(new ResourceMsg_ReceivedCachedMetadata( 193 filter_->Send(new ResourceMsg_ReceivedCachedMetadata(
159 routing_id_, request_id, copy)); 194 routing_id_, request_id, copy));
160 } 195 }
161 196
162 return true; 197 return true;
163 } 198 }
164 199
165 bool AsyncResourceHandler::OnWillStart(int request_id, 200 bool AsyncResourceHandler::OnWillStart(int request_id,
166 const GURL& url, 201 const GURL& url,
167 bool* defer) { 202 bool* defer) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 return true; 235 return true;
201 DCHECK(read_buffer_.get()); 236 DCHECK(read_buffer_.get());
202 237
203 if (read_buffer_->buffer_size() == *bytes_read) { 238 if (read_buffer_->buffer_size() == *bytes_read) {
204 // The network layer has saturated our buffer. Next time, we should give it 239 // The network layer has saturated our buffer. Next time, we should give it
205 // a bigger buffer for it to fill, to minimize the number of round trips we 240 // a bigger buffer for it to fill, to minimize the number of round trips we
206 // do with the renderer process. 241 // do with the renderer process.
207 next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize); 242 next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize);
208 } 243 }
209 244
210 if (!rdh_->WillSendData(filter_->child_id(), request_id, defer)) { 245 if (!WillSendData(defer)) {
211 // We should not send this data now, we have too many pending requests. 246 // We should not send this data now, we have too many pending requests.
212 return true; 247 return true;
213 } 248 }
214 249
215 base::SharedMemoryHandle handle; 250 base::SharedMemoryHandle handle;
216 if (!read_buffer_->shared_memory()->GiveToProcess( 251 if (!read_buffer_->shared_memory()->GiveToProcess(
217 filter_->peer_handle(), &handle)) { 252 filter_->peer_handle(), &handle)) {
218 // We wrongfully incremented the pending data count. Fake an ACK message 253 // We wrongfully incremented the pending data count. Fake an ACK message
219 // to fix this. We can't move this call above the WillSendData because 254 // to fix this. We can't move this call above the WillSendData because
220 // it's killing our read_buffer_, and we don't want that when we pause 255 // it's killing our read_buffer_, and we don't want that when we pause
221 // the request. 256 // the request.
222 rdh_->DataReceivedACK(filter_->child_id(), request_id); 257 OnDataReceivedACK();
258
223 // We just unmapped the memory. 259 // We just unmapped the memory.
224 read_buffer_ = NULL; 260 read_buffer_ = NULL;
225 return false; 261 return false;
226 } 262 }
227 // We just unmapped the memory. 263 // We just unmapped the memory.
228 read_buffer_ = NULL; 264 read_buffer_ = NULL;
229 265
230 net::URLRequest* request = rdh_->GetURLRequest(
231 GlobalRequestID(filter_->child_id(), request_id));
232 int encoded_data_length = 266 int encoded_data_length =
233 DevToolsNetLogObserver::GetAndResetEncodedDataLength(request); 267 DevToolsNetLogObserver::GetAndResetEncodedDataLength(request_);
234 filter_->Send(new ResourceMsg_DataReceived( 268 filter_->Send(new ResourceMsg_DataReceived(
235 routing_id_, request_id, handle, *bytes_read, encoded_data_length)); 269 routing_id_, request_id, handle, *bytes_read, encoded_data_length));
236 270
237 return true; 271 return true;
238 } 272 }
239 273
240 void AsyncResourceHandler::OnDataDownloaded( 274 void AsyncResourceHandler::OnDataDownloaded(
241 int request_id, int bytes_downloaded) { 275 int request_id, int bytes_downloaded) {
242 filter_->Send(new ResourceMsg_DataDownloaded( 276 filter_->Send(new ResourceMsg_DataDownloaded(
243 routing_id_, request_id, bytes_downloaded)); 277 routing_id_, request_id, bytes_downloaded));
244 } 278 }
245 279
246 bool AsyncResourceHandler::OnResponseCompleted( 280 bool AsyncResourceHandler::OnResponseCompleted(
247 int request_id, 281 int request_id,
248 const net::URLRequestStatus& status, 282 const net::URLRequestStatus& status,
249 const std::string& security_info) { 283 const std::string& security_info) {
250 // If we crash here, figure out what URL the renderer was requesting. 284 // If we crash here, figure out what URL the renderer was requesting.
251 // http://crbug.com/107692 285 // http://crbug.com/107692
252 char url_buf[128]; 286 char url_buf[128];
253 base::strlcpy(url_buf, url_.spec().c_str(), arraysize(url_buf)); 287 base::strlcpy(url_buf, request_->url().spec().c_str(), arraysize(url_buf));
254 base::debug::Alias(url_buf); 288 base::debug::Alias(url_buf);
255 289
256 TimeTicks completion_time = TimeTicks::Now(); 290 TimeTicks completion_time = TimeTicks::Now();
257 filter_->Send(new ResourceMsg_RequestComplete(routing_id_, 291 filter_->Send(new ResourceMsg_RequestComplete(routing_id_,
258 request_id, 292 request_id,
259 status, 293 status,
260 security_info, 294 security_info,
261 completion_time)); 295 completion_time));
262 296
263 // If we still have a read buffer, then see about caching it for later... 297 // If we still have a read buffer, then see about caching it for later...
(...skipping 12 matching lines...) Expand all
276 // static 310 // static
277 void AsyncResourceHandler::GlobalCleanup() { 311 void AsyncResourceHandler::GlobalCleanup() {
278 if (g_spare_read_buffer) { 312 if (g_spare_read_buffer) {
279 // Avoid the CHECK in SharedIOBuffer::~SharedIOBuffer(). 313 // Avoid the CHECK in SharedIOBuffer::~SharedIOBuffer().
280 SharedIOBuffer* tmp = g_spare_read_buffer; 314 SharedIOBuffer* tmp = g_spare_read_buffer;
281 g_spare_read_buffer = NULL; 315 g_spare_read_buffer = NULL;
282 tmp->Release(); 316 tmp->Release();
283 } 317 }
284 } 318 }
285 319
320 bool AsyncResourceHandler::WillSendData(bool* defer) {
321 if (++pending_data_count_ > kMaxPendingDataMessages) {
322 // We reached the max number of data messages that can be sent to
323 // the renderer for a given request. Pause the request and wait for
324 // the renderer to start processing them before resuming it.
325 *defer = did_defer_ = true;
326 return false;
327 }
328
329 return true;
330 }
331
332 void AsyncResourceHandler::ResumeIfDeferred() {
333 if (did_defer_) {
334 did_defer_ = false;
335 controller()->Resume();
336 }
337 }
338
286 } // namespace content 339 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698