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 "content/browser/download/download_resource_handler.h" | 5 #include "content/browser/download/download_resource_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 165 |
166 // Get the last modified time and etag. | 166 // Get the last modified time and etag. |
167 const net::HttpResponseHeaders* headers = request_->response_headers(); | 167 const net::HttpResponseHeaders* headers = request_->response_headers(); |
168 if (headers) { | 168 if (headers) { |
169 std::string last_modified_hdr; | 169 std::string last_modified_hdr; |
170 std::string etag; | 170 std::string etag; |
171 if (headers->EnumerateHeader(NULL, "Last-Modified", &last_modified_hdr)) | 171 if (headers->EnumerateHeader(NULL, "Last-Modified", &last_modified_hdr)) |
172 info->last_modified = last_modified_hdr; | 172 info->last_modified = last_modified_hdr; |
173 if (headers->EnumerateHeader(NULL, "ETag", &etag)) | 173 if (headers->EnumerateHeader(NULL, "ETag", &etag)) |
174 info->etag = etag; | 174 info->etag = etag; |
| 175 |
| 176 int status = headers->response_code(); |
| 177 if (status == 200) { // Continue with download: |
| 178 // Downloading the full file, even if we asked for a range. |
| 179 // If there is a temporary file and |received_bytes == 0|, delete it. |
| 180 save_info_->offset = 0; |
| 181 save_info_->hash_state = ""; |
| 182 } |
175 } | 183 } |
176 | 184 |
177 std::string content_type_header; | 185 std::string content_type_header; |
178 if (!response->head.headers || | 186 if (!response->head.headers || |
179 !response->head.headers->GetMimeType(&content_type_header)) | 187 !response->head.headers->GetMimeType(&content_type_header)) |
180 content_type_header = ""; | 188 content_type_header = ""; |
181 info->original_mime_type = content_type_header; | 189 info->original_mime_type = content_type_header; |
182 | 190 |
183 if (!response->head.headers || | 191 if (!response->head.headers || |
184 !response->head.headers->EnumerateHeader( | 192 !response->head.headers->EnumerateHeader( |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 // stack cancelled the request. There aren't that many things that | 323 // stack cancelled the request. There aren't that many things that |
316 // could do this to a download request (whose lifetime is separated from | 324 // could do this to a download request (whose lifetime is separated from |
317 // the tab from which it came). We map this to USER_CANCELLED as the | 325 // the tab from which it came). We map this to USER_CANCELLED as the |
318 // case we know about (system suspend because of laptop close) corresponds | 326 // case we know about (system suspend because of laptop close) corresponds |
319 // to a user action. | 327 // to a user action. |
320 // TODO(ahendrickson) -- Find a better set of codes to use here, as | 328 // TODO(ahendrickson) -- Find a better set of codes to use here, as |
321 // CANCELED/ERR_ABORTED can occur for reasons other than user cancel. | 329 // CANCELED/ERR_ABORTED can occur for reasons other than user cancel. |
322 reason = DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; | 330 reason = DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; |
323 } | 331 } |
324 | 332 |
325 if (status.is_success()) { | 333 if (status.is_success() && |
326 if (response_code >= 400) { | 334 (reason == DOWNLOAD_INTERRUPT_REASON_NONE) && |
| 335 request_->response_headers()) { |
| 336 // Handle server's response codes. |
| 337 if ((response_code >= 0) && ((response_code % 100) != 2)) { |
327 switch(response_code) { | 338 switch(response_code) { |
328 case 404: // File Not Found. | 339 // Continue with download: |
| 340 case 200: // Downloading the full file, even if we asked for a |
| 341 // range. |
| 342 case 206: // Partial content. Leave alone. |
| 343 break; |
| 344 case 204: // No content. File not present. |
| 345 case 404: // File Not Found. |
329 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; | 346 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; |
330 break; | 347 break; |
331 case 416: // Range Not Satisfiable. | 348 case 412: // Precondition failed. Fails 'If-Unmodified-Since' or |
332 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE; | 349 // 'If-Match'. |
333 break; | |
334 case 412: // Precondition Failed. | |
335 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION; | 350 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION; |
336 break; | 351 break; |
337 default: | 352 case 416: // Range Not Satisfiable. |
| 353 // Retry by downloading from the start automatically: |
| 354 // If we haven't received data when we get this error, we won't. |
| 355 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE; |
| 356 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION; |
| 357 break; |
| 358 default: // All other errors. |
338 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; | 359 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; |
339 break; | 360 break; |
340 } | 361 } |
341 } | 362 } |
342 } | 363 } |
343 | 364 |
344 RecordAcceptsRanges(accept_ranges_, bytes_read_); | 365 RecordAcceptsRanges(accept_ranges_, bytes_read_); |
345 RecordNetworkBlockage( | 366 RecordNetworkBlockage( |
346 base::TimeTicks::Now() - download_start_time_, total_pause_time_); | 367 base::TimeTicks::Now() - download_start_time_, total_pause_time_); |
347 | 368 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 457 |
437 // Remove output stream callback if a stream exists. | 458 // Remove output stream callback if a stream exists. |
438 if (stream_writer_.get()) | 459 if (stream_writer_.get()) |
439 stream_writer_->RegisterCallback(base::Closure()); | 460 stream_writer_->RegisterCallback(base::Closure()); |
440 | 461 |
441 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", | 462 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
442 base::TimeTicks::Now() - download_start_time_); | 463 base::TimeTicks::Now() - download_start_time_); |
443 } | 464 } |
444 | 465 |
445 } // namespace content | 466 } // namespace content |
OLD | NEW |