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 |