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

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

Issue 27073: Make sure filter buffer is flushed after it fills its output quota... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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 | Annotate | Revision Log
« no previous file with comments | « net/url_request/url_request_job.h ('k') | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "googleurl/src/gurl.h" 9 #include "googleurl/src/gurl.h"
10 #include "net/base/auth.h" 10 #include "net/base/auth.h"
11 #include "net/base/io_buffer.h" 11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
13 #include "net/url_request/url_request.h" 13 #include "net/url_request/url_request.h"
14 #include "net/url_request/url_request_job_metrics.h" 14 #include "net/url_request/url_request_job_metrics.h"
15 #include "net/url_request/url_request_job_tracker.h" 15 #include "net/url_request/url_request_job_tracker.h"
16 16
17 using base::Time; 17 using base::Time;
18 using base::TimeTicks; 18 using base::TimeTicks;
19 19
20 // Buffer size allocated when de-compressing data. 20 // Buffer size allocated when de-compressing data.
21 static const int kFilterBufSize = 32 * 1024; 21 static const int kFilterBufSize = 32 * 1024;
22 22
23 URLRequestJob::URLRequestJob(URLRequest* request) 23 URLRequestJob::URLRequestJob(URLRequest* request)
24 : request_(request), 24 : request_(request),
25 done_(false), 25 done_(false),
26 filter_needs_more_output_space_(false),
26 read_buffer_(NULL), 27 read_buffer_(NULL),
27 read_buffer_len_(0), 28 read_buffer_len_(0),
28 has_handled_response_(false), 29 has_handled_response_(false),
29 expected_content_size_(-1) { 30 expected_content_size_(-1) {
30 is_profiling_ = request->enable_profiling(); 31 is_profiling_ = request->enable_profiling();
31 if (is_profiling()) { 32 if (is_profiling()) {
32 metrics_.reset(new URLRequestJobMetrics()); 33 metrics_.reset(new URLRequestJobMetrics());
33 metrics_->start_time_ = TimeTicks::Now(); 34 metrics_->start_time_ = TimeTicks::Now();
34 } 35 }
35 g_url_request_job_tracker.AddNewJob(this); 36 g_url_request_job_tracker.AddNewJob(this);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 DCHECK(read_buffer_ != NULL); // we need to have a buffer to fill 161 DCHECK(read_buffer_ != NULL); // we need to have a buffer to fill
161 DCHECK(read_buffer_len_ > 0); // sanity check 162 DCHECK(read_buffer_len_ > 0); // sanity check
162 DCHECK(read_buffer_len_ < 1000000); // sanity check 163 DCHECK(read_buffer_len_ < 1000000); // sanity check
163 164
164 bool rv = false; 165 bool rv = false;
165 *bytes_read = 0; 166 *bytes_read = 0;
166 167
167 if (is_done()) 168 if (is_done())
168 return true; 169 return true;
169 170
170 if (!filter_->stream_data_len()) { 171 if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
171 // We don't have any raw data to work with, so 172 // We don't have any raw data to work with, so
172 // read from the socket. 173 // read from the socket.
173
174 int filtered_data_read; 174 int filtered_data_read;
175 if (ReadRawDataForFilter(&filtered_data_read)) { 175 if (ReadRawDataForFilter(&filtered_data_read)) {
176 if (filtered_data_read > 0) { 176 if (filtered_data_read > 0) {
177 filter_->FlushStreamBuffer(filtered_data_read); 177 filter_->FlushStreamBuffer(filtered_data_read); // Give data to filter.
178 } else { 178 } else {
179 return true; // EOF 179 return true; // EOF
180 } 180 }
181 } else { 181 } else {
182 return false; // IO Pending (or error) 182 return false; // IO Pending (or error)
183 } 183 }
184 } 184 }
185 185
186 if (filter_->stream_data_len() && !is_done()) { 186 if ((filter_->stream_data_len() || filter_needs_more_output_space_)
187 // Get filtered data 187 && !is_done()) {
188 // Get filtered data.
188 int filtered_data_len = read_buffer_len_; 189 int filtered_data_len = read_buffer_len_;
189 Filter::FilterStatus status; 190 Filter::FilterStatus status;
191 int output_buffer_size = filtered_data_len;
190 status = filter_->ReadData(read_buffer_->data(), &filtered_data_len); 192 status = filter_->ReadData(read_buffer_->data(), &filtered_data_len);
193
194 if (filter_needs_more_output_space_ && 0 == filtered_data_len) {
195 // filter_needs_more_output_space_ was mistaken... there are no more bytes
196 // and we should have at least tried to fill up the filter's input buffer.
197 // Correct the state, and try again.
198 filter_needs_more_output_space_ = false;
199 return ReadFilteredData(bytes_read);
200 }
201
191 switch (status) { 202 switch (status) {
192 case Filter::FILTER_DONE: { 203 case Filter::FILTER_DONE: {
204 filter_needs_more_output_space_ = false;
193 *bytes_read = filtered_data_len; 205 *bytes_read = filtered_data_len;
194 rv = true; 206 rv = true;
195 break; 207 break;
196 } 208 }
197 case Filter::FILTER_NEED_MORE_DATA: { 209 case Filter::FILTER_NEED_MORE_DATA: {
210 filter_needs_more_output_space_ =
211 (filtered_data_len == output_buffer_size);
198 // We have finished filtering all data currently in the buffer. 212 // We have finished filtering all data currently in the buffer.
199 // There might be some space left in the output buffer. One can 213 // There might be some space left in the output buffer. One can
200 // consider reading more data from the stream to feed the filter 214 // consider reading more data from the stream to feed the filter
201 // and filling up the output buffer. This leads to more complicated 215 // and filling up the output buffer. This leads to more complicated
202 // buffer management and data notification mechanisms. 216 // buffer management and data notification mechanisms.
203 // We can revisit this issue if there is a real perf need. 217 // We can revisit this issue if there is a real perf need.
204 if (filtered_data_len > 0) { 218 if (filtered_data_len > 0) {
205 *bytes_read = filtered_data_len; 219 *bytes_read = filtered_data_len;
206 rv = true; 220 rv = true;
207 } else { 221 } else {
208 // Read again since we haven't received enough data yet (e.g., we may 222 // Read again since we haven't received enough data yet (e.g., we may
209 // not have a complete gzip header yet) 223 // not have a complete gzip header yet)
210 rv = ReadFilteredData(bytes_read); 224 rv = ReadFilteredData(bytes_read);
211 } 225 }
212 break; 226 break;
213 } 227 }
214 case Filter::FILTER_OK: { 228 case Filter::FILTER_OK: {
229 filter_needs_more_output_space_ =
230 (filtered_data_len == output_buffer_size);
215 *bytes_read = filtered_data_len; 231 *bytes_read = filtered_data_len;
216 rv = true; 232 rv = true;
217 break; 233 break;
218 } 234 }
219 case Filter::FILTER_ERROR: { 235 case Filter::FILTER_ERROR: {
236 filter_needs_more_output_space_ = false;
220 // TODO: Figure out a better error code. 237 // TODO: Figure out a better error code.
221 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, net::ERR_FAILED)); 238 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, net::ERR_FAILED));
222 rv = false; 239 rv = false;
223 break; 240 break;
224 } 241 }
225 default: { 242 default: {
226 NOTREACHED(); 243 NOTREACHED();
244 filter_needs_more_output_space_ = false;
227 rv = false; 245 rv = false;
228 break; 246 break;
229 } 247 }
230 } 248 }
231 } else { 249 } else {
232 // we are done, or there is no data left. 250 // we are done, or there is no data left.
233 rv = true; 251 rv = true;
234 } 252 }
235 253
236 if (rv) { 254 if (rv) {
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 return request_->status(); 504 return request_->status();
487 // If the request is gone, we must be cancelled. 505 // If the request is gone, we must be cancelled.
488 return URLRequestStatus(URLRequestStatus::CANCELED, 506 return URLRequestStatus(URLRequestStatus::CANCELED,
489 net::ERR_ABORTED); 507 net::ERR_ABORTED);
490 } 508 }
491 509
492 void URLRequestJob::SetStatus(const URLRequestStatus &status) { 510 void URLRequestJob::SetStatus(const URLRequestStatus &status) {
493 if (request_) 511 if (request_)
494 request_->set_status(status); 512 request_->set_status(status);
495 } 513 }
OLDNEW
« no previous file with comments | « net/url_request/url_request_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698