diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-24 02:00:21 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-24 02:00:21 +0000 |
commit | 4dd01903cb5c1bb60bfb3682e80389f220ef1c90 (patch) | |
tree | 9ec4a95fbd5d9220aa214ba76c5082b84fcc4252 /net/url_request | |
parent | 8727059c45d9c4b31431cf6b650997658b1f02ce (diff) | |
download | chromium_src-4dd01903cb5c1bb60bfb3682e80389f220ef1c90.zip chromium_src-4dd01903cb5c1bb60bfb3682e80389f220ef1c90.tar.gz chromium_src-4dd01903cb5c1bb60bfb3682e80389f220ef1c90.tar.bz2 |
Make sure filter buffer is flushed after it fills its output quota
In some cases, when the filter returned but the output buffer was full,
the ReadFilteredData code was not "bothering" to call the filter again
(because there was no more input data to provide). We now maintain
state indicating that the output buffer was filled (last time) and use
that to ensure we call the filter(s) again when Read is next called.
bug=7985
r=huanr
Review URL: http://codereview.chromium.org/27073
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10244 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request')
-rw-r--r-- | net/url_request/url_request_job.cc | 28 | ||||
-rw-r--r-- | net/url_request/url_request_job.h | 5 |
2 files changed, 28 insertions, 5 deletions
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 659156b..a82f879 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc @@ -23,6 +23,7 @@ static const int kFilterBufSize = 32 * 1024; URLRequestJob::URLRequestJob(URLRequest* request) : request_(request), done_(false), + filter_needs_more_output_space_(false), read_buffer_(NULL), read_buffer_len_(0), has_handled_response_(false), @@ -167,14 +168,13 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { if (is_done()) return true; - if (!filter_->stream_data_len()) { + if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) { // We don't have any raw data to work with, so // read from the socket. - int filtered_data_read; if (ReadRawDataForFilter(&filtered_data_read)) { if (filtered_data_read > 0) { - filter_->FlushStreamBuffer(filtered_data_read); + filter_->FlushStreamBuffer(filtered_data_read); // Give data to filter. } else { return true; // EOF } @@ -183,18 +183,32 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { } } - if (filter_->stream_data_len() && !is_done()) { - // Get filtered data + if ((filter_->stream_data_len() || filter_needs_more_output_space_) + && !is_done()) { + // Get filtered data. int filtered_data_len = read_buffer_len_; Filter::FilterStatus status; + int output_buffer_size = filtered_data_len; status = filter_->ReadData(read_buffer_->data(), &filtered_data_len); + + if (filter_needs_more_output_space_ && 0 == filtered_data_len) { + // filter_needs_more_output_space_ was mistaken... there are no more bytes + // and we should have at least tried to fill up the filter's input buffer. + // Correct the state, and try again. + filter_needs_more_output_space_ = false; + return ReadFilteredData(bytes_read); + } + switch (status) { case Filter::FILTER_DONE: { + filter_needs_more_output_space_ = false; *bytes_read = filtered_data_len; rv = true; break; } case Filter::FILTER_NEED_MORE_DATA: { + filter_needs_more_output_space_ = + (filtered_data_len == output_buffer_size); // We have finished filtering all data currently in the buffer. // There might be some space left in the output buffer. One can // consider reading more data from the stream to feed the filter @@ -212,11 +226,14 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { break; } case Filter::FILTER_OK: { + filter_needs_more_output_space_ = + (filtered_data_len == output_buffer_size); *bytes_read = filtered_data_len; rv = true; break; } case Filter::FILTER_ERROR: { + filter_needs_more_output_space_ = false; // TODO: Figure out a better error code. NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, net::ERR_FAILED)); rv = false; @@ -224,6 +241,7 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { } default: { NOTREACHED(); + filter_needs_more_output_space_ = false; rv = false; break; } diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index d9729fe..38ab199 100644 --- a/net/url_request/url_request_job.h +++ b/net/url_request/url_request_job.h @@ -285,6 +285,11 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob> { // The data stream filter which is enabled on demand. scoped_ptr<Filter> filter_; + + // If the filter filled its output buffer, then there is a change that it + // still has internal data to emit, and this flag is set. + bool filter_needs_more_output_space_; + // When we filter data, we receive data into the filter buffers. After // processing the filtered data, we return the data in the caller's buffer. // While the async IO is in progress, we save the user buffer here, and |