| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "webkit/appcache/appcache_interceptor.h" | 5 #include "webkit/appcache/appcache_interceptor.h" |
| 6 | 6 |
| 7 #include "webkit/appcache/appcache_backend_impl.h" | 7 #include "webkit/appcache/appcache_backend_impl.h" |
| 8 #include "webkit/appcache/appcache_host.h" | 8 #include "webkit/appcache/appcache_host.h" |
| 9 #include "webkit/appcache/appcache_interfaces.h" | 9 #include "webkit/appcache/appcache_interfaces.h" |
| 10 #include "webkit/appcache/appcache_request_handler.h" |
| 10 #include "webkit/appcache/appcache_service.h" | 11 #include "webkit/appcache/appcache_service.h" |
| 11 | 12 |
| 12 namespace appcache { | 13 namespace appcache { |
| 13 | 14 |
| 14 // Extra info we associate with requests for use at MaybeIntercept time. This | 15 void AppCacheInterceptor::SetHandler( |
| 15 // info is deleted when the URLRequest is deleted which occurs after the | 16 URLRequest* request, AppCacheRequestHandler* handler) { |
| 16 // request is complete and all data has been read. | 17 request->SetUserData(instance(), handler); // request takes ownership |
| 17 struct AppCacheInterceptor::ExtraInfo : public URLRequest::UserData { | 18 } |
| 18 // Inputs, extra request info | |
| 19 AppCacheService* service; | |
| 20 int process_id; | |
| 21 int host_id; | |
| 22 ResourceType::Type resource_type; | |
| 23 | 19 |
| 24 // Outputs, extra response info | 20 AppCacheRequestHandler* AppCacheInterceptor::GetHandler(URLRequest* request) { |
| 25 int64 cache_id; | 21 return reinterpret_cast<AppCacheRequestHandler*>( |
| 26 GURL manifest_url; | 22 request->GetUserData(instance())); |
| 27 | |
| 28 // The host associated with the request | |
| 29 // TODO(michaeln): Be careful with this data member, its not clear | |
| 30 // if a URLRequest can outlive the associated host. As we get further | |
| 31 // along, we'll need to notify reqeust waiting on cache selection to | |
| 32 // allow them to continue upon completion of selection. But we also need | |
| 33 // to handle navigating away from the page away prior to selection being | |
| 34 // complete. | |
| 35 AppCacheHost* host_; | |
| 36 | |
| 37 ExtraInfo(AppCacheService* service, int process_id, int host_id, | |
| 38 ResourceType::Type resource_type, AppCacheHost* host) | |
| 39 : service(service), process_id(process_id), host_id(host_id), | |
| 40 resource_type(resource_type), cache_id(kNoCacheId), host_(host) { | |
| 41 } | |
| 42 | |
| 43 static void SetInfo(URLRequest* request, ExtraInfo* info) { | |
| 44 request->SetUserData(instance(), info); // request takes ownership | |
| 45 } | |
| 46 | |
| 47 static ExtraInfo* GetInfo(URLRequest* request) { | |
| 48 return static_cast<ExtraInfo*>(request->GetUserData(instance())); | |
| 49 } | |
| 50 }; | |
| 51 | |
| 52 static bool IsMainRequest(ResourceType::Type type) { | |
| 53 // TODO(michaeln): SHARED_WORKER type? | |
| 54 return ResourceType::IsFrame(type); | |
| 55 } | 23 } |
| 56 | 24 |
| 57 void AppCacheInterceptor::SetExtraRequestInfo( | 25 void AppCacheInterceptor::SetExtraRequestInfo( |
| 58 URLRequest* request, AppCacheService* service, int process_id, | 26 URLRequest* request, AppCacheService* service, int process_id, |
| 59 int host_id, ResourceType::Type resource_type) { | 27 int host_id, ResourceType::Type resource_type) { |
| 60 if (service && (host_id != kNoHostId)) { | 28 if (!service || (host_id == kNoHostId)) |
| 61 AppCacheHost* host = service->GetBackend(process_id)->GetHost(host_id); | 29 return; |
| 62 DCHECK(host); | 30 |
| 63 if (IsMainRequest(resource_type) || host->selected_cache() || | 31 // TODO(michaeln): An invalid host id is indicative of bad data |
| 64 host->is_selection_pending()) { | 32 // from a child process. How should we handle that here? |
| 65 ExtraInfo* info = new ExtraInfo(service, process_id, | 33 AppCacheHost* host = service->GetBackend(process_id)->GetHost(host_id); |
| 66 host_id, resource_type, host); | 34 if (!host) |
| 67 ExtraInfo::SetInfo(request, info); | 35 return; |
| 68 } | 36 |
| 69 } | 37 // TODO(michaeln): SHARED_WORKER type too |
| 38 bool is_main_request = ResourceType::IsFrame(resource_type); |
| 39 |
| 40 // Create a handler for this request and associate it with the request. |
| 41 AppCacheRequestHandler* handler = |
| 42 host->CreateRequestHandler(request, is_main_request); |
| 43 if (handler) |
| 44 SetHandler(request, handler); |
| 70 } | 45 } |
| 71 | 46 |
| 72 void AppCacheInterceptor::GetExtraResponseInfo(URLRequest* request, | 47 void AppCacheInterceptor::GetExtraResponseInfo(URLRequest* request, |
| 73 int64* cache_id, | 48 int64* cache_id, |
| 74 GURL* manifest_url) { | 49 GURL* manifest_url) { |
| 75 ExtraInfo* info = ExtraInfo::GetInfo(request); | 50 DCHECK(*cache_id == kNoCacheId); |
| 76 if (info) { | 51 DCHECK(manifest_url->is_empty()); |
| 77 // TODO(michaeln): If this is a main request and it was retrieved from | 52 AppCacheRequestHandler* handler = GetHandler(request); |
| 78 // an appcache, ensure that appcache survives the frame navigation. The | 53 if (handler) |
| 79 // AppCacheHost should hold reference to that cache to prevent it from | 54 handler->GetExtraResponseInfo(cache_id, manifest_url); |
| 80 // being dropped from the in-memory collection of AppCaches. When cache | |
| 81 // selection occurs, that extra reference should be dropped. | |
| 82 *cache_id = info->cache_id; | |
| 83 *manifest_url = info->manifest_url; | |
| 84 } else { | |
| 85 DCHECK(*cache_id == kNoCacheId); | |
| 86 DCHECK(manifest_url->is_empty()); | |
| 87 } | |
| 88 } | 55 } |
| 89 | 56 |
| 90 AppCacheInterceptor::AppCacheInterceptor() { | 57 AppCacheInterceptor::AppCacheInterceptor() { |
| 91 URLRequest::RegisterRequestInterceptor(this); | 58 URLRequest::RegisterRequestInterceptor(this); |
| 92 } | 59 } |
| 93 | 60 |
| 94 AppCacheInterceptor::~AppCacheInterceptor() { | 61 AppCacheInterceptor::~AppCacheInterceptor() { |
| 95 URLRequest::UnregisterRequestInterceptor(this); | 62 URLRequest::UnregisterRequestInterceptor(this); |
| 96 } | 63 } |
| 97 | 64 |
| 98 URLRequestJob* AppCacheInterceptor::MaybeIntercept(URLRequest* request) { | 65 URLRequestJob* AppCacheInterceptor::MaybeIntercept(URLRequest* request) { |
| 99 ExtraInfo* info = ExtraInfo::GetInfo(request); | 66 AppCacheRequestHandler* handler = GetHandler(request); |
| 100 if (!info) | 67 if (!handler) |
| 101 return NULL; | 68 return NULL; |
| 102 // TODO(michaeln): write me | 69 return handler->MaybeLoadResource(request); |
| 103 return NULL; | |
| 104 } | 70 } |
| 105 | 71 |
| 106 URLRequestJob* AppCacheInterceptor::MaybeInterceptRedirect( | 72 URLRequestJob* AppCacheInterceptor::MaybeInterceptRedirect( |
| 107 URLRequest* request, | 73 URLRequest* request, |
| 108 const GURL& location) { | 74 const GURL& location) { |
| 109 ExtraInfo* info = ExtraInfo::GetInfo(request); | 75 AppCacheRequestHandler* handler = GetHandler(request); |
| 110 if (!info) | 76 if (!handler) |
| 111 return NULL; | 77 return NULL; |
| 112 // TODO(michaeln): write me | 78 return handler->MaybeLoadFallbackForRedirect(request, location); |
| 113 return NULL; | |
| 114 } | 79 } |
| 115 | 80 |
| 116 URLRequestJob* AppCacheInterceptor::MaybeInterceptResponse( | 81 URLRequestJob* AppCacheInterceptor::MaybeInterceptResponse( |
| 117 URLRequest* request) { | 82 URLRequest* request) { |
| 118 ExtraInfo* info = ExtraInfo::GetInfo(request); | 83 AppCacheRequestHandler* handler = GetHandler(request); |
| 119 if (!info) | 84 if (!handler) |
| 120 return NULL; | 85 return NULL; |
| 121 // TODO(michaeln): write me | 86 return handler->MaybeLoadFallbackForResponse(request); |
| 122 return NULL; | |
| 123 } | 87 } |
| 124 | 88 |
| 125 } // namespace appcache | 89 } // namespace appcache |
| OLD | NEW |