OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "sync/internal_api/public/attachments/attachment_downloader_impl.h" | 5 #include "sync/internal_api/public/attachments/attachment_downloader_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
12 #include "google_apis/gaia/fake_oauth2_token_service.h" | 12 #include "google_apis/gaia/fake_oauth2_token_service.h" |
13 #include "google_apis/gaia/gaia_constants.h" | 13 #include "google_apis/gaia/gaia_constants.h" |
14 #include "net/http/http_response_headers.h" | 14 #include "net/http/http_response_headers.h" |
15 #include "net/url_request/test_url_fetcher_factory.h" | 15 #include "net/url_request/test_url_fetcher_factory.h" |
16 #include "net/url_request/url_request_test_util.h" | 16 #include "net/url_request/url_request_test_util.h" |
17 #include "sync/api/attachments/attachment.h" | 17 #include "sync/api/attachments/attachment.h" |
18 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h" | 18 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h" |
| 19 #include "sync/internal_api/public/attachments/attachment_util.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "third_party/leveldatabase/src/util/crc32c.h" |
20 | 22 |
21 namespace syncer { | 23 namespace syncer { |
22 | 24 |
23 namespace { | 25 namespace { |
24 | 26 |
25 const char kAccountId[] = "attachments@gmail.com"; | 27 const char kAccountId[] = "attachments@gmail.com"; |
26 const char kAccessToken[] = "access.token"; | 28 const char kAccessToken[] = "access.token"; |
27 const char kAttachmentServerUrl[] = "http://attachments.com/"; | 29 const char kAttachmentServerUrl[] = "http://attachments.com/"; |
28 const char kAttachmentContent[] = "attachment.content"; | 30 const char kAttachmentContent[] = "attachment.content"; |
29 | 31 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 void AttachmentDownloaderImplTest::AddHashHeader( | 273 void AttachmentDownloaderImplTest::AddHashHeader( |
272 HashHeaderType hash_header_type, | 274 HashHeaderType hash_header_type, |
273 net::TestURLFetcher* fetcher) { | 275 net::TestURLFetcher* fetcher) { |
274 std::string header = "X-Goog-Hash: crc32c="; | 276 std::string header = "X-Goog-Hash: crc32c="; |
275 scoped_refptr<net::HttpResponseHeaders> headers( | 277 scoped_refptr<net::HttpResponseHeaders> headers( |
276 new net::HttpResponseHeaders("")); | 278 new net::HttpResponseHeaders("")); |
277 switch (hash_header_type) { | 279 switch (hash_header_type) { |
278 case HASH_HEADER_NONE: | 280 case HASH_HEADER_NONE: |
279 break; | 281 break; |
280 case HASH_HEADER_VALID: | 282 case HASH_HEADER_VALID: |
281 header += AttachmentUploaderImpl::ComputeCrc32cHash( | 283 header += AttachmentUploaderImpl::FormatCrc32cHash(leveldb::crc32c::Value( |
282 kAttachmentContent, strlen(kAttachmentContent)); | 284 kAttachmentContent, strlen(kAttachmentContent))); |
283 headers->AddHeader(header); | 285 headers->AddHeader(header); |
284 break; | 286 break; |
285 case HASH_HEADER_INVALID: | 287 case HASH_HEADER_INVALID: |
286 header += "BOGUS1=="; | 288 header += "BOGUS1=="; |
287 headers->AddHeader(header); | 289 headers->AddHeader(header); |
288 break; | 290 break; |
289 } | 291 } |
290 fetcher->set_response_headers(headers); | 292 fetcher->set_response_headers(headers); |
291 } | 293 } |
292 | 294 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 AttachmentId id1 = AttachmentId::Create(); | 414 AttachmentId id1 = AttachmentId::Create(); |
413 downloader()->DownloadAttachment(id1, download_callback(id1)); | 415 downloader()->DownloadAttachment(id1, download_callback(id1)); |
414 RunMessageLoop(); | 416 RunMessageLoop(); |
415 token_service()->RespondToAccessTokenRequest( | 417 token_service()->RespondToAccessTokenRequest( |
416 GoogleServiceAuthError::AuthErrorNone()); | 418 GoogleServiceAuthError::AuthErrorNone()); |
417 RunMessageLoop(); | 419 RunMessageLoop(); |
418 CompleteDownload(net::HTTP_OK, HASH_HEADER_INVALID); | 420 CompleteDownload(net::HTTP_OK, HASH_HEADER_INVALID); |
419 VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR); | 421 VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR); |
420 } | 422 } |
421 | 423 |
| 424 // Verify that extract fails when there is no headers object. |
| 425 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_NoHeaders) { |
| 426 uint32_t extracted; |
| 427 ASSERT_FALSE(AttachmentDownloaderImpl::ExtractCrc32c(nullptr, &extracted)); |
| 428 } |
422 | 429 |
423 // Verify that extract fails when there is no crc32c value. | 430 // Verify that extract fails when there is no crc32c value. |
424 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_Empty) { | 431 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_Empty) { |
425 std::string raw; | 432 std::string raw; |
426 raw += "HTTP/1.1 200 OK\n"; | 433 raw += "HTTP/1.1 200 OK\n"; |
427 raw += "Foo: bar\n"; | 434 raw += "Foo: bar\n"; |
428 raw += "X-Goog-HASH: crc32c=\n"; | 435 raw += "X-Goog-HASH: crc32c=\n"; |
429 raw += "\n"; | 436 raw += "\n"; |
430 std::replace(raw.begin(), raw.end(), '\n', '\0'); | 437 std::replace(raw.begin(), raw.end(), '\n', '\0'); |
431 scoped_refptr<net::HttpResponseHeaders> headers( | 438 scoped_refptr<net::HttpResponseHeaders> headers( |
432 new net::HttpResponseHeaders(raw)); | 439 new net::HttpResponseHeaders(raw)); |
433 std::string extracted; | 440 uint32_t extracted; |
434 ASSERT_FALSE(AttachmentDownloaderImpl::ExtractCrc32c(*headers, &extracted)); | 441 ASSERT_FALSE( |
| 442 AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted)); |
435 } | 443 } |
436 | 444 |
437 // Verify that extract finds the first crc32c and ignores others. | 445 // Verify that extract finds the first crc32c and ignores others. |
438 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_First) { | 446 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_First) { |
439 const std::string expected = "z8SuHQ=="; | 447 const std::string expected_encoded = "z8SuHQ=="; |
| 448 const uint32_t expected = 3485773341; |
440 std::string raw; | 449 std::string raw; |
441 raw += "HTTP/1.1 200 OK\n"; | 450 raw += "HTTP/1.1 200 OK\n"; |
442 raw += "Foo: bar\n"; | 451 raw += "Foo: bar\n"; |
443 // Ignored because it's the wrong header. | 452 // Ignored because it's the wrong header. |
444 raw += "X-Goog-Hashes: crc32c=AAAAAA==\n"; | 453 raw += "X-Goog-Hashes: crc32c=AAAAAA==\n"; |
445 // Header name matches. The md5 item is ignored. | 454 // Header name matches. The md5 item is ignored. |
446 raw += "X-Goog-HASH: md5=rL0Y20zC+Fzt72VPzMSk2A==,crc32c=" + expected + "\n"; | 455 raw += "X-Goog-HASH: md5=rL0Y20zC+Fzt72VPzMSk2A==,crc32c=" + |
| 456 expected_encoded + "\n"; |
447 // Ignored because we already found a crc32c in the one above. | 457 // Ignored because we already found a crc32c in the one above. |
448 raw += "X-Goog-HASH: crc32c=AAAAAA==\n"; | 458 raw += "X-Goog-HASH: crc32c=AAAAAA==\n"; |
449 raw += "\n"; | 459 raw += "\n"; |
450 std::replace(raw.begin(), raw.end(), '\n', '\0'); | 460 std::replace(raw.begin(), raw.end(), '\n', '\0'); |
451 scoped_refptr<net::HttpResponseHeaders> headers( | 461 scoped_refptr<net::HttpResponseHeaders> headers( |
452 new net::HttpResponseHeaders(raw)); | 462 new net::HttpResponseHeaders(raw)); |
453 std::string extracted; | 463 uint32_t extracted; |
454 ASSERT_TRUE(AttachmentDownloaderImpl::ExtractCrc32c(*headers, &extracted)); | 464 ASSERT_TRUE( |
| 465 AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted)); |
455 ASSERT_EQ(expected, extracted); | 466 ASSERT_EQ(expected, extracted); |
456 } | 467 } |
457 | 468 |
| 469 // Verify that extract fails when encoded value is too long. |
| 470 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_TooLong) { |
| 471 std::string raw; |
| 472 raw += "HTTP/1.1 200 OK\n"; |
| 473 raw += "Foo: bar\n"; |
| 474 raw += "X-Goog-HASH: crc32c=AAAAAAAA\n"; |
| 475 raw += "\n"; |
| 476 std::replace(raw.begin(), raw.end(), '\n', '\0'); |
| 477 scoped_refptr<net::HttpResponseHeaders> headers( |
| 478 new net::HttpResponseHeaders(raw)); |
| 479 uint32_t extracted; |
| 480 ASSERT_FALSE( |
| 481 AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted)); |
| 482 } |
| 483 |
458 // Verify that extract fails if there is no crc32c. | 484 // Verify that extract fails if there is no crc32c. |
459 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_None) { | 485 TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_None) { |
460 std::string raw; | 486 std::string raw; |
461 raw += "HTTP/1.1 200 OK\n"; | 487 raw += "HTTP/1.1 200 OK\n"; |
462 raw += "Foo: bar\n"; | 488 raw += "Foo: bar\n"; |
463 raw += "X-Goog-Hash: md5=rL0Y20zC+Fzt72VPzMSk2A==\n"; | 489 raw += "X-Goog-Hash: md5=rL0Y20zC+Fzt72VPzMSk2A==\n"; |
464 raw += "\n"; | 490 raw += "\n"; |
465 std::replace(raw.begin(), raw.end(), '\n', '\0'); | 491 std::replace(raw.begin(), raw.end(), '\n', '\0'); |
466 scoped_refptr<net::HttpResponseHeaders> headers( | 492 scoped_refptr<net::HttpResponseHeaders> headers( |
467 new net::HttpResponseHeaders(raw)); | 493 new net::HttpResponseHeaders(raw)); |
468 std::string extracted; | 494 uint32_t extracted; |
469 ASSERT_FALSE(AttachmentDownloaderImpl::ExtractCrc32c(*headers, &extracted)); | 495 ASSERT_FALSE( |
| 496 AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted)); |
470 } | 497 } |
471 | 498 |
472 } // namespace syncer | 499 } // namespace syncer |
OLD | NEW |