OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/web_application_cache_host_impl.h" | 5 #include "webkit/appcache/web_application_cache_host_impl.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/id_map.h" | 8 #include "base/id_map.h" |
| 9 #include "base/string_util.h" |
9 #include "webkit/api/public/WebURL.h" | 10 #include "webkit/api/public/WebURL.h" |
10 #include "webkit/api/public/WebURLRequest.h" | 11 #include "webkit/api/public/WebURLRequest.h" |
11 #include "webkit/api/public/WebURLResponse.h" | 12 #include "webkit/api/public/WebURLResponse.h" |
12 | 13 |
13 using WebKit::WebApplicationCacheHost; | 14 using WebKit::WebApplicationCacheHost; |
14 using WebKit::WebApplicationCacheHostClient; | 15 using WebKit::WebApplicationCacheHostClient; |
15 using WebKit::WebURLRequest; | 16 using WebKit::WebURLRequest; |
16 using WebKit::WebURL; | 17 using WebKit::WebURL; |
17 using WebKit::WebURLResponse; | 18 using WebKit::WebURLResponse; |
18 | 19 |
19 namespace appcache { | 20 namespace appcache { |
20 | 21 |
21 static IDMap<WebApplicationCacheHostImpl> all_hosts; | 22 static IDMap<WebApplicationCacheHostImpl> all_hosts; |
22 | 23 |
23 WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { | 24 WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { |
24 return all_hosts.Lookup(id); | 25 return all_hosts.Lookup(id); |
25 } | 26 } |
26 | 27 |
27 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( | 28 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( |
28 WebApplicationCacheHostClient* client, | 29 WebApplicationCacheHostClient* client, |
29 AppCacheBackend* backend) | 30 AppCacheBackend* backend) |
30 : client_(client), | 31 : client_(client), |
31 backend_(backend), | 32 backend_(backend), |
32 ALLOW_THIS_IN_INITIALIZER_LIST(host_id_(all_hosts.Add(this))), | 33 ALLOW_THIS_IN_INITIALIZER_LIST(host_id_(all_hosts.Add(this))), |
33 has_status_(false), | 34 has_status_(false), |
34 status_(UNCACHED), | 35 status_(UNCACHED), |
35 has_cached_status_(false), | 36 has_cached_status_(false), |
36 cached_status_(UNCACHED), | 37 cached_status_(UNCACHED), |
37 is_in_http_family_(false), | 38 is_scheme_supported_(false), |
38 should_capture_main_response_(MAYBE) { | 39 is_get_method_(false), |
| 40 is_new_master_entry_(MAYBE) { |
39 DCHECK(client && backend && (host_id_ != kNoHostId)); | 41 DCHECK(client && backend && (host_id_ != kNoHostId)); |
40 | 42 |
41 backend_->RegisterHost(host_id_); | 43 backend_->RegisterHost(host_id_); |
42 } | 44 } |
43 | 45 |
44 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { | 46 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { |
45 backend_->UnregisterHost(host_id_); | 47 backend_->UnregisterHost(host_id_); |
46 all_hosts.Remove(host_id_); | 48 all_hosts.Remove(host_id_); |
47 } | 49 } |
48 | 50 |
49 void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id, | 51 void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id, |
50 appcache::Status status) { | 52 appcache::Status status) { |
51 status_ = status; | 53 status_ = status; |
52 has_status_ = true; | 54 has_status_ = true; |
53 } | 55 } |
54 | 56 |
55 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { | 57 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { |
56 if (has_status_) | 58 if (has_status_) |
57 status_ = status; | 59 status_ = status; |
58 } | 60 } |
59 | 61 |
60 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { | 62 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { |
61 client_->notifyEventListener(static_cast<EventID>(event_id)); | 63 client_->notifyEventListener(static_cast<EventID>(event_id)); |
62 } | 64 } |
63 | 65 |
64 void WebApplicationCacheHostImpl::willStartMainResourceRequest( | 66 void WebApplicationCacheHostImpl::willStartMainResourceRequest( |
65 WebURLRequest& request) { | 67 WebURLRequest& request) { |
66 request.setAppCacheHostID(host_id_); | 68 request.setAppCacheHostID(host_id_); |
| 69 std::string method = request.httpMethod().utf8(); |
| 70 is_get_method_ = (method == kHttpGETMethod); |
| 71 DCHECK(method == StringToUpperASCII(method)); |
67 } | 72 } |
68 | 73 |
69 void WebApplicationCacheHostImpl::willStartSubResourceRequest( | 74 void WebApplicationCacheHostImpl::willStartSubResourceRequest( |
70 WebURLRequest& request) { | 75 WebURLRequest& request) { |
71 request.setAppCacheHostID(host_id_); | 76 request.setAppCacheHostID(host_id_); |
72 } | 77 } |
73 | 78 |
74 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { | 79 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { |
75 // Reset any previous status values we've received from the backend | 80 // Reset any previous status values we've received from the backend |
76 // since we're now selecting a new cache. | 81 // since we're now selecting a new cache. |
77 has_status_ = false; | 82 has_status_ = false; |
78 has_cached_status_ = false; | 83 has_cached_status_ = false; |
79 should_capture_main_response_ = NO; | 84 is_new_master_entry_ = NO; |
80 backend_->SelectCache(host_id_, main_response_url_, | 85 backend_->SelectCache(host_id_, document_url_, |
81 main_response_.appCacheID(), | 86 document_response_.appCacheID(), |
82 GURL()); | 87 GURL()); |
83 } | 88 } |
84 | 89 |
85 bool WebApplicationCacheHostImpl::selectCacheWithManifest( | 90 bool WebApplicationCacheHostImpl::selectCacheWithManifest( |
86 const WebURL& manifest_url) { | 91 const WebURL& manifest_url) { |
87 // Reset any previous status values we've received from the backend | 92 // Reset any previous status values we've received from the backend |
88 // since we're now selecting a new cache. | 93 // since we're now selecting a new cache. |
89 has_status_ = false; | 94 has_status_ = false; |
90 has_cached_status_ = false; | 95 has_cached_status_ = false; |
91 | 96 |
92 GURL manifest_gurl(manifest_url); | 97 GURL manifest_gurl(manifest_url); |
93 if (manifest_gurl.has_ref()) { | 98 if (manifest_gurl.has_ref()) { |
94 GURL::Replacements replacements; | 99 GURL::Replacements replacements; |
95 replacements.ClearRef(); | 100 replacements.ClearRef(); |
96 manifest_gurl = manifest_gurl.ReplaceComponents(replacements); | 101 manifest_gurl = manifest_gurl.ReplaceComponents(replacements); |
97 } | 102 } |
98 | 103 |
| 104 // 6.9.6 The application cache selection algorithm |
99 // Check for new 'master' entries. | 105 // Check for new 'master' entries. |
100 if (main_response_.appCacheID() == kNoCacheId) { | 106 if (document_response_.appCacheID() == kNoCacheId) { |
101 should_capture_main_response_ = is_in_http_family_ ? YES : NO; | 107 if (is_scheme_supported_ && is_get_method_ && |
102 backend_->SelectCache(host_id_, main_response_url_, | 108 (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { |
| 109 is_new_master_entry_ = YES; |
| 110 } else { |
| 111 is_new_master_entry_ = NO; |
| 112 manifest_gurl = GURL::EmptyGURL(); |
| 113 } |
| 114 backend_->SelectCache(host_id_, document_url_, |
103 kNoCacheId, manifest_gurl); | 115 kNoCacheId, manifest_gurl); |
104 return true; | 116 return true; |
105 } | 117 } |
106 | 118 |
107 DCHECK(should_capture_main_response_ == NO); | 119 DCHECK(is_new_master_entry_ = NO); |
108 | 120 |
| 121 // 6.9.6 The application cache selection algorithm |
109 // Check for 'foreign' entries. | 122 // Check for 'foreign' entries. |
110 GURL main_response_manifest_gurl(main_response_.appCacheManifestURL()); | 123 GURL document_manifest_gurl(document_response_.appCacheManifestURL()); |
111 if (main_response_manifest_gurl != manifest_gurl) { | 124 if (document_manifest_gurl != manifest_gurl) { |
112 backend_->MarkAsForeignEntry(host_id_, main_response_url_, | 125 backend_->MarkAsForeignEntry(host_id_, document_url_, |
113 main_response_.appCacheID()); | 126 document_response_.appCacheID()); |
114 has_cached_status_ = true; | 127 has_cached_status_ = true; |
115 cached_status_ = UNCACHED; | 128 cached_status_ = UNCACHED; |
116 return false; // the navigation will be restarted | 129 return false; // the navigation will be restarted |
117 } | 130 } |
118 | 131 |
119 // Its a 'master' entry thats already in the cache. | 132 // Its a 'master' entry thats already in the cache. |
120 backend_->SelectCache(host_id_, main_response_url_, | 133 backend_->SelectCache(host_id_, document_url_, |
121 main_response_.appCacheID(), | 134 document_response_.appCacheID(), |
122 manifest_gurl); | 135 manifest_gurl); |
123 return true; | 136 return true; |
124 } | 137 } |
125 | 138 |
126 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( | 139 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( |
127 const WebURLResponse& response) { | 140 const WebURLResponse& response) { |
128 main_response_ = response; | 141 document_response_ = response; |
129 main_response_url_ = main_response_.url(); | 142 document_url_ = document_response_.url(); |
130 is_in_http_family_ = main_response_url_.SchemeIs("http") || | 143 is_scheme_supported_ = IsSchemeSupported(document_url_); |
131 main_response_url_.SchemeIs("https"); | 144 if ((document_response_.appCacheID() != kNoCacheId) || |
132 if ((main_response_.appCacheID() != kNoCacheId) || !is_in_http_family_) | 145 !is_scheme_supported_ || !is_get_method_) |
133 should_capture_main_response_ = NO; | 146 is_new_master_entry_ = NO; |
134 } | 147 } |
135 | 148 |
136 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( | 149 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( |
137 const char* data, int len) { | 150 const char* data, int len) { |
138 if (should_capture_main_response_ == NO) | 151 if (is_new_master_entry_ == NO) |
139 return; | 152 return; |
140 // TODO(michaeln): write me | 153 // TODO(michaeln): write me |
141 } | 154 } |
142 | 155 |
143 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { | 156 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { |
144 if (should_capture_main_response_ == NO) | 157 if (is_new_master_entry_ == NO) |
145 return; | 158 return; |
146 // TODO(michaeln): write me | 159 // TODO(michaeln): write me |
147 } | 160 } |
148 | 161 |
149 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { | 162 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { |
150 // We're careful about the status value to avoid race conditions. | 163 // We're careful about the status value to avoid race conditions. |
151 // | 164 // |
152 // Generally the webappcachehost sends an async stream of messages to the | 165 // Generally the webappcachehost sends an async stream of messages to the |
153 // backend, and receives an asyncronous stream of events from the backend. | 166 // backend, and receives an asyncronous stream of events from the backend. |
154 // In the backend, all operations are serialized and as state changes | 167 // In the backend, all operations are serialized and as state changes |
(...skipping 19 matching lines...) Expand all Loading... |
174 | 187 |
175 bool WebApplicationCacheHostImpl::startUpdate() { | 188 bool WebApplicationCacheHostImpl::startUpdate() { |
176 return backend_->StartUpdate(host_id_); | 189 return backend_->StartUpdate(host_id_); |
177 } | 190 } |
178 | 191 |
179 bool WebApplicationCacheHostImpl::swapCache() { | 192 bool WebApplicationCacheHostImpl::swapCache() { |
180 return backend_->SwapCache(host_id_); | 193 return backend_->SwapCache(host_id_); |
181 } | 194 } |
182 | 195 |
183 } // appcache namespace | 196 } // appcache namespace |
OLD | NEW |