Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: content/browser/service_worker/service_worker_cache.cc

Issue 574393002: Add Vary support for ServiceWorkerCache::Match. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments and new test Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/service_worker/service_worker_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
22 namespace content { 23 namespace content {
23 24
24 namespace { 25 namespace {
25 26
26 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; 27 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr;
27 typedef base::Callback<void(bool)> BoolCallback; 28 typedef base::Callback<void(bool)> BoolCallback;
28 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 29 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
29 EntryBoolCallback; 30 EntryBoolCallback;
30 typedef base::Callback<void(scoped_ptr<ServiceWorkerRequestResponseHeaders>)> 31 typedef base::Callback<void(scoped_ptr<ServiceWorkerRequestResponseHeaders>)>
31 HeadersCallback; 32 HeadersCallback;
33 typedef std::map<std::string, std::string> HeaderMap;
32 34
33 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; 35 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
34 36
35 // The maximum size of an individual cache. Ultimately cache size is controlled 37 // The maximum size of an individual cache. Ultimately cache size is controlled
36 // per-origin. 38 // per-origin.
37 const int kMaxCacheBytes = 512 * 1024 * 1024; 39 const int kMaxCacheBytes = 512 * 1024 * 1024;
38 40
39 // Buffer size for cache and blob reading/writing. 41 // Buffer size for cache and blob reading/writing.
40 const int kBufferSize = 1024 * 512; 42 const int kBufferSize = 1024 * 512;
41 43
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 368
367 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, 369 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData,
368 base::Passed(request.Pass()), 370 base::Passed(request.Pass()),
369 callback, 371 callback,
370 blob_storage, 372 blob_storage,
371 base::Passed(entry.Pass())); 373 base::Passed(entry.Pass()));
372 374
373 ReadHeaders(tmp_entry_ptr, headers_callback); 375 ReadHeaders(tmp_entry_ptr, headers_callback);
374 } 376 }
375 377
378 bool VaryMatches(const HeaderMap& request,
379 const HeaderMap& cached_request,
380 const HeaderMap& response) {
381 // The headers are assumed to have lower-case keys. This is enforced by
382 // ASSERTS in WebServiceWorkerRequest and WebServiceWorkerResponse.
jkarlin 2014/09/17 18:48:10 The ASSERTS this comment speaks of are in review:
383 HeaderMap::const_iterator vary_iter = response.find("vary");
384 if (vary_iter == response.end())
385 return true;
386
387 std::vector<std::string> vary_keys;
388 Tokenize(vary_iter->second, ",", &vary_keys);
389 for (size_t i = 0, max = vary_keys.size(); i < max; ++i) {
390 std::string trimmed;
391 base::TrimWhitespaceASCII(vary_keys[i], base::TRIM_ALL, &trimmed);
392 if (trimmed == "*")
393 return false;
394
395 HeaderMap::const_iterator request_iter = request.find(trimmed);
396 HeaderMap::const_iterator cached_request_iter =
397 cached_request.find(trimmed);
398
399 // If the header exists in one but not the other, no match.
400 if ((request_iter == request.end()) !=
401 (cached_request_iter == cached_request.end()))
402 return false;
403
404 // If the header exists in one, it exists in both. Verify that the values
405 // are equal.
406 if (request_iter != request.end() &&
407 request_iter->second != cached_request_iter->second)
408 return false;
409 }
410
411 return true;
412 }
413
376 void MatchDidReadHeaderData( 414 void MatchDidReadHeaderData(
377 scoped_ptr<ServiceWorkerFetchRequest> request, 415 scoped_ptr<ServiceWorkerFetchRequest> request,
378 const ServiceWorkerCache::ResponseCallback& callback, 416 const ServiceWorkerCache::ResponseCallback& callback,
379 base::WeakPtr<storage::BlobStorageContext> blob_storage, 417 base::WeakPtr<storage::BlobStorageContext> blob_storage,
380 disk_cache::ScopedEntryPtr entry, 418 disk_cache::ScopedEntryPtr entry,
381 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { 419 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) {
382 if (!headers) { 420 if (!headers) {
383 callback.Run(ServiceWorkerCache::ErrorTypeStorage, 421 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
384 scoped_ptr<ServiceWorkerResponse>(), 422 scoped_ptr<ServiceWorkerResponse>(),
385 scoped_ptr<storage::BlobDataHandle>()); 423 scoped_ptr<storage::BlobDataHandle>());
386 return; 424 return;
387 } 425 }
388 426
389 scoped_ptr<ServiceWorkerResponse> response( 427 scoped_ptr<ServiceWorkerResponse> response(
390 new ServiceWorkerResponse(request->url, 428 new ServiceWorkerResponse(request->url,
391 headers->status_code(), 429 headers->status_code(),
392 headers->status_text(), 430 headers->status_text(),
393 std::map<std::string, std::string>(), 431 std::map<std::string, std::string>(),
394 "")); 432 ""));
395 433
396 for (int i = 0; i < headers->response_headers_size(); ++i) { 434 for (int i = 0; i < headers->response_headers_size(); ++i) {
397 const ServiceWorkerRequestResponseHeaders::HeaderMap header = 435 const ServiceWorkerRequestResponseHeaders::HeaderMap header =
398 headers->response_headers(i); 436 headers->response_headers(i);
399 response->headers.insert(std::make_pair(header.name(), header.value())); 437 response->headers.insert(std::make_pair(header.name(), header.value()));
400 } 438 }
401 439
402 // TODO(jkarlin): Insert vary validation here. 440 HeaderMap cached_request_headers;
441 for (int i = 0; i < headers->request_headers_size(); ++i) {
442 const ServiceWorkerRequestResponseHeaders::HeaderMap header =
443 headers->request_headers(i);
444 cached_request_headers.insert(
445 std::make_pair(header.name(), header.value()));
446 }
447
448 if (!VaryMatches(
449 request->headers, cached_request_headers, response->headers)) {
450 callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
451 scoped_ptr<ServiceWorkerResponse>(),
452 scoped_ptr<storage::BlobDataHandle>());
453 return;
454 }
403 455
404 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { 456 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
405 callback.Run(ServiceWorkerCache::ErrorTypeOK, 457 callback.Run(ServiceWorkerCache::ErrorTypeOK,
406 response.Pass(), 458 response.Pass(),
407 scoped_ptr<storage::BlobDataHandle>()); 459 scoped_ptr<storage::BlobDataHandle>());
408 return; 460 return;
409 } 461 }
410 462
411 // Stream the response body into a blob. 463 // Stream the response body into a blob.
412 if (!blob_storage) { 464 if (!blob_storage) {
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 initialized_ = true; 1025 initialized_ = true;
974 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 1026 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
975 it != init_callbacks_.end(); 1027 it != init_callbacks_.end();
976 ++it) { 1028 ++it) {
977 it->Run(); 1029 it->Run();
978 } 1030 }
979 init_callbacks_.clear(); 1031 init_callbacks_.clear();
980 } 1032 }
981 1033
982 } // namespace content 1034 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/service_worker/service_worker_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698