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