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

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

Issue 18390: Change URLRequest to use a ref-counted buffer for actual IO.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/buffered_resource_handler.h" 5 #include "chrome/browser/renderer_host/buffered_resource_handler.h"
6 6
7 #include "base/histogram.h" 7 #include "base/histogram.h"
8 #include "net/base/mime_sniffer.h" 8 #include "net/base/mime_sniffer.h"
9 #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" 9 #include "chrome/browser/renderer_host/download_throttling_resource_handler.h"
10 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 10 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
11 #include "net/base/mime_sniffer.h"
12 #include "net/base/io_buffer.h"
11 13
12 namespace { 14 namespace {
13 15
16 const int kMaxBytesToSniff = 512;
17
14 void RecordSnifferMetrics(bool sniffing_blocked, 18 void RecordSnifferMetrics(bool sniffing_blocked,
15 bool we_would_like_to_sniff, 19 bool we_would_like_to_sniff,
16 const std::string& mime_type) { 20 const std::string& mime_type) {
17 static BooleanHistogram nosniff_usage(L"nosniff.usage"); 21 static BooleanHistogram nosniff_usage(L"nosniff.usage");
18 nosniff_usage.SetFlags(kUmaTargetedHistogramFlag); 22 nosniff_usage.SetFlags(kUmaTargetedHistogramFlag);
19 nosniff_usage.AddBoolean(sniffing_blocked); 23 nosniff_usage.AddBoolean(sniffing_blocked);
20 24
21 if (sniffing_blocked) { 25 if (sniffing_blocked) {
22 static BooleanHistogram nosniff_otherwise(L"nosniff.otherwise"); 26 static BooleanHistogram nosniff_otherwise(L"nosniff.otherwise");
23 nosniff_otherwise.SetFlags(kUmaTargetedHistogramFlag); 27 nosniff_otherwise.SetFlags(kUmaTargetedHistogramFlag);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 68 }
65 69
66 70
67 bool BufferedResourceHandler::OnResponseCompleted( 71 bool BufferedResourceHandler::OnResponseCompleted(
68 int request_id, const URLRequestStatus& status) { 72 int request_id, const URLRequestStatus& status) {
69 return real_handler_->OnResponseCompleted(request_id, status); 73 return real_handler_->OnResponseCompleted(request_id, status);
70 } 74 }
71 75
72 // We'll let the original event handler provide a buffer, and reuse it for 76 // We'll let the original event handler provide a buffer, and reuse it for
73 // subsequent reads until we're done buffering. 77 // subsequent reads until we're done buffering.
74 bool BufferedResourceHandler::OnWillRead(int request_id, 78 bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
75 char** buf, int* buf_size, 79 int* buf_size, int min_size) {
76 int min_size) {
77 if (buffering_) { 80 if (buffering_) {
78 *buf = read_buffer_ + bytes_read_; 81 DCHECK(!my_buffer_.get());
79 *buf_size = read_buffer_size_ - bytes_read_; 82 my_buffer_ = new net::IOBuffer(kMaxBytesToSniff);
80 DCHECK(*buf_size > 0); 83 *buf = my_buffer_.get();
84 *buf_size = kMaxBytesToSniff;
81 return true; 85 return true;
82 } 86 }
83 87
84 if (finished_) 88 if (finished_)
85 return false; 89 return false;
86 90
87 bool ret = real_handler_->OnWillRead(request_id, buf, buf_size, min_size); 91 bool ret = real_handler_->OnWillRead(request_id, buf, buf_size, min_size);
88 read_buffer_ = *buf; 92 read_buffer_ = *buf;
89 read_buffer_size_ = *buf_size; 93 read_buffer_size_ = *buf_size;
94 DCHECK(read_buffer_size_ >= kMaxBytesToSniff * 2);
90 bytes_read_ = 0; 95 bytes_read_ = 0;
91 return ret; 96 return ret;
92 } 97 }
93 98
94 bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { 99 bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
95 if (sniff_content_ || should_buffer_) { 100 if (sniff_content_ || should_buffer_) {
96 if (KeepBuffering(*bytes_read)) 101 if (KeepBuffering(*bytes_read))
97 return true; 102 return true;
98 103
99 LOG(INFO) << "Finished buffering " << request_->url().spec(); 104 LOG(INFO) << "Finished buffering " << request_->url().spec();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 return false; 166 return false;
162 167
163 // Today, the only reason to buffer the request is to fix the doctype decoding 168 // Today, the only reason to buffer the request is to fix the doctype decoding
164 // performed by webkit: if there is not enough data it will go to quirks mode. 169 // performed by webkit: if there is not enough data it will go to quirks mode.
165 // We only expect the doctype check to apply to html documents. 170 // We only expect the doctype check to apply to html documents.
166 return mime_type == "text/html"; 171 return mime_type == "text/html";
167 } 172 }
168 173
169 bool BufferedResourceHandler::KeepBuffering(int bytes_read) { 174 bool BufferedResourceHandler::KeepBuffering(int bytes_read) {
170 DCHECK(read_buffer_); 175 DCHECK(read_buffer_);
176 if (my_buffer_) {
177 // We are using our own buffer to read, update the main buffer.
178 CHECK(bytes_read + bytes_read_ < read_buffer_size_);
179 memcpy(read_buffer_->data() + bytes_read_, my_buffer_->data(), bytes_read);
180 my_buffer_ = NULL;
181 }
171 bytes_read_ += bytes_read; 182 bytes_read_ += bytes_read;
172 finished_ = (bytes_read == 0); 183 finished_ = (bytes_read == 0);
173 184
174 if (sniff_content_) { 185 if (sniff_content_) {
175 std::string type_hint, new_type; 186 std::string type_hint, new_type;
176 request_->GetMimeType(&type_hint); 187 request_->GetMimeType(&type_hint);
177 188
178 if (!net::SniffMimeType(read_buffer_, bytes_read_, request_->url(), 189 if (!net::SniffMimeType(read_buffer_->data(), bytes_read_,
179 type_hint, &new_type)) { 190 request_->url(), type_hint, &new_type)) {
180 // SniffMimeType() returns false if there is not enough data to determine 191 // SniffMimeType() returns false if there is not enough data to determine
181 // the mime type. However, even if it returns false, it returns a new type 192 // the mime type. However, even if it returns false, it returns a new type
182 // that is probably better than the current one. 193 // that is probably better than the current one.
183 DCHECK(bytes_read_ < 512 /*kMaxBytesToSniff*/); 194 DCHECK(bytes_read_ < kMaxBytesToSniff);
184 if (!finished_) { 195 if (!finished_) {
185 buffering_ = true; 196 buffering_ = true;
186 return true; 197 return true;
187 } 198 }
188 } 199 }
189 sniff_content_ = false; 200 sniff_content_ = false;
190 response_->response_head.mime_type.assign(new_type); 201 response_->response_head.mime_type.assign(new_type);
191 202
192 // We just sniffed the mime type, maybe there is a doctype to process. 203 // We just sniffed the mime type, maybe there is a doctype to process.
193 if (ShouldBuffer(request_->url(), new_type)) 204 if (ShouldBuffer(request_->url(), new_type))
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 new DownloadThrottlingResourceHandler(host_, 247 new DownloadThrottlingResourceHandler(host_,
237 request_, 248 request_,
238 request_->url().spec(), 249 request_->url().spec(),
239 info->render_process_host_id, 250 info->render_process_host_id,
240 info->render_view_id, 251 info->render_view_id,
241 request_id, 252 request_id,
242 in_complete); 253 in_complete);
243 if (bytes_read_) { 254 if (bytes_read_) {
244 // a Read has already occurred and we need to copy the data into the 255 // a Read has already occurred and we need to copy the data into the
245 // EventHandler. 256 // EventHandler.
246 char *buf = NULL; 257 net::IOBuffer* buf = NULL;
247 int buf_len = 0; 258 int buf_len = 0;
248 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); 259 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_);
249 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); 260 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0));
250 memcpy(buf, read_buffer_, bytes_read_); 261 memcpy(buf->data(), read_buffer_->data(), bytes_read_);
251 } 262 }
252 // Update the renderer with the response headers which will cause it to 263 // Update the renderer with the response headers which will cause it to
253 // cancel the request. 264 // cancel the request.
254 // TODO(paulg): Send the renderer a response that indicates that the request 265 // TODO(paulg): Send the renderer a response that indicates that the request
255 // will be handled by an external source (the browser). 266 // will be handled by an external source (the browser).
256 real_handler_->OnResponseStarted(info->request_id, response_); 267 real_handler_->OnResponseStarted(info->request_id, response_);
257 real_handler_ = download_handler; 268 real_handler_ = download_handler;
258 } 269 }
259 return real_handler_->OnResponseStarted(request_id, response_); 270 return real_handler_->OnResponseStarted(request_id, response_);
260 } 271 }
261 272
262 bool BufferedResourceHandler::DidBufferEnough(int bytes_read) { 273 bool BufferedResourceHandler::DidBufferEnough(int bytes_read) {
263 const int kRequiredLength = 256; 274 const int kRequiredLength = 256;
264 275
265 return bytes_read >= kRequiredLength; 276 return bytes_read >= kRequiredLength;
266 } 277 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/buffered_resource_handler.h ('k') | chrome/browser/renderer_host/cross_site_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698