OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |