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 |