Chromium Code Reviews| 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 "content/browser/service_worker/service_worker_cache.h" | 5 #include "content/browser/service_worker/service_worker_cache.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/guid.h" | 10 #include "base/guid.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "base/strings/string_util.h" | |
| 12 #include "content/browser/service_worker/service_worker_cache.pb.h" | 13 #include "content/browser/service_worker/service_worker_cache.pb.h" |
| 13 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 16 #include "net/disk_cache/disk_cache.h" | 17 #include "net/disk_cache/disk_cache.h" |
| 17 #include "net/url_request/url_request_context.h" | 18 #include "net/url_request/url_request_context.h" |
| 18 #include "storage/browser/blob/blob_data_handle.h" | 19 #include "storage/browser/blob/blob_data_handle.h" |
| 19 #include "storage/browser/blob/blob_storage_context.h" | 20 #include "storage/browser/blob/blob_storage_context.h" |
| 20 #include "storage/browser/blob/blob_url_request_job_factory.h" | 21 #include "storage/browser/blob/blob_url_request_job_factory.h" |
| 21 | 22 |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 | 365 |
| 365 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, | 366 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, |
| 366 base::Passed(request.Pass()), | 367 base::Passed(request.Pass()), |
| 367 callback, | 368 callback, |
| 368 blob_storage, | 369 blob_storage, |
| 369 base::Passed(entry.Pass())); | 370 base::Passed(entry.Pass())); |
| 370 | 371 |
| 371 ReadHeaders(tmp_entry_ptr, headers_callback); | 372 ReadHeaders(tmp_entry_ptr, headers_callback); |
| 372 } | 373 } |
| 373 | 374 |
| 375 bool VaryMatches(const ServiceWorkerHeaderMap& request, | |
| 376 const ServiceWorkerHeaderMap& cached_request, | |
| 377 const ServiceWorkerHeaderMap& response) { | |
|
jsbell
2014/09/22 19:17:32
(I'm assuming we lowercase all the header names so
jsbell
2014/09/22 19:18:18
... and that'd be https://codereview.chromium.org/
jkarlin
2014/09/23 11:42:51
Acknowledged.
| |
| 378 ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary"); | |
| 379 if (vary_iter == response.end()) | |
| 380 return true; | |
| 381 | |
| 382 std::vector<std::string> vary_keys; | |
| 383 Tokenize(vary_iter->second, ",", &vary_keys); | |
| 384 for (size_t i = 0, max = vary_keys.size(); i < max; ++i) { | |
|
jsbell
2014/09/22 19:17:32
Why is this an index/size loop instead of an itera
jkarlin
2014/09/23 11:42:51
Done.
| |
| 385 std::string trimmed; | |
| 386 base::TrimWhitespaceASCII(vary_keys[i], base::TRIM_ALL, &trimmed); | |
| 387 if (trimmed == "*") | |
| 388 return false; | |
| 389 | |
| 390 ServiceWorkerHeaderMap::const_iterator request_iter = request.find(trimmed); | |
| 391 ServiceWorkerHeaderMap::const_iterator cached_request_iter = | |
| 392 cached_request.find(trimmed); | |
| 393 | |
| 394 // If the header exists in one but not the other, no match. | |
| 395 if ((request_iter == request.end()) != | |
| 396 (cached_request_iter == cached_request.end())) | |
| 397 return false; | |
| 398 | |
| 399 // If the header exists in one, it exists in both. Verify that the values | |
| 400 // are equal. | |
| 401 if (request_iter != request.end() && | |
| 402 request_iter->second != cached_request_iter->second) | |
| 403 return false; | |
| 404 } | |
| 405 | |
| 406 return true; | |
| 407 } | |
| 408 | |
| 374 void MatchDidReadHeaderData( | 409 void MatchDidReadHeaderData( |
| 375 scoped_ptr<ServiceWorkerFetchRequest> request, | 410 scoped_ptr<ServiceWorkerFetchRequest> request, |
| 376 const ServiceWorkerCache::ResponseCallback& callback, | 411 const ServiceWorkerCache::ResponseCallback& callback, |
| 377 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 412 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 378 disk_cache::ScopedEntryPtr entry, | 413 disk_cache::ScopedEntryPtr entry, |
| 379 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { | 414 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { |
| 380 if (!headers) { | 415 if (!headers) { |
| 381 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 416 callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 382 scoped_ptr<ServiceWorkerResponse>(), | 417 scoped_ptr<ServiceWorkerResponse>(), |
| 383 scoped_ptr<storage::BlobDataHandle>()); | 418 scoped_ptr<storage::BlobDataHandle>()); |
| 384 return; | 419 return; |
| 385 } | 420 } |
| 386 | 421 |
| 387 scoped_ptr<ServiceWorkerResponse> response( | 422 scoped_ptr<ServiceWorkerResponse> response( |
| 388 new ServiceWorkerResponse(request->url, | 423 new ServiceWorkerResponse(request->url, |
| 389 headers->status_code(), | 424 headers->status_code(), |
| 390 headers->status_text(), | 425 headers->status_text(), |
| 391 ServiceWorkerHeaderMap(), | 426 ServiceWorkerHeaderMap(), |
| 392 "")); | 427 "")); |
| 393 | 428 |
| 394 for (int i = 0; i < headers->response_headers_size(); ++i) { | 429 for (int i = 0; i < headers->response_headers_size(); ++i) { |
| 395 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | 430 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
| 396 headers->response_headers(i); | 431 headers->response_headers(i); |
| 397 response->headers.insert(std::make_pair(header.name(), header.value())); | 432 response->headers.insert(std::make_pair(header.name(), header.value())); |
| 398 } | 433 } |
| 399 | 434 |
| 400 // TODO(jkarlin): Insert vary validation here. | 435 ServiceWorkerHeaderMap cached_request_headers; |
| 436 for (int i = 0; i < headers->request_headers_size(); ++i) { | |
| 437 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | |
| 438 headers->request_headers(i); | |
| 439 cached_request_headers.insert( | |
|
jsbell
2014/09/22 19:17:32
Shorter to write: cached_request_headers[header.na
jkarlin
2014/09/23 11:42:51
Done.
| |
| 440 std::make_pair(header.name(), header.value())); | |
| 441 } | |
| 442 | |
| 443 if (!VaryMatches( | |
| 444 request->headers, cached_request_headers, response->headers)) { | |
| 445 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, | |
| 446 scoped_ptr<ServiceWorkerResponse>(), | |
| 447 scoped_ptr<storage::BlobDataHandle>()); | |
| 448 return; | |
| 449 } | |
| 401 | 450 |
| 402 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { | 451 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
| 403 callback.Run(ServiceWorkerCache::ErrorTypeOK, | 452 callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 404 response.Pass(), | 453 response.Pass(), |
| 405 scoped_ptr<storage::BlobDataHandle>()); | 454 scoped_ptr<storage::BlobDataHandle>()); |
| 406 return; | 455 return; |
| 407 } | 456 } |
| 408 | 457 |
| 409 // Stream the response body into a blob. | 458 // Stream the response body into a blob. |
| 410 if (!blob_storage) { | 459 if (!blob_storage) { |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 971 initialized_ = true; | 1020 initialized_ = true; |
| 972 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 1021 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| 973 it != init_callbacks_.end(); | 1022 it != init_callbacks_.end(); |
| 974 ++it) { | 1023 ++it) { |
| 975 it->Run(); | 1024 it->Run(); |
| 976 } | 1025 } |
| 977 init_callbacks_.clear(); | 1026 init_callbacks_.clear(); |
| 978 } | 1027 } |
| 979 | 1028 |
| 980 } // namespace content | 1029 } // namespace content |
| OLD | NEW |