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

Side by Side Diff: trunk/src/content/browser/loader/buffered_resource_handler.cc

Issue 26472004: Revert 227318 "Clean up ResourceHandler API." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 2 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/loader/buffered_resource_handler.h" 5 #include "content/browser/loader/buffered_resource_handler.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 scoped_refptr<net::IOBuffer> buf_; 74 scoped_refptr<net::IOBuffer> buf_;
75 }; 75 };
76 76
77 } // namespace 77 } // namespace
78 78
79 BufferedResourceHandler::BufferedResourceHandler( 79 BufferedResourceHandler::BufferedResourceHandler(
80 scoped_ptr<ResourceHandler> next_handler, 80 scoped_ptr<ResourceHandler> next_handler,
81 ResourceDispatcherHostImpl* host, 81 ResourceDispatcherHostImpl* host,
82 net::URLRequest* request) 82 net::URLRequest* request)
83 : LayeredResourceHandler(request, next_handler.Pass()), 83 : LayeredResourceHandler(next_handler.Pass()),
84 state_(STATE_STARTING), 84 state_(STATE_STARTING),
85 host_(host), 85 host_(host),
86 request_(request),
86 read_buffer_size_(0), 87 read_buffer_size_(0),
87 bytes_read_(0), 88 bytes_read_(0),
88 must_download_(false), 89 must_download_(false),
89 must_download_is_set_(false), 90 must_download_is_set_(false),
90 weak_ptr_factory_(this) { 91 weak_ptr_factory_(this) {
91 } 92 }
92 93
93 BufferedResourceHandler::~BufferedResourceHandler() { 94 BufferedResourceHandler::~BufferedResourceHandler() {
94 } 95 }
95 96
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 response_->head.mime_type.assign("text/plain"); 140 response_->head.mime_type.assign("text/plain");
140 } 141 }
141 } 142 }
142 143
143 state_ = STATE_PROCESSING; 144 state_ = STATE_PROCESSING;
144 return ProcessResponse(defer); 145 return ProcessResponse(defer);
145 } 146 }
146 147
147 // We'll let the original event handler provide a buffer, and reuse it for 148 // We'll let the original event handler provide a buffer, and reuse it for
148 // subsequent reads until we're done buffering. 149 // subsequent reads until we're done buffering.
149 bool BufferedResourceHandler::OnWillRead(int request_id, 150 bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
150 scoped_refptr<net::IOBuffer>* buf, 151 int* buf_size, int min_size) {
151 int* buf_size,
152 int min_size) {
153 if (state_ == STATE_STREAMING) 152 if (state_ == STATE_STREAMING)
154 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); 153 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size);
155 154
156 DCHECK_EQ(-1, min_size); 155 DCHECK_EQ(-1, min_size);
157 156
158 if (read_buffer_.get()) { 157 if (read_buffer_.get()) {
159 CHECK_LT(bytes_read_, read_buffer_size_); 158 CHECK_LT(bytes_read_, read_buffer_size_);
160 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_); 159 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_);
161 *buf_size = read_buffer_size_ - bytes_read_; 160 *buf_size = read_buffer_size_ - bytes_read_;
162 } else { 161 } else {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 if (!(response_->head.headers.get() && 233 if (!(response_->head.headers.get() &&
235 response_->head.headers->response_code() == 304)) { 234 response_->head.headers->response_code() == 304)) {
236 if (!SelectNextHandler(defer)) 235 if (!SelectNextHandler(defer))
237 return false; 236 return false;
238 if (*defer) 237 if (*defer)
239 return true; 238 return true;
240 } 239 }
241 240
242 state_ = STATE_REPLAYING; 241 state_ = STATE_REPLAYING;
243 242
244 if (!next_handler_->OnResponseStarted(GetRequestID(), response_.get(), defer)) 243 int request_id = ResourceRequestInfo::ForRequest(request_)->GetRequestID();
244 if (!next_handler_->OnResponseStarted(request_id, response_.get(), defer))
245 return false; 245 return false;
246 246
247 if (!read_buffer_.get()) { 247 if (!read_buffer_.get()) {
248 state_ = STATE_STREAMING; 248 state_ = STATE_STREAMING;
249 return true; 249 return true;
250 } 250 }
251 251
252 if (!*defer) 252 if (!*defer)
253 return ReplayReadCompleted(defer); 253 return ReplayReadCompleted(defer);
254 254
255 return true; 255 return true;
256 } 256 }
257 257
258 bool BufferedResourceHandler::ShouldSniffContent() { 258 bool BufferedResourceHandler::ShouldSniffContent() {
259 const std::string& mime_type = response_->head.mime_type; 259 const std::string& mime_type = response_->head.mime_type;
260 260
261 std::string content_type_options; 261 std::string content_type_options;
262 request()->GetResponseHeaderByName("x-content-type-options", 262 request_->GetResponseHeaderByName("x-content-type-options",
263 &content_type_options); 263 &content_type_options);
264 264
265 bool sniffing_blocked = 265 bool sniffing_blocked =
266 LowerCaseEqualsASCII(content_type_options, "nosniff"); 266 LowerCaseEqualsASCII(content_type_options, "nosniff");
267 bool we_would_like_to_sniff = 267 bool we_would_like_to_sniff =
268 net::ShouldSniffMimeType(request()->url(), mime_type); 268 net::ShouldSniffMimeType(request_->url(), mime_type);
269 269
270 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type); 270 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type);
271 271
272 if (!sniffing_blocked && we_would_like_to_sniff) { 272 if (!sniffing_blocked && we_would_like_to_sniff) {
273 // We're going to look at the data before deciding what the content type 273 // We're going to look at the data before deciding what the content type
274 // is. That means we need to delay sending the ResponseStarted message 274 // is. That means we need to delay sending the ResponseStarted message
275 // over the IPC channel. 275 // over the IPC channel.
276 VLOG(1) << "To buffer: " << request()->url().spec(); 276 VLOG(1) << "To buffer: " << request_->url().spec();
277 return true; 277 return true;
278 } 278 }
279 279
280 return false; 280 return false;
281 } 281 }
282 282
283 bool BufferedResourceHandler::DetermineMimeType() { 283 bool BufferedResourceHandler::DetermineMimeType() {
284 DCHECK_EQ(STATE_BUFFERING, state_); 284 DCHECK_EQ(STATE_BUFFERING, state_);
285 285
286 const std::string& type_hint = response_->head.mime_type; 286 const std::string& type_hint = response_->head.mime_type;
287 287
288 std::string new_type; 288 std::string new_type;
289 bool made_final_decision = 289 bool made_final_decision =
290 net::SniffMimeType(read_buffer_->data(), bytes_read_, request()->url(), 290 net::SniffMimeType(read_buffer_->data(), bytes_read_, request_->url(),
291 type_hint, &new_type); 291 type_hint, &new_type);
292 292
293 // SniffMimeType() returns false if there is not enough data to determine 293 // SniffMimeType() returns false if there is not enough data to determine
294 // the mime type. However, even if it returns false, it returns a new type 294 // the mime type. However, even if it returns false, it returns a new type
295 // that is probably better than the current one. 295 // that is probably better than the current one.
296 response_->head.mime_type.assign(new_type); 296 response_->head.mime_type.assign(new_type);
297 297
298 return made_final_decision; 298 return made_final_decision;
299 } 299 }
300 300
301 bool BufferedResourceHandler::SelectNextHandler(bool* defer) { 301 bool BufferedResourceHandler::SelectNextHandler(bool* defer) {
302 DCHECK(!response_->head.mime_type.empty()); 302 DCHECK(!response_->head.mime_type.empty());
303 303
304 ResourceRequestInfoImpl* info = GetRequestInfo(); 304 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
305 const std::string& mime_type = response_->head.mime_type; 305 const std::string& mime_type = response_->head.mime_type;
306 306
307 if (net::IsSupportedCertificateMimeType(mime_type)) { 307 if (net::IsSupportedCertificateMimeType(mime_type)) {
308 // Install certificate file. 308 // Install certificate file.
309 scoped_ptr<ResourceHandler> handler( 309 scoped_ptr<ResourceHandler> handler(
310 new CertificateResourceHandler(request())); 310 new CertificateResourceHandler(request_));
311 return UseAlternateNextHandler(handler.Pass()); 311 return UseAlternateNextHandler(handler.Pass());
312 } 312 }
313 313
314 if (!info->allow_download()) 314 if (!info->allow_download())
315 return true; 315 return true;
316 316
317 bool must_download = MustDownload(); 317 bool must_download = MustDownload();
318 if (!must_download) { 318 if (!must_download) {
319 if (net::IsSupportedMimeType(mime_type)) 319 if (net::IsSupportedMimeType(mime_type))
320 return true; 320 return true;
321 321
322 scoped_ptr<ResourceHandler> handler( 322 scoped_ptr<ResourceHandler> handler(
323 host_->MaybeInterceptAsStream(request(), response_.get())); 323 host_->MaybeInterceptAsStream(request_, response_.get()));
324 if (handler) 324 if (handler)
325 return UseAlternateNextHandler(handler.Pass()); 325 return UseAlternateNextHandler(handler.Pass());
326 326
327 #if defined(ENABLE_PLUGINS) 327 #if defined(ENABLE_PLUGINS)
328 bool stale; 328 bool stale;
329 bool has_plugin = HasSupportingPlugin(&stale); 329 bool has_plugin = HasSupportingPlugin(&stale);
330 if (stale) { 330 if (stale) {
331 // Refresh the plugins asynchronously. 331 // Refresh the plugins asynchronously.
332 PluginServiceImpl::GetInstance()->GetPlugins( 332 PluginServiceImpl::GetInstance()->GetPlugins(
333 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, 333 base::Bind(&BufferedResourceHandler::OnPluginsLoaded,
334 weak_ptr_factory_.GetWeakPtr())); 334 weak_ptr_factory_.GetWeakPtr()));
335 *defer = true; 335 *defer = true;
336 return true; 336 return true;
337 } 337 }
338 if (has_plugin) 338 if (has_plugin)
339 return true; 339 return true;
340 #endif 340 #endif
341 } 341 }
342 342
343 // Install download handler 343 // Install download handler
344 info->set_is_download(true); 344 info->set_is_download(true);
345 scoped_ptr<ResourceHandler> handler( 345 scoped_ptr<ResourceHandler> handler(
346 host_->CreateResourceHandlerForDownload( 346 host_->CreateResourceHandlerForDownload(
347 request(), 347 request_,
348 true, // is_content_initiated 348 true, // is_content_initiated
349 must_download, 349 must_download,
350 content::DownloadItem::kInvalidId, 350 content::DownloadItem::kInvalidId,
351 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()), 351 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()),
352 DownloadUrlParameters::OnStartedCallback())); 352 DownloadUrlParameters::OnStartedCallback()));
353 return UseAlternateNextHandler(handler.Pass()); 353 return UseAlternateNextHandler(handler.Pass());
354 } 354 }
355 355
356 bool BufferedResourceHandler::UseAlternateNextHandler( 356 bool BufferedResourceHandler::UseAlternateNextHandler(
357 scoped_ptr<ResourceHandler> new_handler) { 357 scoped_ptr<ResourceHandler> new_handler) {
358 if (response_->head.headers.get() && // Can be NULL if FTP. 358 if (response_->head.headers.get() && // Can be NULL if FTP.
359 response_->head.headers->response_code() / 100 != 2) { 359 response_->head.headers->response_code() / 100 != 2) {
360 // The response code indicates that this is an error page, but we don't 360 // The response code indicates that this is an error page, but we don't
361 // know how to display the content. We follow Firefox here and show our 361 // know how to display the content. We follow Firefox here and show our
362 // own error page instead of triggering a download. 362 // own error page instead of triggering a download.
363 // TODO(abarth): We should abstract the response_code test, but this kind 363 // TODO(abarth): We should abstract the response_code test, but this kind
364 // of check is scattered throughout our codebase. 364 // of check is scattered throughout our codebase.
365 request()->CancelWithError(net::ERR_FILE_NOT_FOUND); 365 request_->CancelWithError(net::ERR_FILE_NOT_FOUND);
366 return false; 366 return false;
367 } 367 }
368 368
369 int request_id = GetRequestID(); 369 int request_id = ResourceRequestInfo::ForRequest(request_)->GetRequestID();
370 370
371 // Inform the original ResourceHandler that this will be handled entirely by 371 // Inform the original ResourceHandler that this will be handled entirely by
372 // the new ResourceHandler. 372 // the new ResourceHandler.
373 // TODO(darin): We should probably check the return values of these. 373 // TODO(darin): We should probably check the return values of these.
374 bool defer_ignored = false; 374 bool defer_ignored = false;
375 next_handler_->OnResponseStarted(request_id, response_.get(), &defer_ignored); 375 next_handler_->OnResponseStarted(request_id, response_.get(), &defer_ignored);
376 DCHECK(!defer_ignored); 376 DCHECK(!defer_ignored);
377 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, 377 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
378 net::ERR_ABORTED); 378 net::ERR_ABORTED);
379 next_handler_->OnResponseCompleted(request_id, status, std::string()); 379 next_handler_->OnResponseCompleted(request_id, status, std::string());
380 380
381 // This is handled entirely within the new ResourceHandler, so just reset the 381 // This is handled entirely within the new ResourceHandler, so just reset the
382 // original ResourceHandler. 382 // original ResourceHandler.
383 next_handler_ = new_handler.Pass(); 383 next_handler_ = new_handler.Pass();
384 next_handler_->SetController(this); 384 next_handler_->SetController(this);
385 385
386 return CopyReadBufferToNextHandler(request_id); 386 return CopyReadBufferToNextHandler(request_id);
387 } 387 }
388 388
389 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) { 389 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) {
390 DCHECK(read_buffer_.get()); 390 DCHECK(read_buffer_.get());
391 391
392 bool result = next_handler_->OnReadCompleted(GetRequestID(), bytes_read_, 392 int request_id = ResourceRequestInfo::ForRequest(request_)->GetRequestID();
393 defer); 393 bool result = next_handler_->OnReadCompleted(request_id, bytes_read_, defer);
394 394
395 read_buffer_ = NULL; 395 read_buffer_ = NULL;
396 read_buffer_size_ = 0; 396 read_buffer_size_ = 0;
397 bytes_read_ = 0; 397 bytes_read_ = 0;
398 398
399 state_ = STATE_STREAMING; 399 state_ = STATE_STREAMING;
400 400
401 return result; 401 return result;
402 } 402 }
403 403
404 void BufferedResourceHandler::CallReplayReadCompleted() { 404 void BufferedResourceHandler::CallReplayReadCompleted() {
405 bool defer = false; 405 bool defer = false;
406 if (!ReplayReadCompleted(&defer)) { 406 if (!ReplayReadCompleted(&defer)) {
407 controller()->Cancel(); 407 controller()->Cancel();
408 } else if (!defer) { 408 } else if (!defer) {
409 state_ = STATE_STREAMING; 409 state_ = STATE_STREAMING;
410 controller()->Resume(); 410 controller()->Resume();
411 } 411 }
412 } 412 }
413 413
414 bool BufferedResourceHandler::MustDownload() { 414 bool BufferedResourceHandler::MustDownload() {
415 if (must_download_is_set_) 415 if (must_download_is_set_)
416 return must_download_; 416 return must_download_;
417 417
418 must_download_is_set_ = true; 418 must_download_is_set_ = true;
419 419
420 std::string disposition; 420 std::string disposition;
421 request()->GetResponseHeaderByName("content-disposition", &disposition); 421 request_->GetResponseHeaderByName("content-disposition", &disposition);
422 if (!disposition.empty() && 422 if (!disposition.empty() &&
423 net::HttpContentDisposition(disposition, std::string()).is_attachment()) { 423 net::HttpContentDisposition(disposition, std::string()).is_attachment()) {
424 must_download_ = true; 424 must_download_ = true;
425 } else if (host_->delegate() && 425 } else if (host_->delegate() &&
426 host_->delegate()->ShouldForceDownloadResource( 426 host_->delegate()->ShouldForceDownloadResource(
427 request()->url(), response_->head.mime_type)) { 427 request_->url(), response_->head.mime_type)) {
428 must_download_ = true; 428 must_download_ = true;
429 } else { 429 } else {
430 must_download_ = false; 430 must_download_ = false;
431 } 431 }
432 432
433 return must_download_; 433 return must_download_;
434 } 434 }
435 435
436 bool BufferedResourceHandler::HasSupportingPlugin(bool* stale) { 436 bool BufferedResourceHandler::HasSupportingPlugin(bool* stale) {
437 ResourceRequestInfoImpl* info = GetRequestInfo(); 437 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
438 438
439 bool allow_wildcard = false; 439 bool allow_wildcard = false;
440 WebPluginInfo plugin; 440 WebPluginInfo plugin;
441 return PluginServiceImpl::GetInstance()->GetPluginInfo( 441 return PluginServiceImpl::GetInstance()->GetPluginInfo(
442 info->GetChildID(), info->GetRouteID(), info->GetContext(), 442 info->GetChildID(), info->GetRouteID(), info->GetContext(),
443 request()->url(), GURL(), response_->head.mime_type, allow_wildcard, 443 request_->url(), GURL(), response_->head.mime_type, allow_wildcard,
444 stale, &plugin, NULL); 444 stale, &plugin, NULL);
445 } 445 }
446 446
447 bool BufferedResourceHandler::CopyReadBufferToNextHandler(int request_id) { 447 bool BufferedResourceHandler::CopyReadBufferToNextHandler(int request_id) {
448 if (!bytes_read_) 448 if (!bytes_read_)
449 return true; 449 return true;
450 450
451 scoped_refptr<net::IOBuffer> buf; 451 net::IOBuffer* buf = NULL;
452 int buf_len = 0; 452 int buf_len = 0;
453 if (!next_handler_->OnWillRead(request_id, &buf, &buf_len, bytes_read_)) 453 if (!next_handler_->OnWillRead(request_id, &buf, &buf_len, bytes_read_))
454 return false; 454 return false;
455 455
456 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); 456 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0));
457 memcpy(buf->data(), read_buffer_->data(), bytes_read_); 457 memcpy(buf->data(), read_buffer_->data(), bytes_read_);
458 return true; 458 return true;
459 } 459 }
460 460
461 void BufferedResourceHandler::OnPluginsLoaded( 461 void BufferedResourceHandler::OnPluginsLoaded(
462 const std::vector<WebPluginInfo>& plugins) { 462 const std::vector<WebPluginInfo>& plugins) {
463 bool defer = false; 463 bool defer = false;
464 if (!ProcessResponse(&defer)) { 464 if (!ProcessResponse(&defer)) {
465 controller()->Cancel(); 465 controller()->Cancel();
466 } else if (!defer) { 466 } else if (!defer) {
467 controller()->Resume(); 467 controller()->Resume();
468 } 468 }
469 } 469 }
470 470
471 } // namespace content 471 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698