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

Side by Side Diff: net/url_request/url_request_job.cc

Issue 267793002: net: Avoid recursion in URLRequestJob::ReadFilteredData. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 "net/url_request/url_request_job.h" 5 #include "net/url_request/url_request_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/power_monitor/power_monitor.h" 10 #include "base/power_monitor/power_monitor.h"
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 534 }
535 535
536 void URLRequestJob::DoneReading() { 536 void URLRequestJob::DoneReading() {
537 // Do nothing. 537 // Do nothing.
538 } 538 }
539 539
540 void URLRequestJob::DoneReadingRedirectResponse() { 540 void URLRequestJob::DoneReadingRedirectResponse() {
541 } 541 }
542 542
543 void URLRequestJob::FilteredDataRead(int bytes_read) { 543 void URLRequestJob::FilteredDataRead(int bytes_read) {
544 DCHECK(filter_.get()); // don't add data if there is no filter 544 DCHECK(filter_);
545 filter_->FlushStreamBuffer(bytes_read); 545 filter_->FlushStreamBuffer(bytes_read);
546 } 546 }
547 547
548 bool URLRequestJob::ReadFilteredData(int* bytes_read) { 548 bool URLRequestJob::ReadFilteredData(int* bytes_read) {
549 DCHECK(filter_.get()); // don't add data if there is no filter 549 DCHECK(filter_);
550 DCHECK(filtered_read_buffer_.get() != 550 DCHECK(filtered_read_buffer_);
551 NULL); // we need to have a buffer to fill 551 DCHECK_GT(filtered_read_buffer_len_, 0);
552 DCHECK_GT(filtered_read_buffer_len_, 0); // sanity check 552 DCHECK_LT(filtered_read_buffer_len_, 1000000); // Sanity check.
553 DCHECK_LT(filtered_read_buffer_len_, 1000000); // sanity check 553 DCHECK(!raw_read_buffer_);
554 DCHECK(raw_read_buffer_.get() ==
555 NULL); // there should be no raw read buffer yet
556 554
555 *bytes_read = 0;
557 bool rv = false; 556 bool rv = false;
558 *bytes_read = 0; 557 bool read_again;
559 558
560 if (is_done()) 559 do {
561 return true; 560 read_again = false;
561 if (is_done())
562 return true;
562 563
563 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) { 564 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
564 // We don't have any raw data to work with, so 565 // We don't have any raw data to work with, so read from the transaction.
565 // read from the socket. 566 int filtered_data_read;
566 int filtered_data_read; 567 if (ReadRawDataForFilter(&filtered_data_read)) {
567 if (ReadRawDataForFilter(&filtered_data_read)) { 568 if (filtered_data_read > 0) {
568 if (filtered_data_read > 0) { 569 // Give data to filter.
569 filter_->FlushStreamBuffer(filtered_data_read); // Give data to filter. 570 filter_->FlushStreamBuffer(filtered_data_read);
571 } else {
572 return true; // EOF.
573 }
570 } else { 574 } else {
571 return true; // EOF 575 return false; // IO Pending (or error).
572 } 576 }
573 } else {
574 return false; // IO Pending (or error)
575 }
576 }
577
578 if ((filter_->stream_data_len() || filter_needs_more_output_space_)
579 && !is_done()) {
580 // Get filtered data.
581 int filtered_data_len = filtered_read_buffer_len_;
582 Filter::FilterStatus status;
583 int output_buffer_size = filtered_data_len;
584 status = filter_->ReadData(filtered_read_buffer_->data(),
585 &filtered_data_len);
586
587 if (filter_needs_more_output_space_ && 0 == filtered_data_len) {
588 // filter_needs_more_output_space_ was mistaken... there are no more bytes
589 // and we should have at least tried to fill up the filter's input buffer.
590 // Correct the state, and try again.
591 filter_needs_more_output_space_ = false;
592 return ReadFilteredData(bytes_read);
593 } 577 }
594 578
595 switch (status) { 579 if ((filter_->stream_data_len() || filter_needs_more_output_space_) &&
596 case Filter::FILTER_DONE: { 580 !is_done()) {
581 // Get filtered data.
582 int filtered_data_len = filtered_read_buffer_len_;
583 int output_buffer_size = filtered_data_len;
584 Filter::FilterStatus status =
585 filter_->ReadData(filtered_read_buffer_->data(), &filtered_data_len);
586
587 if (filter_needs_more_output_space_ && !filtered_data_len) {
588 // filter_needs_more_output_space_ was mistaken... there are no more
589 // bytes and we should have at least tried to fill up the filter's input
590 // buffer. Correct the state, and try again.
597 filter_needs_more_output_space_ = false; 591 filter_needs_more_output_space_ = false;
598 *bytes_read = filtered_data_len; 592 read_again = true;
599 postfilter_bytes_read_ += filtered_data_len; 593 continue;
600 rv = true;
601 break;
602 } 594 }
603 case Filter::FILTER_NEED_MORE_DATA: { 595 filter_needs_more_output_space_ =
604 filter_needs_more_output_space_ = 596 (filtered_data_len == output_buffer_size);
605 (filtered_data_len == output_buffer_size); 597
606 // We have finished filtering all data currently in the buffer. 598 switch (status) {
607 // There might be some space left in the output buffer. One can 599 case Filter::FILTER_DONE: {
608 // consider reading more data from the stream to feed the filter 600 filter_needs_more_output_space_ = false;
609 // and filling up the output buffer. This leads to more complicated
610 // buffer management and data notification mechanisms.
611 // We can revisit this issue if there is a real perf need.
612 if (filtered_data_len > 0) {
613 *bytes_read = filtered_data_len; 601 *bytes_read = filtered_data_len;
614 postfilter_bytes_read_ += filtered_data_len; 602 postfilter_bytes_read_ += filtered_data_len;
615 rv = true; 603 rv = true;
616 } else { 604 break;
617 // Read again since we haven't received enough data yet (e.g., we may
618 // not have a complete gzip header yet)
619 rv = ReadFilteredData(bytes_read);
620 } 605 }
621 break; 606 case Filter::FILTER_NEED_MORE_DATA: {
607 // We have finished filtering all data currently in the buffer.
608 // There might be some space left in the output buffer. One can
609 // consider reading more data from the stream to feed the filter
610 // and filling up the output buffer. This leads to more complicated
611 // buffer management and data notification mechanisms.
612 // We can revisit this issue if there is a real perf need.
613 if (filtered_data_len > 0) {
614 *bytes_read = filtered_data_len;
615 postfilter_bytes_read_ += filtered_data_len;
616 rv = true;
617 } else {
618 // Read again since we haven't received enough data yet (e.g., we
619 // may not have a complete gzip header yet).
620 read_again = true;
621 continue;
622 }
623 break;
624 }
625 case Filter::FILTER_OK: {
626 *bytes_read = filtered_data_len;
627 postfilter_bytes_read_ += filtered_data_len;
628 rv = true;
629 break;
630 }
631 case Filter::FILTER_ERROR: {
632 DVLOG(1) << __FUNCTION__ << "() "
633 << "\"" << (request_ ? request_->url().spec() : "???")
634 << "\"" << " Filter Error";
635 filter_needs_more_output_space_ = false;
636 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
637 ERR_CONTENT_DECODING_FAILED));
638 rv = false;
639 break;
640 }
641 default: {
642 NOTREACHED();
643 filter_needs_more_output_space_ = false;
644 rv = false;
645 break;
646 }
622 } 647 }
623 case Filter::FILTER_OK: { 648
624 filter_needs_more_output_space_ = 649 // If logging all bytes is enabled, log the filtered bytes read.
625 (filtered_data_len == output_buffer_size); 650 if (rv && request() && request()->net_log().IsLoggingBytes() &&
626 *bytes_read = filtered_data_len; 651 filtered_data_len > 0) {
627 postfilter_bytes_read_ += filtered_data_len; 652 request()->net_log().AddByteTransferEvent(
628 rv = true; 653 NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
629 break; 654 filtered_data_len, filtered_read_buffer_->data());
630 } 655 }
631 case Filter::FILTER_ERROR: { 656 } else {
632 DVLOG(1) << __FUNCTION__ << "() " 657 // we are done, or there is no data left.
633 << "\"" << (request_ ? request_->url().spec() : "???") << "\"" 658 rv = true;
634 << " Filter Error";
635 filter_needs_more_output_space_ = false;
636 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
637 ERR_CONTENT_DECODING_FAILED));
638 rv = false;
639 break;
640 }
641 default: {
642 NOTREACHED();
643 filter_needs_more_output_space_ = false;
644 rv = false;
645 break;
646 }
647 } 659 }
648 DVLOG(2) << __FUNCTION__ << "() " 660 } while(read_again);
wtc 2014/05/02 22:59:13 Just wanted to confirm that you realize you delete
rvargas (doing something else) 2014/05/03 00:19:33 Yes, I'm not a fan of leaving debug info forever i
wtc 2014/05/02 22:59:13 1. Nit: add a space between "while" and "(". 2. S
rvargas (doing something else) 2014/05/03 00:19:33 I thought about that before... they are pretty muc
649 << "\"" << (request_ ? request_->url().spec() : "???") << "\""
650 << " rv = " << rv
651 << " post bytes read = " << filtered_data_len
652 << " pre total = " << prefilter_bytes_read_
653 << " post total = "
654 << postfilter_bytes_read_;
655 // If logging all bytes is enabled, log the filtered bytes read.
656 if (rv && request() && request()->net_log().IsLoggingBytes() &&
657 filtered_data_len > 0) {
658 request()->net_log().AddByteTransferEvent(
659 NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
660 filtered_data_len, filtered_read_buffer_->data());
661 }
662 } else {
663 // we are done, or there is no data left.
664 rv = true;
665 }
666 661
667 if (rv) { 662 if (rv) {
668 // When we successfully finished a read, we no longer need to 663 // When we successfully finished a read, we no longer need to save the
669 // save the caller's buffers. Release our reference. 664 // caller's buffers. Release our reference.
670 filtered_read_buffer_ = NULL; 665 filtered_read_buffer_ = NULL;
671 filtered_read_buffer_len_ = 0; 666 filtered_read_buffer_len_ = 0;
672 } 667 }
673 return rv; 668 return rv;
674 } 669 }
675 670
676 void URLRequestJob::DestroyFilters() { 671 void URLRequestJob::DestroyFilters() {
677 filter_.reset(); 672 filter_.reset();
678 } 673 }
679 674
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 762 }
768 763
769 bool URLRequestJob::FilterHasData() { 764 bool URLRequestJob::FilterHasData() {
770 return filter_.get() && filter_->stream_data_len(); 765 return filter_.get() && filter_->stream_data_len();
771 } 766 }
772 767
773 void URLRequestJob::UpdatePacketReadTimes() { 768 void URLRequestJob::UpdatePacketReadTimes() {
774 } 769 }
775 770
776 } // namespace net 771 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698