OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/async_resource_handler.h" | 5 #include "chrome/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/hash_tables.h" | 10 #include "base/hash_tables.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/process.h" | |
13 #include "base/shared_memory.h" | 12 #include "base/shared_memory.h" |
14 #include "chrome/browser/debugger/devtools_netlog_observer.h" | 13 #include "chrome/browser/debugger/devtools_netlog_observer.h" |
15 #include "chrome/browser/net/chrome_url_request_context.h" | 14 #include "chrome/browser/net/chrome_url_request_context.h" |
16 #include "chrome/browser/net/load_timing_observer.h" | 15 #include "chrome/browser/net/load_timing_observer.h" |
17 #include "chrome/browser/renderer_host/global_request_id.h" | 16 #include "chrome/browser/renderer_host/global_request_id.h" |
| 17 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
18 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" | 18 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 19 #include "chrome/browser/renderer_host/resource_message_filter.h" |
19 #include "chrome/common/render_messages.h" | 20 #include "chrome/common/render_messages.h" |
20 #include "chrome/common/resource_response.h" | 21 #include "chrome/common/resource_response.h" |
21 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
22 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
23 #include "net/base/net_log.h" | 24 #include "net/base/net_log.h" |
24 #include "webkit/glue/resource_loader_bridge.h" | 25 #include "webkit/glue/resource_loader_bridge.h" |
25 | 26 |
26 using base::Time; | 27 using base::Time; |
27 using base::TimeTicks; | 28 using base::TimeTicks; |
28 | 29 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 DCHECK(g_spare_read_buffer != this); | 68 DCHECK(g_spare_read_buffer != this); |
68 data_ = NULL; | 69 data_ = NULL; |
69 } | 70 } |
70 | 71 |
71 base::SharedMemory shared_memory_; | 72 base::SharedMemory shared_memory_; |
72 bool ok_; | 73 bool ok_; |
73 int buffer_size_; | 74 int buffer_size_; |
74 }; | 75 }; |
75 | 76 |
76 AsyncResourceHandler::AsyncResourceHandler( | 77 AsyncResourceHandler::AsyncResourceHandler( |
77 ResourceDispatcherHost::Receiver* receiver, | 78 ResourceMessageFilter* filter, |
78 int process_id, | |
79 int routing_id, | 79 int routing_id, |
80 base::ProcessHandle process_handle, | |
81 const GURL& url, | 80 const GURL& url, |
82 ResourceDispatcherHost* resource_dispatcher_host) | 81 ResourceDispatcherHost* resource_dispatcher_host) |
83 : receiver_(receiver), | 82 : filter_(filter), |
84 process_id_(process_id), | |
85 routing_id_(routing_id), | 83 routing_id_(routing_id), |
86 process_handle_(process_handle), | |
87 rdh_(resource_dispatcher_host), | 84 rdh_(resource_dispatcher_host), |
88 next_buffer_size_(kInitialReadBufSize) { | 85 next_buffer_size_(kInitialReadBufSize) { |
89 } | 86 } |
90 | 87 |
91 AsyncResourceHandler::~AsyncResourceHandler() { | 88 AsyncResourceHandler::~AsyncResourceHandler() { |
92 } | 89 } |
93 | 90 |
94 bool AsyncResourceHandler::OnUploadProgress(int request_id, | 91 bool AsyncResourceHandler::OnUploadProgress(int request_id, |
95 uint64 position, | 92 uint64 position, |
96 uint64 size) { | 93 uint64 size) { |
97 return receiver_->Send(new ViewMsg_Resource_UploadProgress(routing_id_, | 94 return filter_->Send(new ViewMsg_Resource_UploadProgress(routing_id_, |
98 request_id, | 95 request_id, |
99 position, size)); | 96 position, size)); |
100 } | 97 } |
101 | 98 |
102 bool AsyncResourceHandler::OnRequestRedirected(int request_id, | 99 bool AsyncResourceHandler::OnRequestRedirected(int request_id, |
103 const GURL& new_url, | 100 const GURL& new_url, |
104 ResourceResponse* response, | 101 ResourceResponse* response, |
105 bool* defer) { | 102 bool* defer) { |
106 *defer = true; | 103 *defer = true; |
107 net::URLRequest* request = rdh_->GetURLRequest( | 104 net::URLRequest* request = rdh_->GetURLRequest( |
108 GlobalRequestID(process_id_, request_id)); | 105 GlobalRequestID(filter_->child_id(), request_id)); |
109 LoadTimingObserver::PopulateTimingInfo(request, response); | 106 LoadTimingObserver::PopulateTimingInfo(request, response); |
110 DevToolsNetLogObserver::PopulateResponseInfo(request, response); | 107 DevToolsNetLogObserver::PopulateResponseInfo(request, response); |
111 return receiver_->Send(new ViewMsg_Resource_ReceivedRedirect( | 108 return filter_->Send(new ViewMsg_Resource_ReceivedRedirect( |
112 routing_id_, request_id, new_url, response->response_head)); | 109 routing_id_, request_id, new_url, response->response_head)); |
113 } | 110 } |
114 | 111 |
115 bool AsyncResourceHandler::OnResponseStarted(int request_id, | 112 bool AsyncResourceHandler::OnResponseStarted(int request_id, |
116 ResourceResponse* response) { | 113 ResourceResponse* response) { |
117 // For changes to the main frame, inform the renderer of the new URL's | 114 // For changes to the main frame, inform the renderer of the new URL's |
118 // per-host settings before the request actually commits. This way the | 115 // per-host settings before the request actually commits. This way the |
119 // renderer will be able to set these precisely at the time the | 116 // renderer will be able to set these precisely at the time the |
120 // request commits, avoiding the possibility of e.g. zooming the old content | 117 // request commits, avoiding the possibility of e.g. zooming the old content |
121 // or of having to layout the new content twice. | 118 // or of having to layout the new content twice. |
122 net::URLRequest* request = rdh_->GetURLRequest( | 119 net::URLRequest* request = rdh_->GetURLRequest( |
123 GlobalRequestID(process_id_, request_id)); | 120 GlobalRequestID(filter_->child_id(), request_id)); |
124 | 121 |
125 LoadTimingObserver::PopulateTimingInfo(request, response); | 122 LoadTimingObserver::PopulateTimingInfo(request, response); |
126 DevToolsNetLogObserver::PopulateResponseInfo(request, response); | 123 DevToolsNetLogObserver::PopulateResponseInfo(request, response); |
127 | 124 |
128 ResourceDispatcherHostRequestInfo* info = rdh_->InfoForRequest(request); | 125 ResourceDispatcherHostRequestInfo* info = rdh_->InfoForRequest(request); |
129 if (info->resource_type() == ResourceType::MAIN_FRAME) { | 126 if (info->resource_type() == ResourceType::MAIN_FRAME) { |
130 GURL request_url(request->url()); | 127 GURL request_url(request->url()); |
131 ChromeURLRequestContext* context = | 128 ChromeURLRequestContext* context = |
132 static_cast<ChromeURLRequestContext*>(request->context()); | 129 static_cast<ChromeURLRequestContext*>(request->context()); |
133 if (context) { | 130 if (context) { |
134 receiver_->Send(new ViewMsg_SetContentSettingsForLoadingURL( | 131 filter_->Send(new ViewMsg_SetContentSettingsForLoadingURL( |
135 info->route_id(), request_url, | 132 info->route_id(), request_url, |
136 context->host_content_settings_map()->GetContentSettings( | 133 context->host_content_settings_map()->GetContentSettings( |
137 request_url))); | 134 request_url))); |
138 receiver_->Send(new ViewMsg_SetZoomLevelForLoadingURL(info->route_id(), | 135 filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(info->route_id(), |
139 request_url, context->host_zoom_map()->GetZoomLevel(request_url))); | 136 request_url, context->host_zoom_map()->GetZoomLevel(request_url))); |
140 } | 137 } |
141 } | 138 } |
142 | 139 |
143 receiver_->Send(new ViewMsg_Resource_ReceivedResponse( | 140 filter_->Send(new ViewMsg_Resource_ReceivedResponse( |
144 routing_id_, request_id, response->response_head)); | 141 routing_id_, request_id, response->response_head)); |
145 | 142 |
146 if (request->response_info().metadata) { | 143 if (request->response_info().metadata) { |
147 std::vector<char> copy(request->response_info().metadata->data(), | 144 std::vector<char> copy(request->response_info().metadata->data(), |
148 request->response_info().metadata->data() + | 145 request->response_info().metadata->data() + |
149 request->response_info().metadata->size()); | 146 request->response_info().metadata->size()); |
150 receiver_->Send(new ViewMsg_Resource_ReceivedCachedMetadata( | 147 filter_->Send(new ViewMsg_Resource_ReceivedCachedMetadata( |
151 routing_id_, request_id, copy)); | 148 routing_id_, request_id, copy)); |
152 } | 149 } |
153 | 150 |
154 return true; | 151 return true; |
155 } | 152 } |
156 | 153 |
157 bool AsyncResourceHandler::OnWillStart(int request_id, | 154 bool AsyncResourceHandler::OnWillStart(int request_id, |
158 const GURL& url, | 155 const GURL& url, |
159 bool* defer) { | 156 bool* defer) { |
160 return true; | 157 return true; |
(...skipping 30 matching lines...) Expand all Loading... |
191 return true; | 188 return true; |
192 DCHECK(read_buffer_.get()); | 189 DCHECK(read_buffer_.get()); |
193 | 190 |
194 if (read_buffer_->buffer_size() == *bytes_read) { | 191 if (read_buffer_->buffer_size() == *bytes_read) { |
195 // The network layer has saturated our buffer. Next time, we should give it | 192 // The network layer has saturated our buffer. Next time, we should give it |
196 // a bigger buffer for it to fill, to minimize the number of round trips we | 193 // a bigger buffer for it to fill, to minimize the number of round trips we |
197 // do with the renderer process. | 194 // do with the renderer process. |
198 next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize); | 195 next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize); |
199 } | 196 } |
200 | 197 |
201 if (!rdh_->WillSendData(process_id_, request_id)) { | 198 if (!rdh_->WillSendData(filter_->child_id(), request_id)) { |
202 // We should not send this data now, we have too many pending requests. | 199 // We should not send this data now, we have too many pending requests. |
203 return true; | 200 return true; |
204 } | 201 } |
205 | 202 |
206 base::SharedMemoryHandle handle; | 203 base::SharedMemoryHandle handle; |
207 if (!read_buffer_->shared_memory()->GiveToProcess(process_handle_, &handle)) { | 204 if (!read_buffer_->shared_memory()->GiveToProcess( |
| 205 filter_->peer_handle(), &handle)) { |
208 // We wrongfully incremented the pending data count. Fake an ACK message | 206 // We wrongfully incremented the pending data count. Fake an ACK message |
209 // to fix this. We can't move this call above the WillSendData because | 207 // to fix this. We can't move this call above the WillSendData because |
210 // it's killing our read_buffer_, and we don't want that when we pause | 208 // it's killing our read_buffer_, and we don't want that when we pause |
211 // the request. | 209 // the request. |
212 rdh_->DataReceivedACK(process_id_, request_id); | 210 rdh_->DataReceivedACK(filter_->child_id(), request_id); |
213 // We just unmapped the memory. | 211 // We just unmapped the memory. |
214 read_buffer_ = NULL; | 212 read_buffer_ = NULL; |
215 return false; | 213 return false; |
216 } | 214 } |
217 // We just unmapped the memory. | 215 // We just unmapped the memory. |
218 read_buffer_ = NULL; | 216 read_buffer_ = NULL; |
219 | 217 |
220 receiver_->Send(new ViewMsg_Resource_DataReceived( | 218 filter_->Send(new ViewMsg_Resource_DataReceived( |
221 routing_id_, request_id, handle, *bytes_read)); | 219 routing_id_, request_id, handle, *bytes_read)); |
222 | 220 |
223 return true; | 221 return true; |
224 } | 222 } |
225 | 223 |
226 void AsyncResourceHandler::OnDataDownloaded( | 224 void AsyncResourceHandler::OnDataDownloaded( |
227 int request_id, int bytes_downloaded) { | 225 int request_id, int bytes_downloaded) { |
228 receiver_->Send(new ViewMsg_Resource_DataDownloaded( | 226 filter_->Send(new ViewMsg_Resource_DataDownloaded( |
229 routing_id_, request_id, bytes_downloaded)); | 227 routing_id_, request_id, bytes_downloaded)); |
230 } | 228 } |
231 | 229 |
232 bool AsyncResourceHandler::OnResponseCompleted( | 230 bool AsyncResourceHandler::OnResponseCompleted( |
233 int request_id, | 231 int request_id, |
234 const URLRequestStatus& status, | 232 const URLRequestStatus& status, |
235 const std::string& security_info) { | 233 const std::string& security_info) { |
236 Time completion_time = Time::Now(); | 234 Time completion_time = Time::Now(); |
237 receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, | 235 filter_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, |
238 request_id, | 236 request_id, |
239 status, | 237 status, |
240 security_info, | 238 security_info, |
241 completion_time)); | 239 completion_time)); |
242 | 240 |
243 // If we still have a read buffer, then see about caching it for later... | 241 // If we still have a read buffer, then see about caching it for later... |
244 // Note that we have to make sure the buffer is not still being used, so we | 242 // Note that we have to make sure the buffer is not still being used, so we |
245 // have to perform an explicit check on the status code. | 243 // have to perform an explicit check on the status code. |
246 if (g_spare_read_buffer || URLRequestStatus::SUCCESS != status.status()) { | 244 if (g_spare_read_buffer || URLRequestStatus::SUCCESS != status.status()) { |
247 read_buffer_ = NULL; | 245 read_buffer_ = NULL; |
248 } else if (read_buffer_.get()) { | 246 } else if (read_buffer_.get()) { |
249 DCHECK(read_buffer_->data()); | 247 DCHECK(read_buffer_->data()); |
250 read_buffer_.swap(&g_spare_read_buffer); | 248 read_buffer_.swap(&g_spare_read_buffer); |
251 } | 249 } |
252 return true; | 250 return true; |
253 } | 251 } |
254 | 252 |
255 void AsyncResourceHandler::OnRequestClosed() { | 253 void AsyncResourceHandler::OnRequestClosed() { |
256 } | 254 } |
257 | 255 |
258 // static | 256 // static |
259 void AsyncResourceHandler::GlobalCleanup() { | 257 void AsyncResourceHandler::GlobalCleanup() { |
260 if (g_spare_read_buffer) { | 258 if (g_spare_read_buffer) { |
261 // Avoid the CHECK in SharedIOBuffer::~SharedIOBuffer(). | 259 // Avoid the CHECK in SharedIOBuffer::~SharedIOBuffer(). |
262 SharedIOBuffer* tmp = g_spare_read_buffer; | 260 SharedIOBuffer* tmp = g_spare_read_buffer; |
263 g_spare_read_buffer = NULL; | 261 g_spare_read_buffer = NULL; |
264 tmp->Release(); | 262 tmp->Release(); |
265 } | 263 } |
266 } | 264 } |
OLD | NEW |