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

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

Issue 6532073: Move core pieces of browser\renderer_host to src\content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 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
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/renderer_host/async_resource_handler.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/hash_tables.h"
11 #include "base/logging.h"
12 #include "base/shared_memory.h"
13 #include "chrome/browser/debugger/devtools_netlog_observer.h"
14 #include "chrome/browser/net/chrome_url_request_context.h"
15 #include "chrome/browser/net/load_timing_observer.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"
19 #include "chrome/browser/renderer_host/resource_message_filter.h"
20 #include "chrome/common/render_messages.h"
21 #include "chrome/common/resource_response.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/load_flags.h"
24 #include "net/base/net_log.h"
25 #include "webkit/glue/resource_loader_bridge.h"
26
27 using base::Time;
28 using base::TimeTicks;
29
30 namespace {
31
32 // When reading, we don't know if we are going to get EOF (0 bytes read), so
33 // we typically have a buffer that we allocated but did not use. We keep
34 // this buffer around for the next read as a small optimization.
35 SharedIOBuffer* g_spare_read_buffer = NULL;
36
37 // The initial size of the shared memory buffer. (32 kilobytes).
38 const int kInitialReadBufSize = 32768;
39
40 // The maximum size of the shared memory buffer. (512 kilobytes).
41 const int kMaxReadBufSize = 524288;
42
43 } // namespace
44
45 // Our version of IOBuffer that uses shared memory.
46 class SharedIOBuffer : public net::IOBuffer {
47 public:
48 explicit SharedIOBuffer(int buffer_size)
49 : net::IOBuffer(),
50 ok_(false),
51 buffer_size_(buffer_size) {}
52
53 bool Init() {
54 if (shared_memory_.CreateAndMapAnonymous(buffer_size_)) {
55 data_ = reinterpret_cast<char*>(shared_memory_.memory());
56 DCHECK(data_);
57 ok_ = true;
58 }
59 return ok_;
60 }
61
62 base::SharedMemory* shared_memory() { return &shared_memory_; }
63 bool ok() { return ok_; }
64 int buffer_size() { return buffer_size_; }
65
66 private:
67 ~SharedIOBuffer() {
68 DCHECK(g_spare_read_buffer != this);
69 data_ = NULL;
70 }
71
72 base::SharedMemory shared_memory_;
73 bool ok_;
74 int buffer_size_;
75 };
76
77 AsyncResourceHandler::AsyncResourceHandler(
78 ResourceMessageFilter* filter,
79 int routing_id,
80 const GURL& url,
81 ResourceDispatcherHost* resource_dispatcher_host)
82 : filter_(filter),
83 routing_id_(routing_id),
84 rdh_(resource_dispatcher_host),
85 next_buffer_size_(kInitialReadBufSize) {
86 }
87
88 AsyncResourceHandler::~AsyncResourceHandler() {
89 }
90
91 bool AsyncResourceHandler::OnUploadProgress(int request_id,
92 uint64 position,
93 uint64 size) {
94 return filter_->Send(new ViewMsg_Resource_UploadProgress(routing_id_,
95 request_id,
96 position, size));
97 }
98
99 bool AsyncResourceHandler::OnRequestRedirected(int request_id,
100 const GURL& new_url,
101 ResourceResponse* response,
102 bool* defer) {
103 *defer = true;
104 net::URLRequest* request = rdh_->GetURLRequest(
105 GlobalRequestID(filter_->child_id(), request_id));
106 LoadTimingObserver::PopulateTimingInfo(request, response);
107 DevToolsNetLogObserver::PopulateResponseInfo(request, response);
108 return filter_->Send(new ViewMsg_Resource_ReceivedRedirect(
109 routing_id_, request_id, new_url, response->response_head));
110 }
111
112 bool AsyncResourceHandler::OnResponseStarted(int request_id,
113 ResourceResponse* response) {
114 // For changes to the main frame, inform the renderer of the new URL's
115 // per-host settings before the request actually commits. This way the
116 // renderer will be able to set these precisely at the time the
117 // request commits, avoiding the possibility of e.g. zooming the old content
118 // or of having to layout the new content twice.
119 net::URLRequest* request = rdh_->GetURLRequest(
120 GlobalRequestID(filter_->child_id(), request_id));
121
122 LoadTimingObserver::PopulateTimingInfo(request, response);
123 DevToolsNetLogObserver::PopulateResponseInfo(request, response);
124
125 ResourceDispatcherHostRequestInfo* info = rdh_->InfoForRequest(request);
126 if (info->resource_type() == ResourceType::MAIN_FRAME) {
127 GURL request_url(request->url());
128 ChromeURLRequestContext* context =
129 static_cast<ChromeURLRequestContext*>(request->context());
130 if (context) {
131 filter_->Send(new ViewMsg_SetContentSettingsForLoadingURL(
132 info->route_id(), request_url,
133 context->host_content_settings_map()->GetContentSettings(
134 request_url)));
135 filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(info->route_id(),
136 request_url, context->host_zoom_map()->GetZoomLevel(request_url)));
137 }
138 }
139
140 filter_->Send(new ViewMsg_Resource_ReceivedResponse(
141 routing_id_, request_id, response->response_head));
142
143 if (request->response_info().metadata) {
144 std::vector<char> copy(request->response_info().metadata->data(),
145 request->response_info().metadata->data() +
146 request->response_info().metadata->size());
147 filter_->Send(new ViewMsg_Resource_ReceivedCachedMetadata(
148 routing_id_, request_id, copy));
149 }
150
151 return true;
152 }
153
154 bool AsyncResourceHandler::OnWillStart(int request_id,
155 const GURL& url,
156 bool* defer) {
157 return true;
158 }
159
160 bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
161 int* buf_size, int min_size) {
162 DCHECK_EQ(-1, min_size);
163
164 if (g_spare_read_buffer) {
165 DCHECK(!read_buffer_);
166 read_buffer_.swap(&g_spare_read_buffer);
167 DCHECK(read_buffer_->data());
168
169 *buf = read_buffer_.get();
170 *buf_size = read_buffer_->buffer_size();
171 } else {
172 read_buffer_ = new SharedIOBuffer(next_buffer_size_);
173 if (!read_buffer_->Init()) {
174 DLOG(ERROR) << "Couldn't allocate shared io buffer";
175 read_buffer_ = NULL;
176 return false;
177 }
178 DCHECK(read_buffer_->data());
179 *buf = read_buffer_.get();
180 *buf_size = next_buffer_size_;
181 }
182
183 return true;
184 }
185
186 bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
187 if (!*bytes_read)
188 return true;
189 DCHECK(read_buffer_.get());
190
191 if (read_buffer_->buffer_size() == *bytes_read) {
192 // The network layer has saturated our buffer. Next time, we should give it
193 // a bigger buffer for it to fill, to minimize the number of round trips we
194 // do with the renderer process.
195 next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize);
196 }
197
198 if (!rdh_->WillSendData(filter_->child_id(), request_id)) {
199 // We should not send this data now, we have too many pending requests.
200 return true;
201 }
202
203 base::SharedMemoryHandle handle;
204 if (!read_buffer_->shared_memory()->GiveToProcess(
205 filter_->peer_handle(), &handle)) {
206 // We wrongfully incremented the pending data count. Fake an ACK message
207 // to fix this. We can't move this call above the WillSendData because
208 // it's killing our read_buffer_, and we don't want that when we pause
209 // the request.
210 rdh_->DataReceivedACK(filter_->child_id(), request_id);
211 // We just unmapped the memory.
212 read_buffer_ = NULL;
213 return false;
214 }
215 // We just unmapped the memory.
216 read_buffer_ = NULL;
217
218 filter_->Send(new ViewMsg_Resource_DataReceived(
219 routing_id_, request_id, handle, *bytes_read));
220
221 return true;
222 }
223
224 void AsyncResourceHandler::OnDataDownloaded(
225 int request_id, int bytes_downloaded) {
226 filter_->Send(new ViewMsg_Resource_DataDownloaded(
227 routing_id_, request_id, bytes_downloaded));
228 }
229
230 bool AsyncResourceHandler::OnResponseCompleted(
231 int request_id,
232 const net::URLRequestStatus& status,
233 const std::string& security_info) {
234 Time completion_time = Time::Now();
235 filter_->Send(new ViewMsg_Resource_RequestComplete(routing_id_,
236 request_id,
237 status,
238 security_info,
239 completion_time));
240
241 // If we still have a read buffer, then see about caching it for later...
242 // Note that we have to make sure the buffer is not still being used, so we
243 // have to perform an explicit check on the status code.
244 if (g_spare_read_buffer ||
245 net::URLRequestStatus::SUCCESS != status.status()) {
246 read_buffer_ = NULL;
247 } else if (read_buffer_.get()) {
248 DCHECK(read_buffer_->data());
249 read_buffer_.swap(&g_spare_read_buffer);
250 }
251 return true;
252 }
253
254 void AsyncResourceHandler::OnRequestClosed() {
255 }
256
257 // static
258 void AsyncResourceHandler::GlobalCleanup() {
259 if (g_spare_read_buffer) {
260 // Avoid the CHECK in SharedIOBuffer::~SharedIOBuffer().
261 SharedIOBuffer* tmp = g_spare_read_buffer;
262 g_spare_read_buffer = NULL;
263 tmp->Release();
264 }
265 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698