blob: 1990941236decaadc459189cfbee09b26305e073 [file] [log] [blame]
[email protected]0a0b2542012-01-03 08:25:221// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e3c404b2008-12-23 01:07:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]1d8a3d1f2011-02-19 07:11:525#include "content/browser/renderer_host/buffered_resource_handler.h"
[email protected]e3c404b2008-12-23 01:07:326
[email protected]dd9b5462009-09-25 17:22:237#include <vector>
8
[email protected]d33e7cc2011-09-23 01:43:569#include "base/bind.h"
[email protected]5203e6002009-07-29 03:42:0010#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3811#include "base/metrics/histogram.h"
[email protected]319d9e6f2009-02-18 19:47:2112#include "base/string_util.h"
[email protected]2909e342011-10-29 00:46:5313#include "content/browser/download/download_id_factory.h"
[email protected]254ed742011-08-16 18:45:2714#include "content/browser/download/download_resource_handler.h"
[email protected]f6c2b5312011-11-16 22:31:3915#include "content/browser/download/download_types.h"
[email protected]e67385f2011-12-21 06:00:5616#include "content/browser/plugin_service_impl.h"
[email protected]1d8a3d1f2011-02-19 07:11:5217#include "content/browser/renderer_host/resource_dispatcher_host.h"
18#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
19#include "content/browser/renderer_host/x509_user_cert_resource_handler.h"
[email protected]eda58402011-09-21 19:32:0220#include "content/browser/resource_context.h"
[email protected]c38831a12011-10-28 12:44:4921#include "content/public/browser/browser_thread.h"
[email protected]87f3c082011-10-19 18:07:4422#include "content/public/browser/content_browser_client.h"
[email protected]1bd0ef12011-10-20 05:24:1723#include "content/public/browser/resource_dispatcher_host_delegate.h"
[email protected]2336ffe2011-11-24 01:23:3424#include "content/public/common/resource_response.h"
[email protected]dd9b5462009-09-25 17:22:2325#include "net/base/io_buffer.h"
[email protected]9dea9e1f2009-01-29 00:30:4726#include "net/base/mime_sniffer.h"
[email protected]35fa6a22009-08-15 00:04:0127#include "net/base/mime_util.h"
[email protected]dd9b5462009-09-25 17:22:2328#include "net/base/net_errors.h"
[email protected]319d9e6f2009-02-18 19:47:2129#include "net/http/http_response_headers.h"
[email protected]d33e7cc2011-09-23 01:43:5630#include "webkit/plugins/webplugininfo.h"
[email protected]e3c404b2008-12-23 01:07:3231
[email protected]d18720a2012-01-06 09:53:5532namespace content {
33
[email protected]306291392009-01-17 19:15:3634namespace {
35
36void RecordSnifferMetrics(bool sniffing_blocked,
37 bool we_would_like_to_sniff,
38 const std::string& mime_type) {
[email protected]81ce9f3b2011-04-05 04:48:5339 static base::Histogram* nosniff_usage(NULL);
40 if (!nosniff_usage)
41 nosniff_usage = base::BooleanHistogram::FactoryGet(
42 "nosniff.usage", base::Histogram::kUmaTargetedHistogramFlag);
[email protected]e8829a192009-12-06 00:09:3743 nosniff_usage->AddBoolean(sniffing_blocked);
[email protected]306291392009-01-17 19:15:3644
45 if (sniffing_blocked) {
[email protected]81ce9f3b2011-04-05 04:48:5346 static base::Histogram* nosniff_otherwise(NULL);
47 if (!nosniff_otherwise)
48 nosniff_otherwise = base::BooleanHistogram::FactoryGet(
49 "nosniff.otherwise", base::Histogram::kUmaTargetedHistogramFlag);
[email protected]e8829a192009-12-06 00:09:3750 nosniff_otherwise->AddBoolean(we_would_like_to_sniff);
[email protected]306291392009-01-17 19:15:3651
[email protected]81ce9f3b2011-04-05 04:48:5352 static base::Histogram* nosniff_empty_mime_type(NULL);
53 if (!nosniff_empty_mime_type)
54 nosniff_empty_mime_type = base::BooleanHistogram::FactoryGet(
55 "nosniff.empty_mime_type",
56 base::Histogram::kUmaTargetedHistogramFlag);
[email protected]e8829a192009-12-06 00:09:3757 nosniff_empty_mime_type->AddBoolean(mime_type.empty());
[email protected]306291392009-01-17 19:15:3658 }
59}
60
61} // namespace
62
[email protected]e3c404b2008-12-23 01:07:3263BufferedResourceHandler::BufferedResourceHandler(ResourceHandler* handler,
64 ResourceDispatcherHost* host,
[email protected]6981d9632010-11-30 21:34:0265 net::URLRequest* request)
[email protected]d18720a2012-01-06 09:53:5566 : LayeredResourceHandler(handler),
[email protected]e3c404b2008-12-23 01:07:3267 host_(host),
68 request_(request),
[email protected]dd9b5462009-09-25 17:22:2369 read_buffer_size_(0),
[email protected]e3c404b2008-12-23 01:07:3270 bytes_read_(0),
71 sniff_content_(false),
[email protected]35fa6a22009-08-15 00:04:0172 wait_for_plugins_(false),
[email protected]e3c404b2008-12-23 01:07:3273 buffering_(false),
74 finished_(false) {
75}
76
[email protected]2336ffe2011-11-24 01:23:3477bool BufferedResourceHandler::OnResponseStarted(
78 int request_id,
[email protected]d18720a2012-01-06 09:53:5579 ResourceResponse* response) {
[email protected]e3c404b2008-12-23 01:07:3280 response_ = response;
81 if (!DelayResponse())
[email protected]0a0b2542012-01-03 08:25:2282 return CompleteResponseStarted(request_id);
[email protected]e3c404b2008-12-23 01:07:3283 return true;
84}
85
[email protected]35fa6a22009-08-15 00:04:0186void BufferedResourceHandler::OnRequestClosed() {
87 request_ = NULL;
[email protected]d18720a2012-01-06 09:53:5588 next_handler_->OnRequestClosed();
[email protected]afd832c2010-03-02 04:53:3189}
90
[email protected]e3c404b2008-12-23 01:07:3291// We'll let the original event handler provide a buffer, and reuse it for
92// subsequent reads until we're done buffering.
[email protected]9dea9e1f2009-01-29 00:30:4793bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
94 int* buf_size, int min_size) {
[email protected]e3c404b2008-12-23 01:07:3295 if (buffering_) {
[email protected]9dea9e1f2009-01-29 00:30:4796 DCHECK(!my_buffer_.get());
[email protected]2e7aff62010-03-16 06:34:5697 my_buffer_ = new net::IOBuffer(net::kMaxBytesToSniff);
[email protected]9dea9e1f2009-01-29 00:30:4798 *buf = my_buffer_.get();
[email protected]2e7aff62010-03-16 06:34:5699 *buf_size = net::kMaxBytesToSniff;
[email protected]e3c404b2008-12-23 01:07:32100 return true;
101 }
102
103 if (finished_)
104 return false;
105
[email protected]d18720a2012-01-06 09:53:55106 if (!next_handler_->OnWillRead(request_id, buf, buf_size, min_size)) {
[email protected]67199052009-06-12 21:15:33107 return false;
108 }
[email protected]e3c404b2008-12-23 01:07:32109 read_buffer_ = *buf;
110 read_buffer_size_ = *buf_size;
[email protected]2e7aff62010-03-16 06:34:56111 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
[email protected]e3c404b2008-12-23 01:07:32112 bytes_read_ = 0;
[email protected]67199052009-06-12 21:15:33113 return true;
[email protected]e3c404b2008-12-23 01:07:32114}
115
116bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
[email protected]216c17f4d2011-05-17 06:00:55117 if (sniff_content_) {
[email protected]e3c404b2008-12-23 01:07:32118 if (KeepBuffering(*bytes_read))
119 return true;
120
[email protected]e3c404b2008-12-23 01:07:32121 *bytes_read = bytes_read_;
122
123 // Done buffering, send the pending ResponseStarted event.
[email protected]0a0b2542012-01-03 08:25:22124 if (!CompleteResponseStarted(request_id))
[email protected]e3c404b2008-12-23 01:07:32125 return false;
[email protected]98d6f152011-09-29 19:35:51126
127 // The next handler might have paused the request in OnResponseStarted.
128 ResourceDispatcherHostRequestInfo* info =
129 ResourceDispatcherHost::InfoForRequest(request_);
130 if (info->pause_count())
131 return true;
[email protected]35fa6a22009-08-15 00:04:01132 } else if (wait_for_plugins_) {
133 return true;
[email protected]e3c404b2008-12-23 01:07:32134 }
135
[email protected]9dea9e1f2009-01-29 00:30:47136 // Release the reference that we acquired at OnWillRead.
137 read_buffer_ = NULL;
[email protected]d18720a2012-01-06 09:53:55138 return next_handler_->OnReadCompleted(request_id, bytes_read);
[email protected]e3c404b2008-12-23 01:07:32139}
140
[email protected]38e08982010-10-22 17:28:43141BufferedResourceHandler::~BufferedResourceHandler() {}
142
[email protected]e3c404b2008-12-23 01:07:32143bool BufferedResourceHandler::DelayResponse() {
144 std::string mime_type;
145 request_->GetMimeType(&mime_type);
146
147 std::string content_type_options;
148 request_->GetResponseHeaderByName("x-content-type-options",
149 &content_type_options);
[email protected]306291392009-01-17 19:15:36150
[email protected]423bd5b842009-01-23 17:30:50151 const bool sniffing_blocked =
152 LowerCaseEqualsASCII(content_type_options, "nosniff");
[email protected]e19d7132009-10-16 23:33:57153 const bool not_modified_status =
[email protected]2336ffe2011-11-24 01:23:34154 response_->headers && response_->headers->response_code() == 304;
[email protected]e19d7132009-10-16 23:33:57155 const bool we_would_like_to_sniff = not_modified_status ?
156 false : net::ShouldSniffMimeType(request_->url(), mime_type);
[email protected]306291392009-01-17 19:15:36157
158 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type);
159
160 if (!sniffing_blocked && we_would_like_to_sniff) {
[email protected]e3c404b2008-12-23 01:07:32161 // We're going to look at the data before deciding what the content type
162 // is. That means we need to delay sending the ResponseStarted message
163 // over the IPC channel.
164 sniff_content_ = true;
[email protected]238667042010-10-23 01:40:00165 VLOG(1) << "To buffer: " << request_->url().spec();
[email protected]e3c404b2008-12-23 01:07:32166 return true;
167 }
168
[email protected]e19d7132009-10-16 23:33:57169 if (sniffing_blocked && mime_type.empty() && !not_modified_status) {
[email protected]423bd5b842009-01-23 17:30:50170 // Ugg. The server told us not to sniff the content but didn't give us a
171 // mime type. What's a browser to do? Turns out, we're supposed to treat
172 // the response as "text/plain". This is the most secure option.
173 mime_type.assign("text/plain");
[email protected]2336ffe2011-11-24 01:23:34174 response_->mime_type.assign(mime_type);
[email protected]423bd5b842009-01-23 17:30:50175 }
176
[email protected]b4599a12009-09-07 23:09:58177 if (mime_type == "application/rss+xml" ||
178 mime_type == "application/atom+xml") {
179 // Sad face. The server told us that they wanted us to treat the response
180 // as RSS or Atom. Unfortunately, we don't have a built-in feed previewer
181 // like other browsers. We can't just render the content as XML because
182 // web sites let third parties inject arbitrary script into their RSS
183 // feeds. That leaves us with little choice but to practically ignore the
184 // response. In the future, when we have an RSS feed previewer, we can
185 // remove this logic.
186 mime_type.assign("text/plain");
[email protected]2336ffe2011-11-24 01:23:34187 response_->mime_type.assign(mime_type);
[email protected]b4599a12009-09-07 23:09:58188 }
189
[email protected]e19d7132009-10-16 23:33:57190 if (!not_modified_status && ShouldWaitForPlugins()) {
[email protected]35fa6a22009-08-15 00:04:01191 wait_for_plugins_ = true;
192 return true;
193 }
194
[email protected]e3c404b2008-12-23 01:07:32195 return false;
196}
197
[email protected]35fa6a22009-08-15 00:04:01198bool BufferedResourceHandler::DidBufferEnough(int bytes_read) {
199 const int kRequiredLength = 256;
200
201 return bytes_read >= kRequiredLength;
202}
203
[email protected]e3c404b2008-12-23 01:07:32204bool BufferedResourceHandler::KeepBuffering(int bytes_read) {
205 DCHECK(read_buffer_);
[email protected]9dea9e1f2009-01-29 00:30:47206 if (my_buffer_) {
207 // We are using our own buffer to read, update the main buffer.
[email protected]c0dac3272010-07-28 08:04:45208 // TODO(darin): We should handle the case where read_buffer_size_ is small!
209 // See RedirectToFileResourceHandler::BufIsFull to see how this impairs
210 // downstream ResourceHandler implementations.
[email protected]2e7aff62010-03-16 06:34:56211 CHECK_LT(bytes_read + bytes_read_, read_buffer_size_);
[email protected]9dea9e1f2009-01-29 00:30:47212 memcpy(read_buffer_->data() + bytes_read_, my_buffer_->data(), bytes_read);
213 my_buffer_ = NULL;
214 }
[email protected]e3c404b2008-12-23 01:07:32215 bytes_read_ += bytes_read;
216 finished_ = (bytes_read == 0);
217
218 if (sniff_content_) {
219 std::string type_hint, new_type;
220 request_->GetMimeType(&type_hint);
221
[email protected]9dea9e1f2009-01-29 00:30:47222 if (!net::SniffMimeType(read_buffer_->data(), bytes_read_,
223 request_->url(), type_hint, &new_type)) {
[email protected]e3c404b2008-12-23 01:07:32224 // SniffMimeType() returns false if there is not enough data to determine
225 // the mime type. However, even if it returns false, it returns a new type
226 // that is probably better than the current one.
[email protected]2e7aff62010-03-16 06:34:56227 DCHECK_LT(bytes_read_, net::kMaxBytesToSniff);
[email protected]e3c404b2008-12-23 01:07:32228 if (!finished_) {
229 buffering_ = true;
230 return true;
231 }
232 }
233 sniff_content_ = false;
[email protected]2336ffe2011-11-24 01:23:34234 response_->mime_type.assign(new_type);
[email protected]e3c404b2008-12-23 01:07:32235
236 // We just sniffed the mime type, maybe there is a doctype to process.
[email protected]35fa6a22009-08-15 00:04:01237 if (ShouldWaitForPlugins())
238 wait_for_plugins_ = true;
[email protected]e3c404b2008-12-23 01:07:32239 }
[email protected]35fa6a22009-08-15 00:04:01240
[email protected]e3c404b2008-12-23 01:07:32241 buffering_ = false;
[email protected]35fa6a22009-08-15 00:04:01242
243 if (wait_for_plugins_)
244 return true;
245
[email protected]e3c404b2008-12-23 01:07:32246 return false;
247}
248
[email protected]0a0b2542012-01-03 08:25:22249bool BufferedResourceHandler::CompleteResponseStarted(int request_id) {
[email protected]347867b72009-09-02 00:35:58250 ResourceDispatcherHostRequestInfo* info =
251 ResourceDispatcherHost::InfoForRequest(request_);
[email protected]a755e1072009-10-23 16:58:37252 std::string mime_type;
253 request_->GetMimeType(&mime_type);
254
255 // Check if this is an X.509 certificate, if yes, let it be handled
256 // by X509UserCertResourceHandler.
257 if (mime_type == "application/x-x509-user-cert") {
[email protected]a755e1072009-10-23 16:58:37258 // This is entirely similar to how DownloadThrottlingResourceHandler
259 // works except we are doing it for an X.509 client certificates.
260
[email protected]2336ffe2011-11-24 01:23:34261 if (response_->headers && // Can be NULL if FTP.
262 response_->headers->response_code() / 100 != 2) {
[email protected]a755e1072009-10-23 16:58:37263 // The response code indicates that this is an error page, but we are
264 // expecting an X.509 user certificate. We follow Firefox here and show
265 // our own error page instead of handling the error page as a
266 // certificate.
267 // TODO(abarth): We should abstract the response_code test, but this kind
268 // of check is scattered throughout our codebase.
269 request_->SimulateError(net::ERR_FILE_NOT_FOUND);
270 return false;
271 }
272
[email protected]0dc72bbe2010-04-08 15:29:17273 X509UserCertResourceHandler* x509_cert_handler =
[email protected]4a729ae72010-08-02 21:26:11274 new X509UserCertResourceHandler(host_, request_,
275 info->child_id(), info->route_id());
[email protected]0dc72bbe2010-04-08 15:29:17276 UseAlternateResourceHandler(request_id, x509_cert_handler);
[email protected]a755e1072009-10-23 16:58:37277 }
[email protected]e3c404b2008-12-23 01:07:32278
[email protected]0dc72bbe2010-04-08 15:29:17279 // Check to see if we should forward the data from this request to the
280 // download thread.
281 // TODO(paulg): Only download if the context from the renderer allows it.
[email protected]347867b72009-09-02 00:35:58282 if (info->allow_download() && ShouldDownload(NULL)) {
[email protected]2336ffe2011-11-24 01:23:34283 if (response_->headers && // Can be NULL if FTP.
284 response_->headers->response_code() / 100 != 2) {
[email protected]e3c404b2008-12-23 01:07:32285 // The response code indicates that this is an error page, but we don't
286 // know how to display the content. We follow Firefox here and show our
287 // own error page instead of triggering a download.
288 // TODO(abarth): We should abstract the response_code test, but this kind
289 // of check is scattered throughout our codebase.
[email protected]c4891b32009-03-08 07:41:31290 request_->SimulateError(net::ERR_FILE_NOT_FOUND);
[email protected]e3c404b2008-12-23 01:07:32291 return false;
292 }
293
[email protected]347867b72009-09-02 00:35:58294 info->set_is_download(true);
[email protected]e3c404b2008-12-23 01:07:32295
[email protected]2909e342011-10-29 00:46:53296 DownloadId dl_id = info->context()->download_id_factory()->GetNextId();
[email protected]eda58402011-09-21 19:32:02297
[email protected]254ed742011-08-16 18:45:27298 scoped_refptr<ResourceHandler> handler(
299 new DownloadResourceHandler(host_,
300 info->child_id(),
301 info->route_id(),
302 info->request_id(),
303 request_->url(),
[email protected]eda58402011-09-21 19:32:02304 dl_id,
[email protected]254ed742011-08-16 18:45:27305 host_->download_file_manager(),
306 request_,
307 false,
[email protected]8e3ae68c2011-09-16 22:15:47308 DownloadResourceHandler::OnStartedCallback(),
[email protected]254ed742011-08-16 18:45:27309 DownloadSaveInfo()));
310
311 if (host_->delegate()) {
312 handler = host_->delegate()->DownloadStarting(
313 handler, *info->context(), request_, info->child_id(),
[email protected]0a0b2542012-01-03 08:25:22314 info->route_id(), info->request_id(), false);
[email protected]254ed742011-08-16 18:45:27315 }
316
317 UseAlternateResourceHandler(request_id, handler);
[email protected]e3c404b2008-12-23 01:07:32318 }
[email protected]d18720a2012-01-06 09:53:55319 return next_handler_->OnResponseStarted(request_id, response_);
[email protected]e3c404b2008-12-23 01:07:32320}
321
[email protected]35fa6a22009-08-15 00:04:01322bool BufferedResourceHandler::ShouldWaitForPlugins() {
323 bool need_plugin_list;
324 if (!ShouldDownload(&need_plugin_list) || !need_plugin_list)
325 return false;
[email protected]e3c404b2008-12-23 01:07:32326
[email protected]35fa6a22009-08-15 00:04:01327 // We don't want to keep buffering as our buffer will fill up.
[email protected]347867b72009-09-02 00:35:58328 ResourceDispatcherHostRequestInfo* info =
329 ResourceDispatcherHost::InfoForRequest(request_);
330 host_->PauseRequest(info->child_id(), info->request_id(), true);
[email protected]35fa6a22009-08-15 00:04:01331
[email protected]d33e7cc2011-09-23 01:43:56332 // Get the plugins asynchronously.
[email protected]e67385f2011-12-21 06:00:56333 PluginServiceImpl::GetInstance()->GetPlugins(
[email protected]d33e7cc2011-09-23 01:43:56334 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, this));
[email protected]35fa6a22009-08-15 00:04:01335 return true;
336}
337
338// This test mirrors the decision that WebKit makes in
339// WebFrameLoaderClient::dispatchDecidePolicyForMIMEType.
340bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) {
341 if (need_plugin_list)
342 *need_plugin_list = false;
[email protected]2336ffe2011-11-24 01:23:34343 std::string type = StringToLowerASCII(response_->mime_type);
[email protected]35fa6a22009-08-15 00:04:01344 std::string disposition;
345 request_->GetResponseHeaderByName("content-disposition", &disposition);
346 disposition = StringToLowerASCII(disposition);
347
348 // First, examine content-disposition.
349 if (!disposition.empty()) {
350 bool should_download = true;
351
352 // Some broken sites just send ...
353 // Content-Disposition: ; filename="file"
354 // ... screen those out here.
355 if (disposition[0] == ';')
356 should_download = false;
357
358 if (disposition.compare(0, 6, "inline") == 0)
359 should_download = false;
360
361 // Some broken sites just send ...
362 // Content-Disposition: filename="file"
363 // ... without a disposition token... Screen those out.
364 if (disposition.compare(0, 8, "filename") == 0)
365 should_download = false;
366
367 // Also in use is Content-Disposition: name="file"
368 if (disposition.compare(0, 4, "name") == 0)
369 should_download = false;
370
371 // We have a content-disposition of "attachment" or unknown.
372 // RFC 2183, section 2.8 says that an unknown disposition
373 // value should be treated as "attachment".
374 if (should_download)
375 return true;
376 }
377
[email protected]9f3fba52011-06-08 20:37:19378 if (host_->delegate() &&
379 host_->delegate()->ShouldForceDownloadResource(request_->url(), type))
[email protected]6657afa62009-11-04 02:15:20380 return true;
381
[email protected]35fa6a22009-08-15 00:04:01382 // MIME type checking.
383 if (net::IsSupportedMimeType(type))
384 return false;
385
[email protected]68598072011-07-29 08:21:28386 // Finally, check the plugin list.
387 bool allow_wildcard = false;
[email protected]dfba8762011-09-02 12:49:54388 ResourceDispatcherHostRequestInfo* info =
389 ResourceDispatcherHost::InfoForRequest(request_);
[email protected]68598072011-07-29 08:21:28390 bool stale = false;
[email protected]dfba8762011-09-02 12:49:54391 webkit::WebPluginInfo plugin;
[email protected]e67385f2011-12-21 06:00:56392 bool found = PluginServiceImpl::GetInstance()->GetPluginInfo(
[email protected]dfba8762011-09-02 12:49:54393 info->child_id(), info->route_id(), *info->context(),
394 request_->url(), GURL(), type, allow_wildcard,
395 &stale, &plugin, NULL);
396
[email protected]35fa6a22009-08-15 00:04:01397 if (need_plugin_list) {
[email protected]68598072011-07-29 08:21:28398 if (stale) {
[email protected]35fa6a22009-08-15 00:04:01399 *need_plugin_list = true;
400 return true;
401 }
402 } else {
[email protected]68598072011-07-29 08:21:28403 DCHECK(!stale);
[email protected]35fa6a22009-08-15 00:04:01404 }
405
[email protected]dfba8762011-09-02 12:49:54406 return !found;
[email protected]35fa6a22009-08-15 00:04:01407}
408
[email protected]0dc72bbe2010-04-08 15:29:17409void BufferedResourceHandler::UseAlternateResourceHandler(
410 int request_id,
411 ResourceHandler* handler) {
412 ResourceDispatcherHostRequestInfo* info =
413 ResourceDispatcherHost::InfoForRequest(request_);
414 if (bytes_read_) {
415 // A Read has already occured and we need to copy the data into the new
416 // ResourceHandler.
417 net::IOBuffer* buf = NULL;
418 int buf_len = 0;
419 handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_);
420 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0));
421 memcpy(buf->data(), read_buffer_->data(), bytes_read_);
422 }
423
424 // Inform the original ResourceHandler that this will be handled entirely by
425 // the new ResourceHandler.
[email protected]d18720a2012-01-06 09:53:55426 next_handler_->OnResponseStarted(info->request_id(), response_);
[email protected]f90bf0d92011-01-13 02:12:44427 net::URLRequestStatus status(net::URLRequestStatus::HANDLED_EXTERNALLY, 0);
[email protected]d18720a2012-01-06 09:53:55428 next_handler_->OnResponseCompleted(info->request_id(), status, std::string());
[email protected]0dc72bbe2010-04-08 15:29:17429
[email protected]11149bd2010-06-10 16:31:04430 // Remove the non-owning pointer to the CrossSiteResourceHandler, if any,
431 // from the extra request info because the CrossSiteResourceHandler (part of
432 // the original ResourceHandler chain) will be deleted by the next statement.
433 info->set_cross_site_handler(NULL);
434
[email protected]0dc72bbe2010-04-08 15:29:17435 // This is handled entirely within the new ResourceHandler, so just reset the
436 // original ResourceHandler.
[email protected]d18720a2012-01-06 09:53:55437 next_handler_ = handler;
[email protected]0dc72bbe2010-04-08 15:29:17438}
439
[email protected]d33e7cc2011-09-23 01:43:56440void BufferedResourceHandler::OnPluginsLoaded(
441 const std::vector<webkit::WebPluginInfo>& plugins) {
[email protected]5658a602009-11-03 23:12:52442 wait_for_plugins_ = false;
[email protected]7f2e792e2009-11-30 23:18:29443 if (!request_)
444 return;
[email protected]5658a602009-11-03 23:12:52445
[email protected]7f2e792e2009-11-30 23:18:29446 ResourceDispatcherHostRequestInfo* info =
447 ResourceDispatcherHost::InfoForRequest(request_);
448 host_->PauseRequest(info->child_id(), info->request_id(), false);
[email protected]0a0b2542012-01-03 08:25:22449 if (!CompleteResponseStarted(info->request_id()))
[email protected]7f2e792e2009-11-30 23:18:29450 host_->CancelRequest(info->child_id(), info->request_id(), false);
[email protected]e3c404b2008-12-23 01:07:32451}
[email protected]d18720a2012-01-06 09:53:55452
453} // namespace content