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: 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: Address comments 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
« no previous file with comments | « net/http/http_transaction_unittest.cc ('k') | net/url_request/url_request_job_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
559 557
560 if (is_done()) 558 for (;;) {
561 return true; 559 if (is_done())
560 return true;
562 561
563 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) { 562 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
564 // We don't have any raw data to work with, so 563 // We don't have any raw data to work with, so read from the transaction.
565 // read from the socket. 564 int filtered_data_read;
566 int filtered_data_read; 565 if (ReadRawDataForFilter(&filtered_data_read)) {
567 if (ReadRawDataForFilter(&filtered_data_read)) { 566 if (filtered_data_read > 0) {
568 if (filtered_data_read > 0) { 567 // Give data to filter.
569 filter_->FlushStreamBuffer(filtered_data_read); // Give data to filter. 568 filter_->FlushStreamBuffer(filtered_data_read);
569 } else {
570 return true; // EOF.
571 }
570 } else { 572 } else {
571 return true; // EOF 573 return false; // IO Pending (or error).
572 } 574 }
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 } 575 }
594 576
595 switch (status) { 577 if ((filter_->stream_data_len() || filter_needs_more_output_space_) &&
596 case Filter::FILTER_DONE: { 578 !is_done()) {
579 // Get filtered data.
580 int filtered_data_len = filtered_read_buffer_len_;
581 int output_buffer_size = filtered_data_len;
582 Filter::FilterStatus status =
583 filter_->ReadData(filtered_read_buffer_->data(), &filtered_data_len);
584
585 if (filter_needs_more_output_space_ && !filtered_data_len) {
586 // filter_needs_more_output_space_ was mistaken... there are no more
587 // bytes and we should have at least tried to fill up the filter's input
588 // buffer. Correct the state, and try again.
597 filter_needs_more_output_space_ = false; 589 filter_needs_more_output_space_ = false;
598 *bytes_read = filtered_data_len; 590 continue;
599 postfilter_bytes_read_ += filtered_data_len;
600 rv = true;
601 break;
602 } 591 }
603 case Filter::FILTER_NEED_MORE_DATA: { 592 filter_needs_more_output_space_ =
604 filter_needs_more_output_space_ = 593 (filtered_data_len == output_buffer_size);
605 (filtered_data_len == output_buffer_size); 594
606 // We have finished filtering all data currently in the buffer. 595 switch (status) {
607 // There might be some space left in the output buffer. One can 596 case Filter::FILTER_DONE: {
608 // consider reading more data from the stream to feed the filter 597 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; 598 *bytes_read = filtered_data_len;
614 postfilter_bytes_read_ += filtered_data_len; 599 postfilter_bytes_read_ += filtered_data_len;
615 rv = true; 600 rv = true;
616 } else { 601 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 } 602 }
621 break; 603 case Filter::FILTER_NEED_MORE_DATA: {
604 // We have finished filtering all data currently in the buffer.
605 // There might be some space left in the output buffer. One can
606 // consider reading more data from the stream to feed the filter
607 // and filling up the output buffer. This leads to more complicated
608 // buffer management and data notification mechanisms.
609 // We can revisit this issue if there is a real perf need.
610 if (filtered_data_len > 0) {
611 *bytes_read = filtered_data_len;
612 postfilter_bytes_read_ += filtered_data_len;
613 rv = true;
614 } else {
615 // Read again since we haven't received enough data yet (e.g., we
616 // may not have a complete gzip header yet).
617 continue;
618 }
619 break;
620 }
621 case Filter::FILTER_OK: {
622 *bytes_read = filtered_data_len;
623 postfilter_bytes_read_ += filtered_data_len;
624 rv = true;
625 break;
626 }
627 case Filter::FILTER_ERROR: {
628 DVLOG(1) << __FUNCTION__ << "() "
629 << "\"" << (request_ ? request_->url().spec() : "???")
630 << "\"" << " Filter Error";
631 filter_needs_more_output_space_ = false;
632 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
633 ERR_CONTENT_DECODING_FAILED));
634 rv = false;
635 break;
636 }
637 default: {
638 NOTREACHED();
639 filter_needs_more_output_space_ = false;
640 rv = false;
641 break;
642 }
622 } 643 }
623 case Filter::FILTER_OK: { 644
624 filter_needs_more_output_space_ = 645 // If logging all bytes is enabled, log the filtered bytes read.
625 (filtered_data_len == output_buffer_size); 646 if (rv && request() && request()->net_log().IsLoggingBytes() &&
626 *bytes_read = filtered_data_len; 647 filtered_data_len > 0) {
627 postfilter_bytes_read_ += filtered_data_len; 648 request()->net_log().AddByteTransferEvent(
628 rv = true; 649 NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
629 break; 650 filtered_data_len, filtered_read_buffer_->data());
630 } 651 }
631 case Filter::FILTER_ERROR: { 652 } else {
632 DVLOG(1) << __FUNCTION__ << "() " 653 // we are done, or there is no data left.
633 << "\"" << (request_ ? request_->url().spec() : "???") << "\"" 654 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 } 655 }
648 DVLOG(2) << __FUNCTION__ << "() " 656 break;
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 } 657 }
666 658
667 if (rv) { 659 if (rv) {
668 // When we successfully finished a read, we no longer need to 660 // When we successfully finished a read, we no longer need to save the
669 // save the caller's buffers. Release our reference. 661 // caller's buffers. Release our reference.
670 filtered_read_buffer_ = NULL; 662 filtered_read_buffer_ = NULL;
671 filtered_read_buffer_len_ = 0; 663 filtered_read_buffer_len_ = 0;
672 } 664 }
673 return rv; 665 return rv;
674 } 666 }
675 667
676 void URLRequestJob::DestroyFilters() { 668 void URLRequestJob::DestroyFilters() {
677 filter_.reset(); 669 filter_.reset();
678 } 670 }
679 671
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 759 }
768 760
769 bool URLRequestJob::FilterHasData() { 761 bool URLRequestJob::FilterHasData() {
770 return filter_.get() && filter_->stream_data_len(); 762 return filter_.get() && filter_->stream_data_len();
771 } 763 }
772 764
773 void URLRequestJob::UpdatePacketReadTimes() { 765 void URLRequestJob::UpdatePacketReadTimes() {
774 } 766 }
775 767
776 } // namespace net 768 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_transaction_unittest.cc ('k') | net/url_request/url_request_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698