| 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 |