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

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

Issue 19004: 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();
100 sniff_content_ = should_buffer_ = false; 105 sniff_content_ = should_buffer_ = false;
101 *bytes_read = bytes_read_; 106 *bytes_read = bytes_read_;
102 107
103 // Done buffering, send the pending ResponseStarted event. 108 // Done buffering, send the pending ResponseStarted event.
104 if (!CompleteResponseStarted(request_id, true)) 109 if (!CompleteResponseStarted(request_id, true))
105 return false; 110 return false;
106 } 111 }
107 112
113 // Release the reference that we acquired at OnWillRead.
114 read_buffer_ = NULL;
108 return real_handler_->OnReadCompleted(request_id, bytes_read); 115 return real_handler_->OnReadCompleted(request_id, bytes_read);
109 } 116 }
110 117
111 bool BufferedResourceHandler::DelayResponse() { 118 bool BufferedResourceHandler::DelayResponse() {
112 std::string mime_type; 119 std::string mime_type;
113 request_->GetMimeType(&mime_type); 120 request_->GetMimeType(&mime_type);
114 121
115 std::string content_type_options; 122 std::string content_type_options;
116 request_->GetResponseHeaderByName("x-content-type-options", 123 request_->GetResponseHeaderByName("x-content-type-options",
117 &content_type_options); 124 &content_type_options);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 return false; 168 return false;
162 169
163 // Today, the only reason to buffer the request is to fix the doctype decoding 170 // 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. 171 // 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. 172 // We only expect the doctype check to apply to html documents.
166 return mime_type == "text/html"; 173 return mime_type == "text/html";
167 } 174 }
168 175
169 bool BufferedResourceHandler::KeepBuffering(int bytes_read) { 176 bool BufferedResourceHandler::KeepBuffering(int bytes_read) {
170 DCHECK(read_buffer_); 177 DCHECK(read_buffer_);
178 if (my_buffer_) {
179 // We are using our own buffer to read, update the main buffer.
180 CHECK(bytes_read + bytes_read_ < read_buffer_size_);
181 memcpy(read_buffer_->data() + bytes_read_, my_buffer_->data(), bytes_read);
182 my_buffer_ = NULL;
183 }
171 bytes_read_ += bytes_read; 184 bytes_read_ += bytes_read;
172 finished_ = (bytes_read == 0); 185 finished_ = (bytes_read == 0);
173 186
174 if (sniff_content_) { 187 if (sniff_content_) {
175 std::string type_hint, new_type; 188 std::string type_hint, new_type;
176 request_->GetMimeType(&type_hint); 189 request_->GetMimeType(&type_hint);
177 190
178 if (!net::SniffMimeType(read_buffer_, bytes_read_, request_->url(), 191 if (!net::SniffMimeType(read_buffer_->data(), bytes_read_,
179 type_hint, &new_type)) { 192 request_->url(), type_hint, &new_type)) {
180 // SniffMimeType() returns false if there is not enough data to determine 193 // 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 194 // the mime type. However, even if it returns false, it returns a new type
182 // that is probably better than the current one. 195 // that is probably better than the current one.
183 DCHECK(bytes_read_ < 512 /*kMaxBytesToSniff*/); 196 DCHECK(bytes_read_ < kMaxBytesToSniff);
184 if (!finished_) { 197 if (!finished_) {
185 buffering_ = true; 198 buffering_ = true;
186 return true; 199 return true;
187 } 200 }
188 } 201 }
189 sniff_content_ = false; 202 sniff_content_ = false;
190 response_->response_head.mime_type.assign(new_type); 203 response_->response_head.mime_type.assign(new_type);
191 204
192 // We just sniffed the mime type, maybe there is a doctype to process. 205 // We just sniffed the mime type, maybe there is a doctype to process.
193 if (ShouldBuffer(request_->url(), new_type)) 206 if (ShouldBuffer(request_->url(), new_type))
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 new DownloadThrottlingResourceHandler(host_, 249 new DownloadThrottlingResourceHandler(host_,
237 request_, 250 request_,
238 request_->url().spec(), 251 request_->url().spec(),
239 info->render_process_host_id, 252 info->render_process_host_id,
240 info->render_view_id, 253 info->render_view_id,
241 request_id, 254 request_id,
242 in_complete); 255 in_complete);
243 if (bytes_read_) { 256 if (bytes_read_) {
244 // a Read has already occurred and we need to copy the data into the 257 // a Read has already occurred and we need to copy the data into the
245 // EventHandler. 258 // EventHandler.
246 char *buf = NULL; 259 net::IOBuffer* buf = NULL;
247 int buf_len = 0; 260 int buf_len = 0;
248 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); 261 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_);
249 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); 262 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0));
250 memcpy(buf, read_buffer_, bytes_read_); 263 memcpy(buf->data(), read_buffer_->data(), bytes_read_);
251 } 264 }
252 // Update the renderer with the response headers which will cause it to 265 // Update the renderer with the response headers which will cause it to
253 // cancel the request. 266 // cancel the request.
254 // TODO(paulg): Send the renderer a response that indicates that the request 267 // TODO(paulg): Send the renderer a response that indicates that the request
255 // will be handled by an external source (the browser). 268 // will be handled by an external source (the browser).
256 real_handler_->OnResponseStarted(info->request_id, response_); 269 real_handler_->OnResponseStarted(info->request_id, response_);
257 real_handler_ = download_handler; 270 real_handler_ = download_handler;
258 } 271 }
259 return real_handler_->OnResponseStarted(request_id, response_); 272 return real_handler_->OnResponseStarted(request_id, response_);
260 } 273 }
261 274
262 bool BufferedResourceHandler::DidBufferEnough(int bytes_read) { 275 bool BufferedResourceHandler::DidBufferEnough(int bytes_read) {
263 const int kRequiredLength = 256; 276 const int kRequiredLength = 256;
264 277
265 return bytes_read >= kRequiredLength; 278 return bytes_read >= kRequiredLength;
266 } 279 }
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