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

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

Issue 1662763002: [ON HOLD] Implement pull-based design for content decoding (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 if ((http_status_code == 303 && method != "HEAD") || 56 if ((http_status_code == 303 && method != "HEAD") ||
57 ((http_status_code == 301 || http_status_code == 302) && 57 ((http_status_code == 301 || http_status_code == 302) &&
58 method == "POST")) { 58 method == "POST")) {
59 return "GET"; 59 return "GET";
60 } 60 }
61 return method; 61 return method;
62 } 62 }
63 63
64 } // namespace 64 } // namespace
65 65
66 // StreamSources own the previous StreamSource in the chain, but the ultimate
67 // source is URLRequestJob, which has other ownership semantics, so this class
68 // is a proxy for URLRequestJob that is owned by the first filter (in dataflow
69 // order).
70 // last filter in the chain.
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 nit: Extra comment line.
xunjieli 2016/03/03 23:00:09 Done. Removed. Used that last comment to remind my
71 class URLRequestJobStreamSource
72 : public StreamSource,
73 public base::SupportsWeakPtr<URLRequestJobStreamSource> {
mmenke 2016/02/18 22:58:28 I don't think you ever vend any weak pointers, so
xunjieli 2016/03/03 23:00:09 Done.
74 public:
75 URLRequestJobStreamSource(const base::WeakPtr<URLRequestJob>& job)
76 : total_bytes_output_(0), job_(job) {}
77
78 ~URLRequestJobStreamSource() override {}
79 // StreamSource implementation:
80 Error Read(IOBuffer* dest_buffer,
81 size_t buffer_size,
82 size_t* bytes_read,
83 const StreamSource::OnReadCompleteCallback& callback) override;
84 size_t GetBytesOutput() const override;
85
86 private:
87 friend class base::RefCounted<URLRequestJobStreamSource>;
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 I'm confused--the pattern I'm used to is that if a
xunjieli 2016/03/03 23:00:09 Done.
88
89 void OnRawReadComplete(const StreamSource::OnReadCompleteCallback& callback,
90 Error error,
91 size_t bytes_read);
92
93 size_t total_bytes_output_;
94 const base::WeakPtr<URLRequestJob> job_;
95 };
96
97 // The documentation for URLRequestJob::ReadRawData() is helpful for
98 // understanding this, since that method has a complex contract.
99 Error URLRequestJobStreamSource::Read(
100 IOBuffer* dest_buffer,
101 size_t buffer_size,
102 size_t* bytes_read,
103 const StreamSource::OnReadCompleteCallback& callback) {
104 URLRequestJob* job = job_.get();
105 DCHECK(job);
106
107 // This is a bit of a hack. This should just be callback, but URLRequestJob
108 // needs to maintain counts of prefilter and postfilter bytes for use by
109 // subclasses, and this class (URLRequestJobStreamSource) is the only one that
110 // knows how many prefilter bytes were returned by a synchronous read, so the
111 // prefilter byte count is stored in this class.
112 OnReadCompleteCallback wrapped_callback = base::Bind(
113 &URLRequestJobStreamSource::OnRawReadComplete,
114 // This object is solely owned by the next filter in the chain. The filter
115 // chain cannot be destroyed while there is a pending read, which means
116 // this object also cannot be destroyed while there is a pending read.
117 base::Unretained(this), callback);
118 // If ReadRawData() returns true, the underlying data source has synchronously
119 // succeeded, which might be an EOF.
120 int bytes_read_raw;
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 nit: I'd init this to zero.
xunjieli 2016/03/03 23:00:09 Done.
121 Error error = job->ReadRawDataHelper(dest_buffer, buffer_size,
122 &bytes_read_raw, wrapped_callback);
123 // LOG(ERROR) << "job->ReadRawDataHelper error:" << error <<
124 // "*******************";
125 if (error == OK) {
126 *bytes_read = base::checked_cast<size_t>(bytes_read_raw);
127 total_bytes_output_ += base::checked_cast<size_t>(bytes_read_raw);
128 return OK;
129 }
130
131 return error;
132 }
133
134 void URLRequestJobStreamSource::OnRawReadComplete(
135 const StreamSource::OnReadCompleteCallback& callback,
136 Error error,
137 size_t bytes_read) {
138 if (error == OK)
139 total_bytes_output_ += bytes_read;
140 callback.Run(error, bytes_read);
141 }
142
143 size_t URLRequestJobStreamSource::GetBytesOutput() const {
144 return total_bytes_output_;
145 }
146
66 URLRequestJob::URLRequestJob(URLRequest* request, 147 URLRequestJob::URLRequestJob(URLRequest* request,
67 NetworkDelegate* network_delegate) 148 NetworkDelegate* network_delegate)
68 : request_(request), 149 : request_(request),
69 done_(false), 150 done_(false),
70 prefilter_bytes_read_(0),
71 postfilter_bytes_read_(0),
72 filter_needs_more_output_space_(false), 151 filter_needs_more_output_space_(false),
73 filtered_read_buffer_len_(0), 152 filtered_read_buffer_len_(0),
74 has_handled_response_(false), 153 has_handled_response_(false),
75 expected_content_size_(-1), 154 expected_content_size_(-1),
76 network_delegate_(network_delegate), 155 network_delegate_(network_delegate),
77 last_notified_total_received_bytes_(0), 156 last_notified_total_received_bytes_(0),
78 last_notified_total_sent_bytes_(0), 157 last_notified_total_sent_bytes_(0),
158 raw_bytes_read_(0),
79 weak_factory_(this) { 159 weak_factory_(this) {
80 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); 160 base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
81 if (power_monitor) 161 if (power_monitor)
82 power_monitor->AddObserver(this); 162 power_monitor->AddObserver(this);
83 } 163 }
84 164
85 URLRequestJob::~URLRequestJob() { 165 URLRequestJob::~URLRequestJob() {
86 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); 166 base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
87 if (power_monitor) 167 if (power_monitor)
88 power_monitor->RemoveObserver(this); 168 power_monitor->RemoveObserver(this);
(...skipping 15 matching lines...) Expand all
104 // Kill(). 184 // Kill().
105 // TODO(mmenke): The URLRequest is currently deleted before this method 185 // TODO(mmenke): The URLRequest is currently deleted before this method
106 // invokes its async callback whenever this is called by the URLRequest. 186 // invokes its async callback whenever this is called by the URLRequest.
107 // Try to simplify how cancellation works. 187 // Try to simplify how cancellation works.
108 NotifyCanceled(); 188 NotifyCanceled();
109 } 189 }
110 190
111 // This function calls ReadRawData to get stream data. If a filter exists, it 191 // This function calls ReadRawData to get stream data. If a filter exists, it
112 // passes the data to the attached filter. It then returns the output from 192 // passes the data to the attached filter. It then returns the output from
113 // filter back to the caller. 193 // filter back to the caller.
194 // This method passes reads down the filter chain, where they eventually end up
195 // at URLRequestJobStreamSource::Read, which calls back into
196 // URLRequestJob::ReadRawData.
114 bool URLRequestJob::Read(IOBuffer* buf, int buf_size, int *bytes_read) { 197 bool URLRequestJob::Read(IOBuffer* buf, int buf_size, int *bytes_read) {
115 DCHECK_LT(buf_size, 1000000); // Sanity check. 198 DCHECK_LT(buf_size, 1000000); // Sanity check.
116 DCHECK(buf); 199 DCHECK(buf);
117 DCHECK(bytes_read); 200 DCHECK(bytes_read);
118 DCHECK(filtered_read_buffer_.get() == NULL); 201 DCHECK(filtered_read_buffer_.get() == NULL);
119 DCHECK_EQ(0, filtered_read_buffer_len_); 202 DCHECK_EQ(0, filtered_read_buffer_len_);
120 203
121 Error error = OK; 204 Error error = OK;
122 *bytes_read = 0; 205 *bytes_read = 0;
123 206
124 // Skip Filter if not present. 207 size_t bytes_read_n = 0;
125 if (!filter_) { 208 error = source_->Read(buf, buf_size, &bytes_read_n,
126 error = ReadRawDataHelper(buf, buf_size, bytes_read); 209 base::Bind(&URLRequestJob::SourceReadComplete,
127 } else { 210 weak_factory_.GetWeakPtr()));
128 // Save the caller's buffers while we do IO 211 *bytes_read = bytes_read_n;
129 // in the filter's buffers.
130 filtered_read_buffer_ = buf;
131 filtered_read_buffer_len_ = buf_size;
132
133 error = ReadFilteredData(bytes_read);
134
135 // Synchronous EOF from the filter.
136 if (error == OK && *bytes_read == 0)
137 DoneReading();
138 }
139 212
140 if (error == OK) { 213 if (error == OK) {
141 // If URLRequestJob read zero bytes, the job is at EOF. 214 // If URLRequestJob read zero bytes, the job is at EOF.
142 if (*bytes_read == 0) 215 if (*bytes_read == 0) {
216 DoneReading();
143 NotifyDone(URLRequestStatus()); 217 NotifyDone(URLRequestStatus());
218 }
144 } else if (error == ERR_IO_PENDING) { 219 } else if (error == ERR_IO_PENDING) {
145 SetStatus(URLRequestStatus::FromError(ERR_IO_PENDING)); 220 SetStatus(URLRequestStatus::FromError(ERR_IO_PENDING));
146 } else { 221 } else {
147 NotifyDone(URLRequestStatus::FromError(error)); 222 NotifyDone(URLRequestStatus::FromError(error));
148 *bytes_read = -1; 223 *bytes_read = -1;
149 } 224 }
150 return error == OK; 225 return error == OK;
151 } 226 }
152 227
228 // Callback for asynchronous reads from |source_|. See the documentation for
229 // |Read| above for the contract of this method.
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 nit: I think the documentation for |Read| is in th
xunjieli 2016/03/03 23:00:09 Done.
230 void URLRequestJob::SourceReadComplete(Error error, size_t bytes_read) {
231 DCHECK_NE(ERR_IO_PENDING, error);
232 DCHECK(error == OK || bytes_read == 0);
233
234 // Synchronize the URLRequest state machine with the URLRequestJob state
235 // machine. If this read succeeded, either the request is at EOF and the
236 // URLRequest state machine goes to 'finished', or it is not and the
237 // URLRequest state machine goes to 'success'. If the read failed, the
238 // URLRequest state machine goes directly to 'finished'. If filtered data is
239 // pending, then there's nothing to do, since the status of the request is
240 // already pending.
241 //
242 // Update the URLRequest's status first, so that NotifyReadCompleted has an
243 // accurate view of the request.
244 if (error == OK && bytes_read > 0) {
245 SetStatus(URLRequestStatus());
246 } else {
247 NotifyDone(URLRequestStatus::FromError(error));
248 }
249 if (error == OK) {
250 if (bytes_read == 0)
251 DoneReading();
252 request_->NotifyReadCompleted(bytes_read);
253 }
254 }
255
153 void URLRequestJob::StopCaching() { 256 void URLRequestJob::StopCaching() {
154 // Nothing to do here. 257 // Nothing to do here.
155 } 258 }
156 259
157 bool URLRequestJob::GetFullRequestHeaders(HttpRequestHeaders* headers) const { 260 bool URLRequestJob::GetFullRequestHeaders(HttpRequestHeaders* headers) const {
158 // Most job types don't send request headers. 261 // Most job types don't send request headers.
159 return false; 262 return false;
160 } 263 }
161 264
162 int64_t URLRequestJob::GetTotalReceivedBytes() const { 265 int64_t URLRequestJob::GetTotalReceivedBytes() const {
(...skipping 28 matching lines...) Expand all
191 } 294 }
192 295
193 bool URLRequestJob::GetResponseCookies(std::vector<std::string>* cookies) { 296 bool URLRequestJob::GetResponseCookies(std::vector<std::string>* cookies) {
194 return false; 297 return false;
195 } 298 }
196 299
197 void URLRequestJob::PopulateNetErrorDetails(NetErrorDetails* details) const { 300 void URLRequestJob::PopulateNetErrorDetails(NetErrorDetails* details) const {
198 return; 301 return;
199 } 302 }
200 303
304 #if 0
201 Filter* URLRequestJob::SetupFilter() const { 305 Filter* URLRequestJob::SetupFilter() const {
202 return NULL; 306 return NULL;
203 } 307 }
308 #endif
309
310 scoped_ptr<StreamSource> URLRequestJob::SetupSource() {
311 scoped_ptr<URLRequestJobStreamSource> source(
312 new URLRequestJobStreamSource(weak_factory_.GetWeakPtr()));
313 return std::move(source);
314 }
204 315
205 bool URLRequestJob::IsRedirectResponse(GURL* location, 316 bool URLRequestJob::IsRedirectResponse(GURL* location,
206 int* http_status_code) { 317 int* http_status_code) {
207 // For non-HTTP jobs, headers will be null. 318 // For non-HTTP jobs, headers will be null.
208 HttpResponseHeaders* headers = request_->response_headers(); 319 HttpResponseHeaders* headers = request_->response_headers();
209 if (!headers) 320 if (!headers)
210 return false; 321 return false;
211 322
212 std::string value; 323 std::string value;
213 if (!headers->IsRedirect(&value)) 324 if (!headers->IsRedirect(&value))
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 // Need to check for a NULL auth_info because the server may have failed 549 // Need to check for a NULL auth_info because the server may have failed
439 // to send a challenge with the 401 response. 550 // to send a challenge with the 401 response.
440 if (auth_info.get()) { 551 if (auth_info.get()) {
441 request_->NotifyAuthRequired(auth_info.get()); 552 request_->NotifyAuthRequired(auth_info.get());
442 // Wait for SetAuth or CancelAuth to be called. 553 // Wait for SetAuth or CancelAuth to be called.
443 return; 554 return;
444 } 555 }
445 } 556 }
446 557
447 has_handled_response_ = true; 558 has_handled_response_ = true;
448 if (request_->status().is_success()) 559 if (request_->status().is_success()) {
449 filter_.reset(SetupFilter()); 560 // filter_.reset(SetupFilter());
561 source_ = SetupSource();
562 }
450 563
451 if (!filter_.get()) { 564 if (!filter_.get()) {
452 std::string content_length; 565 std::string content_length;
453 request_->GetResponseHeaderByName("content-length", &content_length); 566 request_->GetResponseHeaderByName("content-length", &content_length);
454 if (!content_length.empty()) 567 if (!content_length.empty())
455 base::StringToInt64(content_length, &expected_content_size_); 568 base::StringToInt64(content_length, &expected_content_size_);
456 } else { 569 } else {
457 request_->net_log().AddEvent( 570 request_->net_log().AddEvent(
458 NetLog::TYPE_URL_REQUEST_FILTERS_SET, 571 NetLog::TYPE_URL_REQUEST_FILTERS_SET,
459 base::Bind(&FiltersSetCallback, base::Unretained(filter_.get()))); 572 base::Bind(&FiltersSetCallback, base::Unretained(filter_.get())));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 DCHECK(has_handled_response_); 604 DCHECK(has_handled_response_);
492 605
493 Error error; 606 Error error;
494 int bytes_read; 607 int bytes_read;
495 ConvertResultToError(result, &error, &bytes_read); 608 ConvertResultToError(result, &error, &bytes_read);
496 609
497 DCHECK_NE(ERR_IO_PENDING, error); 610 DCHECK_NE(ERR_IO_PENDING, error);
498 611
499 GatherRawReadStats(error, bytes_read); 612 GatherRawReadStats(error, bytes_read);
500 613
501 if (filter_.get() && error == OK) { 614 // Notify StreamSource.
502 // |bytes_read| being 0 indicates an EOF was received. ReadFilteredData 615 if (error == OK) {
503 // can incorrectly return ERR_IO_PENDING when 0 bytes are passed to it, so 616 DCHECK(!read_raw_callback_.is_null());
504 // just don't call into the filter in that case. 617 StreamSource::OnReadCompleteCallback cb = read_raw_callback_;
505 int filter_bytes_read = 0; 618 read_raw_callback_.Reset();
506 if (bytes_read > 0) { 619 cb.Run(OK, bytes_read);
507 // Tell the filter that it has more data.
508 PushInputToFilter(bytes_read);
509
510 // Filter the data.
511 error = ReadFilteredData(&filter_bytes_read);
512 }
513
514 if (error == OK && !filter_bytes_read)
515 DoneReading();
516
517 DVLOG(1) << __FUNCTION__ << "() "
518 << "\"" << request_->url().spec() << "\""
519 << " pre bytes read = " << bytes_read
520 << " pre total = " << prefilter_bytes_read_
521 << " post total = " << postfilter_bytes_read_;
522 bytes_read = filter_bytes_read;
523 } else {
524 DVLOG(1) << __FUNCTION__ << "() "
525 << "\"" << request_->url().spec() << "\""
526 << " pre bytes read = " << bytes_read
527 << " pre total = " << prefilter_bytes_read_
528 << " post total = " << postfilter_bytes_read_;
529 } 620 }
530 621
531 // Synchronize the URLRequest state machine with the URLRequestJob state
532 // machine. If this read succeeded, either the request is at EOF and the
533 // URLRequest state machine goes to 'finished', or it is not and the
534 // URLRequest state machine goes to 'success'. If the read failed, the
535 // URLRequest state machine goes directly to 'finished'. If filtered data is
536 // pending, then there's nothing to do, since the status of the request is
537 // already pending.
538 //
539 // Update the URLRequest's status first, so that NotifyReadCompleted has an
540 // accurate view of the request.
541 if (error == OK && bytes_read > 0) {
542 SetStatus(URLRequestStatus());
543 } else if (error != ERR_IO_PENDING) {
544 NotifyDone(URLRequestStatus::FromError(error));
545 }
546
547 // NotifyReadCompleted should be called after SetStatus or NotifyDone updates
548 // the status.
549 if (error == OK)
550 request_->NotifyReadCompleted(bytes_read);
551
552 // |this| may be destroyed at this point. 622 // |this| may be destroyed at this point.
553 } 623 }
554 624
625 #if 0
626 void URLRequestJob::OnRawReadComplete(int bytes_read) {
627 if (bytes_read > 0) {
628 }
629 DCHECK(!read_raw_callback_.is_null());
630 StreamSource::OnReadCompleteCallback cb = read_raw_callback_;
631 read_raw_callback_.Reset();
632 cb.Run(OK, bytes_read);
633 }
634 #endif
635
555 void URLRequestJob::NotifyStartError(const URLRequestStatus &status) { 636 void URLRequestJob::NotifyStartError(const URLRequestStatus &status) {
556 DCHECK(!has_handled_response_); 637 DCHECK(!has_handled_response_);
557 DCHECK(request_->status().is_io_pending()); 638 DCHECK(request_->status().is_io_pending());
558 639
559 has_handled_response_ = true; 640 has_handled_response_ = true;
560 // There may be relevant information in the response info even in the 641 // There may be relevant information in the response info even in the
561 // error case. 642 // error case.
562 GetResponseInfo(&request_->response_info_); 643 GetResponseInfo(&request_->response_info_);
563 644
564 SetStatus(status); 645 SetStatus(status);
(...skipping 26 matching lines...) Expand all
591 request_->set_status(status); 672 request_->set_status(status);
592 } 673 }
593 674
594 // If the request succeeded (And wasn't cancelled) and the response code was 675 // If the request succeeded (And wasn't cancelled) and the response code was
595 // 4xx or 5xx, record whether or not the main frame was blank. This is 676 // 4xx or 5xx, record whether or not the main frame was blank. This is
596 // intended to be a short-lived histogram, used to figure out how important 677 // intended to be a short-lived histogram, used to figure out how important
597 // fixing http://crbug.com/331745 is. 678 // fixing http://crbug.com/331745 is.
598 if (request_->status().is_success()) { 679 if (request_->status().is_success()) {
599 int response_code = GetResponseCode(); 680 int response_code = GetResponseCode();
600 if (400 <= response_code && response_code <= 599) { 681 if (400 <= response_code && response_code <= 599) {
601 bool page_has_content = (postfilter_bytes_read_ != 0); 682 bool page_has_content = (postfilter_bytes_read() != 0);
602 if (request_->load_flags() & net::LOAD_MAIN_FRAME) { 683 if (request_->load_flags() & net::LOAD_MAIN_FRAME) {
603 UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentMainFrame", 684 UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentMainFrame",
604 page_has_content); 685 page_has_content);
605 } else { 686 } else {
606 UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentNonMainFrame", 687 UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentNonMainFrame",
607 page_has_content); 688 page_has_content);
608 } 689 }
609 } 690 }
610 } 691 }
611 692
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 743 }
663 744
664 void URLRequestJob::DoneReadingRedirectResponse() { 745 void URLRequestJob::DoneReadingRedirectResponse() {
665 } 746 }
666 747
667 void URLRequestJob::PushInputToFilter(int bytes_read) { 748 void URLRequestJob::PushInputToFilter(int bytes_read) {
668 DCHECK(filter_); 749 DCHECK(filter_);
669 filter_->FlushStreamBuffer(bytes_read); 750 filter_->FlushStreamBuffer(bytes_read);
670 } 751 }
671 752
672 Error URLRequestJob::ReadFilteredData(int* bytes_read) {
673 DCHECK(filter_);
674 DCHECK(filtered_read_buffer_.get());
675 DCHECK_GT(filtered_read_buffer_len_, 0);
676 DCHECK_LT(filtered_read_buffer_len_, 1000000); // Sanity check.
677 DCHECK(!raw_read_buffer_);
678
679 *bytes_read = 0;
680 Error error = ERR_FAILED;
681
682 for (;;) {
683 if (is_done())
684 return OK;
685
686 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
687 // We don't have any raw data to work with, so read from the transaction.
688 int filtered_data_read;
689 error = ReadRawDataForFilter(&filtered_data_read);
690 // If ReadRawDataForFilter returned some data, fall through to the case
691 // below; otherwise, return early.
692 if (error != OK || filtered_data_read == 0)
693 return error;
694 filter_->FlushStreamBuffer(filtered_data_read);
695 }
696
697 if ((filter_->stream_data_len() || filter_needs_more_output_space_) &&
698 !is_done()) {
699 // Get filtered data.
700 int filtered_data_len = filtered_read_buffer_len_;
701 int output_buffer_size = filtered_data_len;
702 Filter::FilterStatus status =
703 filter_->ReadData(filtered_read_buffer_->data(), &filtered_data_len);
704
705 if (filter_needs_more_output_space_ && !filtered_data_len) {
706 // filter_needs_more_output_space_ was mistaken... there are no more
707 // bytes and we should have at least tried to fill up the filter's input
708 // buffer. Correct the state, and try again.
709 filter_needs_more_output_space_ = false;
710 continue;
711 }
712 filter_needs_more_output_space_ =
713 (filtered_data_len == output_buffer_size);
714
715 switch (status) {
716 case Filter::FILTER_DONE: {
717 filter_needs_more_output_space_ = false;
718 *bytes_read = filtered_data_len;
719 postfilter_bytes_read_ += filtered_data_len;
720 error = OK;
721 break;
722 }
723 case Filter::FILTER_NEED_MORE_DATA: {
724 // We have finished filtering all data currently in the buffer.
725 // There might be some space left in the output buffer. One can
726 // consider reading more data from the stream to feed the filter
727 // and filling up the output buffer. This leads to more complicated
728 // buffer management and data notification mechanisms.
729 // We can revisit this issue if there is a real perf need.
730 if (filtered_data_len > 0) {
731 *bytes_read = filtered_data_len;
732 postfilter_bytes_read_ += filtered_data_len;
733 error = OK;
734 } else {
735 // Read again since we haven't received enough data yet (e.g., we
736 // may not have a complete gzip header yet).
737 continue;
738 }
739 break;
740 }
741 case Filter::FILTER_OK: {
742 *bytes_read = filtered_data_len;
743 postfilter_bytes_read_ += filtered_data_len;
744 error = OK;
745 break;
746 }
747 case Filter::FILTER_ERROR: {
748 DVLOG(1) << __FUNCTION__ << "() "
749 << "\"" << request_->url().spec() << "\""
750 << " Filter Error";
751 filter_needs_more_output_space_ = false;
752 error = ERR_CONTENT_DECODING_FAILED;
753 break;
754 }
755 default: {
756 NOTREACHED();
757 filter_needs_more_output_space_ = false;
758 error = ERR_FAILED;
759 break;
760 }
761 }
762
763 // If logging all bytes is enabled, log the filtered bytes read.
764 if (error == OK && filtered_data_len > 0 &&
765 request()->net_log().IsCapturing()) {
766 request()->net_log().AddByteTransferEvent(
767 NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ, filtered_data_len,
768 filtered_read_buffer_->data());
769 }
770 } else {
771 // we are done, or there is no data left.
772 error = OK;
773 }
774 break;
775 }
776
777 if (error == OK) {
778 // When we successfully finished a read, we no longer need to save the
779 // caller's buffers. Release our reference.
780 filtered_read_buffer_ = NULL;
781 filtered_read_buffer_len_ = 0;
782 }
783 return error;
784 }
785
786 void URLRequestJob::DestroyFilters() { 753 void URLRequestJob::DestroyFilters() {
787 filter_.reset(); 754 filter_.reset();
788 } 755 }
789 756
790 const URLRequestStatus URLRequestJob::GetStatus() { 757 const URLRequestStatus URLRequestJob::GetStatus() {
791 return request_->status(); 758 return request_->status();
792 } 759 }
793 760
794 void URLRequestJob::SetStatus(const URLRequestStatus &status) { 761 void URLRequestJob::SetStatus(const URLRequestStatus &status) {
795 // An error status should never be replaced by a non-error status by a 762 // An error status should never be replaced by a non-error status by a
796 // URLRequestJob. URLRequest has some retry paths, but it resets the status 763 // URLRequestJob. URLRequest has some retry paths, but it resets the status
797 // itself, if needed. 764 // itself, if needed.
798 DCHECK(request_->status().is_io_pending() || 765 DCHECK(request_->status().is_io_pending() ||
799 request_->status().is_success() || 766 request_->status().is_success() ||
800 (!status.is_success() && !status.is_io_pending())); 767 (!status.is_success() && !status.is_io_pending()));
801 request_->set_status(status); 768 request_->set_status(status);
802 } 769 }
803 770
804 void URLRequestJob::SetProxyServer(const HostPortPair& proxy_server) { 771 void URLRequestJob::SetProxyServer(const HostPortPair& proxy_server) {
805 request_->proxy_server_ = proxy_server; 772 request_->proxy_server_ = proxy_server;
806 } 773 }
807 774
808 Error URLRequestJob::ReadRawDataForFilter(int* bytes_read) { 775 int64_t URLRequestJob::prefilter_bytes_read() const {
809 Error error = ERR_FAILED; 776 return base::checked_cast<int64_t>(raw_bytes_read_);
810 DCHECK(bytes_read);
811 DCHECK(filter_.get());
812
813 *bytes_read = 0;
814
815 // Get more pre-filtered data if needed.
816 // TODO(mbelshe): is it possible that the filter needs *MORE* data
817 // when there is some data already in the buffer?
818 if (!filter_->stream_data_len() && !is_done()) {
819 IOBuffer* stream_buffer = filter_->stream_buffer();
820 int stream_buffer_size = filter_->stream_buffer_size();
821 error = ReadRawDataHelper(stream_buffer, stream_buffer_size, bytes_read);
822 }
823 return error;
824 } 777 }
825 778
826 Error URLRequestJob::ReadRawDataHelper(IOBuffer* buf, 779 int64_t URLRequestJob::postfilter_bytes_read() const {
827 int buf_size, 780 return source_ ? source_->GetBytesOutput() : 0;
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 nit: Comment line indicating when source will be n
xunjieli 2016/03/03 23:00:09 Done. Changed so that we are tracking postfilter_b
828 int* bytes_read) { 781 }
782
783 Error URLRequestJob::ReadRawDataHelper(
784 IOBuffer* buf,
785 int buf_size,
786 int* bytes_read,
787 const StreamSource::OnReadCompleteCallback& callback) {
829 DCHECK(!raw_read_buffer_); 788 DCHECK(!raw_read_buffer_);
830 789
831 // Keep a pointer to the read buffer, so we have access to it in 790 // Keep a pointer to the read buffer, so we have access to it in
832 // GatherRawReadStats() in the event that the read completes asynchronously. 791 // GatherRawReadStats() in the event that the read completes asynchronously.
833 raw_read_buffer_ = buf; 792 raw_read_buffer_ = buf;
834 Error error; 793 Error error;
835 ConvertResultToError(ReadRawData(buf, buf_size), &error, bytes_read); 794 ConvertResultToError(ReadRawData(buf, buf_size), &error, bytes_read);
836 795
837 if (error != ERR_IO_PENDING) { 796 if (error != ERR_IO_PENDING) {
838 // If the read completes synchronously, either success or failure, invoke 797 // If the read completes synchronously, either success or failure, invoke
839 // GatherRawReadStats so we can account for the completed read. 798 // GatherRawReadStats so we can account for the completed read.
840 GatherRawReadStats(error, *bytes_read); 799 GatherRawReadStats(error, *bytes_read);
800 } else {
801 // Keep a pointer to the read buffer, so we have access to it in the
802 // OnRawReadComplete() callback in the event that the read completes
Randy Smith (Not in Mondays) 2016/02/08 23:28:42 nit: I think this comment is actually referring to
xunjieli 2016/03/03 23:00:09 Done. Good catch!
803 // asynchronously.
804 // raw_read_buffer_ = buf;
805 read_raw_callback_ = callback;
841 } 806 }
842 return error; 807 return error;
843 } 808 }
844 809
845 void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) { 810 void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) {
846 int rv = request_->Redirect(redirect_info); 811 int rv = request_->Redirect(redirect_info);
847 if (rv != OK) 812 if (rv != OK)
848 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 813 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
849 } 814 }
850 815
(...skipping 14 matching lines...) Expand all
865 } 830 }
866 831
867 if (bytes_read > 0) { 832 if (bytes_read > 0) {
868 RecordBytesRead(bytes_read); 833 RecordBytesRead(bytes_read);
869 } 834 }
870 raw_read_buffer_ = nullptr; 835 raw_read_buffer_ = nullptr;
871 } 836 }
872 837
873 void URLRequestJob::RecordBytesRead(int bytes_read) { 838 void URLRequestJob::RecordBytesRead(int bytes_read) {
874 DCHECK_GT(bytes_read, 0); 839 DCHECK_GT(bytes_read, 0);
875 prefilter_bytes_read_ += bytes_read; 840 raw_bytes_read_ += base::checked_cast<size_t>(bytes_read);
876 841
877 // On first read, notify NetworkQualityEstimator that response headers have 842 // On first read, notify NetworkQualityEstimator that response headers have
878 // been received. 843 // been received.
879 // TODO(tbansal): Move this to url_request_http_job.cc. This may catch 844 // TODO(tbansal): Move this to url_request_http_job.cc. This may catch
880 // Service Worker jobs twice. 845 // Service Worker jobs twice.
881 // If prefilter_bytes_read_ is equal to bytes_read, it indicates this is the 846 // If prefilter_bytes_read_ is equal to bytes_read, it indicates this is the
882 // first raw read of the response body. This is used as the signal that 847 // first raw read of the response body. This is used as the signal that
883 // response headers have been received. 848 // response headers have been received.
884 if (request_->context()->network_quality_estimator() && 849 if (request_->context()->network_quality_estimator() &&
885 prefilter_bytes_read_ == bytes_read) { 850 prefilter_bytes_read() == bytes_read) {
886 request_->context()->network_quality_estimator()->NotifyHeadersReceived( 851 request_->context()->network_quality_estimator()->NotifyHeadersReceived(
887 *request_); 852 *request_);
888 } 853 }
889 854
890 if (!filter_.get())
891 postfilter_bytes_read_ += bytes_read;
892 DVLOG(2) << __FUNCTION__ << "() " 855 DVLOG(2) << __FUNCTION__ << "() "
893 << "\"" << request_->url().spec() << "\"" 856 << "\"" << request_->url().spec() << "\""
894 << " pre bytes read = " << bytes_read 857 << " pre bytes read = " << bytes_read
895 << " pre total = " << prefilter_bytes_read_ 858 << " pre total = " << prefilter_bytes_read()
896 << " post total = " << postfilter_bytes_read_; 859 << " post total = " << postfilter_bytes_read();
897 UpdatePacketReadTimes(); // Facilitate stats recording if it is active. 860 UpdatePacketReadTimes(); // Facilitate stats recording if it is active.
898 861
899 // Notify observers if any additional network usage has occurred. Note that 862 // Notify observers if any additional network usage has occurred. Note that
900 // the number of received bytes over the network sent by this notification 863 // the number of received bytes over the network sent by this notification
901 // could be vastly different from |bytes_read|, such as when a large chunk of 864 // could be vastly different from |bytes_read|, such as when a large chunk of
902 // network bytes is received before multiple smaller raw reads are performed 865 // network bytes is received before multiple smaller raw reads are performed
903 // on it. 866 // on it.
904 MaybeNotifyNetworkBytes(); 867 MaybeNotifyNetworkBytes();
905 } 868 }
906 869
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 int64_t total_sent_bytes = GetTotalSentBytes(); 935 int64_t total_sent_bytes = GetTotalSentBytes();
973 DCHECK_GE(total_sent_bytes, last_notified_total_sent_bytes_); 936 DCHECK_GE(total_sent_bytes, last_notified_total_sent_bytes_);
974 if (total_sent_bytes > last_notified_total_sent_bytes_) { 937 if (total_sent_bytes > last_notified_total_sent_bytes_) {
975 network_delegate_->NotifyNetworkBytesSent( 938 network_delegate_->NotifyNetworkBytesSent(
976 request_, total_sent_bytes - last_notified_total_sent_bytes_); 939 request_, total_sent_bytes - last_notified_total_sent_bytes_);
977 } 940 }
978 last_notified_total_sent_bytes_ = total_sent_bytes; 941 last_notified_total_sent_bytes_ = total_sent_bytes;
979 } 942 }
980 943
981 } // namespace net 944 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698