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) { |
| 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 (std::vector<std::string>::const_iterator it = vary_keys.begin(); |
| 385 it != vary_keys.end(); |
| 386 ++it) { |
| 387 std::string trimmed; |
| 388 base::TrimWhitespaceASCII(*it, base::TRIM_ALL, &trimmed); |
| 389 if (trimmed == "*") |
| 390 return false; |
| 391 |
| 392 ServiceWorkerHeaderMap::const_iterator request_iter = request.find(trimmed); |
| 393 ServiceWorkerHeaderMap::const_iterator cached_request_iter = |
| 394 cached_request.find(trimmed); |
| 395 |
| 396 // If the header exists in one but not the other, no match. |
| 397 if ((request_iter == request.end()) != |
| 398 (cached_request_iter == cached_request.end())) |
| 399 return false; |
| 400 |
| 401 // If the header exists in one, it exists in both. Verify that the values |
| 402 // are equal. |
| 403 if (request_iter != request.end() && |
| 404 request_iter->second != cached_request_iter->second) |
| 405 return false; |
| 406 } |
| 407 |
| 408 return true; |
| 409 } |
| 410 |
374 void MatchDidReadHeaderData( | 411 void MatchDidReadHeaderData( |
375 scoped_ptr<ServiceWorkerFetchRequest> request, | 412 scoped_ptr<ServiceWorkerFetchRequest> request, |
376 const ServiceWorkerCache::ResponseCallback& callback, | 413 const ServiceWorkerCache::ResponseCallback& callback, |
377 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 414 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
378 disk_cache::ScopedEntryPtr entry, | 415 disk_cache::ScopedEntryPtr entry, |
379 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { | 416 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { |
380 if (!headers) { | 417 if (!headers) { |
381 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 418 callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
382 scoped_ptr<ServiceWorkerResponse>(), | 419 scoped_ptr<ServiceWorkerResponse>(), |
383 scoped_ptr<storage::BlobDataHandle>()); | 420 scoped_ptr<storage::BlobDataHandle>()); |
384 return; | 421 return; |
385 } | 422 } |
386 | 423 |
387 scoped_ptr<ServiceWorkerResponse> response( | 424 scoped_ptr<ServiceWorkerResponse> response( |
388 new ServiceWorkerResponse(request->url, | 425 new ServiceWorkerResponse(request->url, |
389 headers->status_code(), | 426 headers->status_code(), |
390 headers->status_text(), | 427 headers->status_text(), |
391 ServiceWorkerHeaderMap(), | 428 ServiceWorkerHeaderMap(), |
392 "")); | 429 "")); |
393 | 430 |
394 for (int i = 0; i < headers->response_headers_size(); ++i) { | 431 for (int i = 0; i < headers->response_headers_size(); ++i) { |
395 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | 432 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
396 headers->response_headers(i); | 433 headers->response_headers(i); |
397 response->headers.insert(std::make_pair(header.name(), header.value())); | 434 response->headers.insert(std::make_pair(header.name(), header.value())); |
398 } | 435 } |
399 | 436 |
400 // TODO(jkarlin): Insert vary validation here. | 437 ServiceWorkerHeaderMap cached_request_headers; |
| 438 for (int i = 0; i < headers->request_headers_size(); ++i) { |
| 439 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
| 440 headers->request_headers(i); |
| 441 cached_request_headers[header.name()] = header.value(); |
| 442 } |
| 443 |
| 444 if (!VaryMatches( |
| 445 request->headers, cached_request_headers, response->headers)) { |
| 446 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, |
| 447 scoped_ptr<ServiceWorkerResponse>(), |
| 448 scoped_ptr<storage::BlobDataHandle>()); |
| 449 return; |
| 450 } |
401 | 451 |
402 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { | 452 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
403 callback.Run(ServiceWorkerCache::ErrorTypeOK, | 453 callback.Run(ServiceWorkerCache::ErrorTypeOK, |
404 response.Pass(), | 454 response.Pass(), |
405 scoped_ptr<storage::BlobDataHandle>()); | 455 scoped_ptr<storage::BlobDataHandle>()); |
406 return; | 456 return; |
407 } | 457 } |
408 | 458 |
409 // Stream the response body into a blob. | 459 // Stream the response body into a blob. |
410 if (!blob_storage) { | 460 if (!blob_storage) { |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 initialized_ = true; | 1021 initialized_ = true; |
972 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 1022 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
973 it != init_callbacks_.end(); | 1023 it != init_callbacks_.end(); |
974 ++it) { | 1024 ++it) { |
975 it->Run(); | 1025 it->Run(); |
976 } | 1026 } |
977 init_callbacks_.clear(); | 1027 init_callbacks_.clear(); |
978 } | 1028 } |
979 | 1029 |
980 } // namespace content | 1030 } // namespace content |
OLD | NEW |