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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 174 |
175 // Get the last modified time and etag. | 175 // Get the last modified time and etag. |
176 const net::HttpResponseHeaders* headers = request_->response_headers(); | 176 const net::HttpResponseHeaders* headers = request_->response_headers(); |
177 if (headers) { | 177 if (headers) { |
178 std::string last_modified_hdr; | 178 std::string last_modified_hdr; |
179 std::string etag; | 179 std::string etag; |
180 if (headers->EnumerateHeader(NULL, "Last-Modified", &last_modified_hdr)) | 180 if (headers->EnumerateHeader(NULL, "Last-Modified", &last_modified_hdr)) |
181 info->last_modified = last_modified_hdr; | 181 info->last_modified = last_modified_hdr; |
182 if (headers->EnumerateHeader(NULL, "ETag", &etag)) | 182 if (headers->EnumerateHeader(NULL, "ETag", &etag)) |
183 info->etag = etag; | 183 info->etag = etag; |
| 184 |
| 185 int status = headers->response_code(); |
| 186 if (status == 200) { // Continue with download: |
| 187 // Downloading the full file, even if we asked for a range. |
| 188 // If there is a temporary file and |received_bytes == 0|, delete it. |
| 189 info->received_bytes = 0; |
| 190 info->save_info.hash_state = ""; |
| 191 } |
184 } | 192 } |
185 | 193 |
186 std::string content_type_header; | 194 std::string content_type_header; |
187 if (!response->head.headers || | 195 if (!response->head.headers || |
188 !response->head.headers->GetMimeType(&content_type_header)) | 196 !response->head.headers->GetMimeType(&content_type_header)) |
189 content_type_header = ""; | 197 content_type_header = ""; |
190 info->original_mime_type = content_type_header; | 198 info->original_mime_type = content_type_header; |
191 | 199 |
192 if (!response->head.headers || | 200 if (!response->head.headers || |
193 !response->head.headers->EnumerateHeader( | 201 !response->head.headers->EnumerateHeader( |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 // stack cancelled the request. There aren't that many things that | 335 // stack cancelled the request. There aren't that many things that |
328 // could do this to a download request (whose lifetime is separated from | 336 // could do this to a download request (whose lifetime is separated from |
329 // the tab from which it came). We map this to USER_CANCELLED as the | 337 // the tab from which it came). We map this to USER_CANCELLED as the |
330 // case we know about (system suspend because of laptop close) corresponds | 338 // case we know about (system suspend because of laptop close) corresponds |
331 // to a user action. | 339 // to a user action. |
332 // TODO(ahendrickson) -- Find a better set of codes to use here, as | 340 // TODO(ahendrickson) -- Find a better set of codes to use here, as |
333 // CANCELED/ERR_ABORTED can occur for reasons other than user cancel. | 341 // CANCELED/ERR_ABORTED can occur for reasons other than user cancel. |
334 reason = content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; | 342 reason = content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; |
335 } | 343 } |
336 | 344 |
337 if (status.is_success()) { | 345 if (status.is_success() && |
338 if (response_code >= 400) { | 346 (reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) && |
339 switch(response_code) { | 347 request_->response_headers()) { |
340 case 404: // File Not Found. | 348 // Handle server's response codes. |
341 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; | 349 if ((response_code >= 0) && ((response_code % 100) != 2)) { |
| 350 switch(response_code) { |
| 351 // Continue with download: |
| 352 case 200: // Downloading the full file, even if we asked for a |
| 353 // range. |
| 354 case 206: // Partial content. Leave alone. |
342 break; | 355 break; |
| 356 case 204: // No content. File not present. |
| 357 case 404: // File Not Found. |
| 358 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; |
| 359 break; |
| 360 case 412: // Precondition failed. Fails 'If-Unmodified-Since' or |
| 361 // 'If-Match'. |
| 362 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION; |
| 363 break; |
343 case 416: // Range Not Satisfiable. | 364 case 416: // Range Not Satisfiable. |
| 365 // Retry by downloading from the start automatically: |
| 366 // If we haven't received data when we get this error, we won't. |
344 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE; | 367 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE; |
345 break; | 368 break; |
346 case 412: // Precondition Failed. | 369 default: // All other errors. |
347 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION; | |
348 break; | |
349 default: | |
350 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; | 370 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; |
351 break; | 371 break; |
352 } | 372 } |
353 } | 373 } |
354 } | 374 } |
355 | 375 |
356 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); | 376 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); |
357 download_stats::RecordNetworkBlockage( | 377 download_stats::RecordNetworkBlockage( |
358 base::TimeTicks::Now() - download_start_time_, total_pause_time_); | 378 base::TimeTicks::Now() - download_start_time_, total_pause_time_); |
359 | 379 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 // false somewhere in the chain of resource handlers. | 468 // false somewhere in the chain of resource handlers. |
449 CallStartedCB(NULL, net::ERR_ACCESS_DENIED); | 469 CallStartedCB(NULL, net::ERR_ACCESS_DENIED); |
450 | 470 |
451 // Remove output stream callback if a stream exists. | 471 // Remove output stream callback if a stream exists. |
452 if (stream_writer_.get()) | 472 if (stream_writer_.get()) |
453 stream_writer_->RegisterCallback(base::Closure()); | 473 stream_writer_->RegisterCallback(base::Closure()); |
454 | 474 |
455 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", | 475 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
456 base::TimeTicks::Now() - download_start_time_); | 476 base::TimeTicks::Now() - download_start_time_); |
457 } | 477 } |
OLD | NEW |