diff options
author | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 01:05:09 +0000 |
---|---|---|
committer | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 01:05:09 +0000 |
commit | 7e8e3dd7b1633874650f8de9a818aca8cb594f5b (patch) | |
tree | 5a973e64a1b5ca1a243744e2a9aa4a336a699985 /webkit | |
parent | 8b2034f851b1b41c2ec6539c057b63c92ef7289c (diff) | |
download | chromium_src-7e8e3dd7b1633874650f8de9a818aca8cb594f5b.zip chromium_src-7e8e3dd7b1633874650f8de9a818aca8cb594f5b.tar.gz chromium_src-7e8e3dd7b1633874650f8de9a818aca8cb594f5b.tar.bz2 |
Check for supported schemes and examine request methods at key points. We support http, https, and file (dbg only) URLs for now.
* Added IsSchemeSupported, IsMethodSupported and IsMethodAndSchemeSupported helpers, and string constants.
* Check for supported schemes and methods during cache selection and during request interception. Must be GET for cache selectino, GET or HEAD for request interception.
* Renamed some data members in WebApplicationCacheHostImpl to more closely match naming elsewhere.
* Added AppCacheHost::Observer to make life easier. (I like the observer model, and even noticed that the chrome code base has a multi-threaded version too (ala Gears)... nice :)
* Switched to using the observer model in AppCacheRequestDispatcher instead of a WeakPtr. One of the observable methods is OnDestructionImminent(host).
* Added gyp dependency on the net library
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/205017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26537 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/appcache/appcache_host.cc | 25 | ||||
-rw-r--r-- | webkit/appcache/appcache_host.h | 21 | ||||
-rw-r--r-- | webkit/appcache/appcache_interfaces.cc | 26 | ||||
-rw-r--r-- | webkit/appcache/appcache_interfaces.h | 15 | ||||
-rw-r--r-- | webkit/appcache/appcache_request_handler.cc | 37 | ||||
-rw-r--r-- | webkit/appcache/appcache_request_handler.h | 18 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.cc | 59 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.h | 11 | ||||
-rw-r--r-- | webkit/webkit.gyp | 2 |
9 files changed, 158 insertions, 56 deletions
diff --git a/webkit/appcache/appcache_host.cc b/webkit/appcache/appcache_host.cc index 252c618..77a0d96 100644 --- a/webkit/appcache/appcache_host.cc +++ b/webkit/appcache/appcache_host.cc @@ -22,11 +22,20 @@ AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend, } AppCacheHost::~AppCacheHost() { + FOR_EACH_OBSERVER(Observer, observers_, OnDestructionImminent(this)); if (associated_cache_.get()) associated_cache_->UnassociateHost(this); service_->CancelLoads(this); } +void AppCacheHost::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void AppCacheHost::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + void AppCacheHost::SelectCache(const GURL& document_url, const int64 cache_document_was_loaded_from, const GURL& manifest_url) { @@ -56,9 +65,9 @@ void AppCacheHost::SelectCache(const GURL& document_url, // 6.9.6 The application cache selection algorithm. // The algorithm is started here and continues in FinishCacheSelection, // after cache or group loading is complete. - // Note: foriegn entries are detected on the client side and + // Note: Foreign entries are detected on the client side and // MarkAsForeignEntry is called in that case, so that detection - // step is skipped here. + // step is skipped here. See WebApplicationCacheHostImpl.cc if (cache_document_was_loaded_from != kNoCacheId) { LoadCache(cache_document_was_loaded_from); @@ -67,6 +76,9 @@ void AppCacheHost::SelectCache(const GURL& document_url, if (!manifest_url.is_empty() && (manifest_url.GetOrigin() == document_url.GetOrigin())) { + // Note: The client detects if the document was not loaded using HTTP GET + // and invokes SelectCache without a manifest url, so that detection step + // is also skipped here. See WebApplicationCacheHostImpl.cc new_master_entry_url_ = document_url; LoadOrCreateGroup(manifest_url); return; @@ -161,10 +173,11 @@ AppCacheRequestHandler* AppCacheHost::CreateRequestHandler( URLRequest* request, bool is_main_request) { if (is_main_request) - return new AppCacheRequestHandler(this); + return new AppCacheRequestHandler(this, true); - if (associated_cache() && associated_cache()->is_complete()) - return new AppCacheRequestHandler(associated_cache()); + if ((associated_cache() && associated_cache()->is_complete()) || + is_selection_pending()) + return new AppCacheRequestHandler(this, false); return NULL; } @@ -240,6 +253,8 @@ void AppCacheHost::FinishCacheSelection( DoPendingStartUpdate(); else if (pending_swap_cache_callback_) DoPendingSwapCache(); + + FOR_EACH_OBSERVER(Observer, observers_, OnCacheSelectionComplete(this)); } void AppCacheHost::AssociateCache(AppCache* cache) { diff --git a/webkit/appcache/appcache_host.h b/webkit/appcache/appcache_host.h index d8ee843..9b7db30 100644 --- a/webkit/appcache/appcache_host.h +++ b/webkit/appcache/appcache_host.h @@ -5,6 +5,7 @@ #ifndef WEBKIT_APPCACHE_APPCACHE_HOST_H_ #define WEBKIT_APPCACHE_APPCACHE_HOST_H_ +#include "base/observer_list.h" #include "base/ref_counted.h" #include "base/task.h" #include "base/weak_ptr.h" @@ -31,10 +32,27 @@ typedef Callback2<bool, void*>::Type SwapCacheCallback; class AppCacheHost : public base::SupportsWeakPtr<AppCacheHost>, public AppCacheService::LoadClient { public: + + class Observer { + public: + // Called just after the cache selection algorithm completes. + virtual void OnCacheSelectionComplete(AppCacheHost* host) = 0; + + // Called just prior to the instance being deleted. + virtual void OnDestructionImminent(AppCacheHost* host) = 0; + + virtual ~Observer() {} + }; + AppCacheHost(int host_id, AppCacheFrontend* frontend, AppCacheService* service); ~AppCacheHost(); + // Adds/removes an observer, the AppCacheHost does not take + // ownership of the observer. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + // Support for cache selection and scriptable method calls. void SelectCache(const GURL& document_url, const int64 cache_document_was_loaded_from, @@ -118,6 +136,9 @@ class AppCacheHost : public base::SupportsWeakPtr<AppCacheHost>, SwapCacheCallback* pending_swap_cache_callback_; void* pending_callback_param_; + // List of objects observing us. + ObserverList<Observer> observers_; + FRIEND_TEST(AppCacheTest, CleanupUnusedCache); FRIEND_TEST(AppCacheGroupTest, CleanupUnusedGroup); FRIEND_TEST(AppCacheHostTest, Basic); diff --git a/webkit/appcache/appcache_interfaces.cc b/webkit/appcache/appcache_interfaces.cc index bd73879..1b7681f 100644 --- a/webkit/appcache/appcache_interfaces.cc +++ b/webkit/appcache/appcache_interfaces.cc @@ -3,15 +3,39 @@ // found in the LICENSE file. #include "webkit/appcache/appcache_interfaces.h" + +#include "googleurl/src/gurl.h" +#include "net/url_request/url_request.h" #include "webkit/api/public/WebApplicationCacheHost.h" using WebKit::WebApplicationCacheHost; namespace appcache { +const char kHttpScheme[] = "http"; +const char kHttpsScheme[] = "https"; +const char kHttpGETMethod[] = "GET"; +const char kHttpHEADMethod[] = "HEAD"; + +bool IsSchemeSupported(const GURL& url) { + bool supported = url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme); +#ifndef NDEBUG + supported |= url.SchemeIsFile(); +#endif + return supported; +} + +bool IsMethodSupported(const std::string& method) { + return (method == kHttpGETMethod) || (method == kHttpHEADMethod); +} + +bool IsSchemeAndMethodSupported(const URLRequest* request) { + return IsSchemeSupported(request->url()) && + IsMethodSupported(request->method()); +} + // Ensure that enum values never get out of sync with the // ones declared for use within the WebKit api - COMPILE_ASSERT((int)WebApplicationCacheHost::Uncached == (int)UNCACHED, Uncached); COMPILE_ASSERT((int)WebApplicationCacheHost::Idle == diff --git a/webkit/appcache/appcache_interfaces.h b/webkit/appcache/appcache_interfaces.h index ee63633..27d8a15 100644 --- a/webkit/appcache/appcache_interfaces.h +++ b/webkit/appcache/appcache_interfaces.h @@ -5,10 +5,12 @@ #ifndef WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ #define WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ +#include <string> #include <vector> #include "base/basictypes.h" class GURL; +class URLRequest; namespace appcache { @@ -70,6 +72,19 @@ class AppCacheBackend { virtual ~AppCacheBackend() {} }; +// Useful string constants. +// Note: These are also defined elsewhere in the chrome code base in +// url_contants.h .cc, however the appcache library doesn't not have +// any dependencies on the chrome library, so we can't use them in here. +extern const char kHttpScheme[]; +extern const char kHttpsScheme[]; +extern const char kHttpGETMethod[]; +extern const char kHttpHEADMethod[]; + +bool IsSchemeSupported(const GURL& url); +bool IsMethodSupported(const std::string& method); +bool IsSchemeAndMethodSupported(const URLRequest* request); + } // namespace #endif // WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ diff --git a/webkit/appcache/appcache_request_handler.cc b/webkit/appcache/appcache_request_handler.cc index 322e8bc..614c12e 100644 --- a/webkit/appcache/appcache_request_handler.cc +++ b/webkit/appcache/appcache_request_handler.cc @@ -12,18 +12,16 @@ namespace appcache { // AppCacheRequestHandler ----------------------------------------------------- -static bool IsHttpOrHttpsGetOrEquivalent(URLRequest* request) { - return false; // TODO(michaeln): write me +AppCacheRequestHandler::AppCacheRequestHandler(AppCacheHost* host, + bool is_main_resource) + : is_main_request_(is_main_resource), host_(host) { + DCHECK(host_); + host_->AddObserver(this); } -AppCacheRequestHandler::AppCacheRequestHandler(AppCacheHost* host) - : is_main_request_(true), cache_id_(kNoCacheId), - host_(host->AsWeakPtr()), service_(host->service()) { -} - -AppCacheRequestHandler::AppCacheRequestHandler(AppCache* cache) - : is_main_request_(false), cache_id_(kNoCacheId), - cache_(cache), service_(cache->service()) { +AppCacheRequestHandler::~AppCacheRequestHandler() { + if (host_) + host_->RemoveObserver(this); } void AppCacheRequestHandler::GetExtraResponseInfo( @@ -37,7 +35,10 @@ void AppCacheRequestHandler::GetExtraResponseInfo( } URLRequestJob* AppCacheRequestHandler::MaybeLoadResource(URLRequest* request) { - if (!IsHttpOrHttpsGetOrEquivalent(request)) + // 6.9.7 Changes to the networking model + // If the resource is not to be fetched using the HTTP GET mechanism or + // equivalent ... then fetch the resource normally + if (!host_ || !IsSchemeAndMethodSupported(request)) return NULL; // TODO(michaeln): write me return NULL; @@ -45,7 +46,7 @@ URLRequestJob* AppCacheRequestHandler::MaybeLoadResource(URLRequest* request) { URLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( URLRequest* request, const GURL& location) { - if (!IsHttpOrHttpsGetOrEquivalent(request)) + if (!host_ || !IsSchemeAndMethodSupported(request)) return NULL; // TODO(michaeln): write me return NULL; @@ -53,11 +54,21 @@ URLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( URLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( URLRequest* request) { - if (!IsHttpOrHttpsGetOrEquivalent(request)) + if (!host_ || !IsSchemeAndMethodSupported(request)) return NULL; // TODO(michaeln): write me return NULL; } +void AppCacheRequestHandler::OnCacheSelectionComplete(AppCacheHost* host) { + DCHECK(host == host_); + // TODO(michaeln): write me +} + +void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { + host_ = NULL; + // TODO(michaeln): write me +} + } // namespace appcache diff --git a/webkit/appcache/appcache_request_handler.h b/webkit/appcache/appcache_request_handler.h index 78fe9c3..d848f08 100644 --- a/webkit/appcache/appcache_request_handler.h +++ b/webkit/appcache/appcache_request_handler.h @@ -18,8 +18,11 @@ namespace appcache { // given the opportunity to hijack the request along the way. Callers // should use AppCacheHost::CreateRequestHandler to manufacture instances // that can retrieve resources for a particular host. -class AppCacheRequestHandler : public URLRequest::UserData { +class AppCacheRequestHandler : public URLRequest::UserData, + public AppCacheHost::Observer { public: + virtual ~AppCacheRequestHandler(); + // Should be called on each request intercept opportunity. URLRequestJob* MaybeLoadResource(URLRequest* request); URLRequestJob* MaybeLoadFallbackForRedirect(URLRequest* request, @@ -31,20 +34,19 @@ class AppCacheRequestHandler : public URLRequest::UserData { private: friend class AppCacheHost; - // Ctor for main resource loads. - explicit AppCacheRequestHandler(AppCacheHost* host); + // Callers should use AppCacheHost::CreateRequestHandler. + AppCacheRequestHandler(AppCacheHost* host, bool is_main_resource); - // Ctor for subresource loads when the cache is loaded. - explicit AppCacheRequestHandler(AppCache* cache); + // AppCacheHost::Observer methods + virtual void OnCacheSelectionComplete(AppCacheHost* host); + virtual void OnDestructionImminent(AppCacheHost* host); // Main vs subresource loads are very different. // TODO(michaeln): maybe have two derived classes? bool is_main_request_; - int64 cache_id_; + AppCacheHost* host_; scoped_refptr<AppCache> cache_; - base::WeakPtr<AppCacheHost> host_; scoped_refptr<URLRequestJob> job_; - AppCacheService* service_; }; } // namespace appcache diff --git a/webkit/appcache/web_application_cache_host_impl.cc b/webkit/appcache/web_application_cache_host_impl.cc index dfba39b..96c8cbf 100644 --- a/webkit/appcache/web_application_cache_host_impl.cc +++ b/webkit/appcache/web_application_cache_host_impl.cc @@ -6,6 +6,7 @@ #include "base/compiler_specific.h" #include "base/id_map.h" +#include "base/string_util.h" #include "webkit/api/public/WebURL.h" #include "webkit/api/public/WebURLRequest.h" #include "webkit/api/public/WebURLResponse.h" @@ -34,8 +35,9 @@ WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( status_(UNCACHED), has_cached_status_(false), cached_status_(UNCACHED), - is_in_http_family_(false), - should_capture_main_response_(MAYBE) { + is_scheme_supported_(false), + is_get_method_(false), + is_new_master_entry_(MAYBE) { DCHECK(client && backend && (host_id_ != kNoHostId)); backend_->RegisterHost(host_id_); @@ -64,6 +66,9 @@ void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { void WebApplicationCacheHostImpl::willStartMainResourceRequest( WebURLRequest& request) { request.setAppCacheHostID(host_id_); + std::string method = request.httpMethod().utf8(); + is_get_method_ = (method == kHttpGETMethod); + DCHECK(method == StringToUpperASCII(method)); } void WebApplicationCacheHostImpl::willStartSubResourceRequest( @@ -76,9 +81,9 @@ void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { // since we're now selecting a new cache. has_status_ = false; has_cached_status_ = false; - should_capture_main_response_ = NO; - backend_->SelectCache(host_id_, main_response_url_, - main_response_.appCacheID(), + is_new_master_entry_ = NO; + backend_->SelectCache(host_id_, document_url_, + document_response_.appCacheID(), GURL()); } @@ -96,52 +101,60 @@ bool WebApplicationCacheHostImpl::selectCacheWithManifest( manifest_gurl = manifest_gurl.ReplaceComponents(replacements); } + // 6.9.6 The application cache selection algorithm // Check for new 'master' entries. - if (main_response_.appCacheID() == kNoCacheId) { - should_capture_main_response_ = is_in_http_family_ ? YES : NO; - backend_->SelectCache(host_id_, main_response_url_, + if (document_response_.appCacheID() == kNoCacheId) { + if (is_scheme_supported_ && is_get_method_ && + (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { + is_new_master_entry_ = YES; + } else { + is_new_master_entry_ = NO; + manifest_gurl = GURL::EmptyGURL(); + } + backend_->SelectCache(host_id_, document_url_, kNoCacheId, manifest_gurl); return true; } - DCHECK(should_capture_main_response_ == NO); + DCHECK(is_new_master_entry_ = NO); + // 6.9.6 The application cache selection algorithm // Check for 'foreign' entries. - GURL main_response_manifest_gurl(main_response_.appCacheManifestURL()); - if (main_response_manifest_gurl != manifest_gurl) { - backend_->MarkAsForeignEntry(host_id_, main_response_url_, - main_response_.appCacheID()); + GURL document_manifest_gurl(document_response_.appCacheManifestURL()); + if (document_manifest_gurl != manifest_gurl) { + backend_->MarkAsForeignEntry(host_id_, document_url_, + document_response_.appCacheID()); has_cached_status_ = true; cached_status_ = UNCACHED; return false; // the navigation will be restarted } // Its a 'master' entry thats already in the cache. - backend_->SelectCache(host_id_, main_response_url_, - main_response_.appCacheID(), + backend_->SelectCache(host_id_, document_url_, + document_response_.appCacheID(), manifest_gurl); return true; } void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( const WebURLResponse& response) { - main_response_ = response; - main_response_url_ = main_response_.url(); - is_in_http_family_ = main_response_url_.SchemeIs("http") || - main_response_url_.SchemeIs("https"); - if ((main_response_.appCacheID() != kNoCacheId) || !is_in_http_family_) - should_capture_main_response_ = NO; + document_response_ = response; + document_url_ = document_response_.url(); + is_scheme_supported_ = IsSchemeSupported(document_url_); + if ((document_response_.appCacheID() != kNoCacheId) || + !is_scheme_supported_ || !is_get_method_) + is_new_master_entry_ = NO; } void WebApplicationCacheHostImpl::didReceiveDataForMainResource( const char* data, int len) { - if (should_capture_main_response_ == NO) + if (is_new_master_entry_ == NO) return; // TODO(michaeln): write me } void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { - if (should_capture_main_response_ == NO) + if (is_new_master_entry_ == NO) return; // TODO(michaeln): write me } diff --git a/webkit/appcache/web_application_cache_host_impl.h b/webkit/appcache/web_application_cache_host_impl.h index dbc00f1..1926667 100644 --- a/webkit/appcache/web_application_cache_host_impl.h +++ b/webkit/appcache/web_application_cache_host_impl.h @@ -40,7 +40,7 @@ class WebApplicationCacheHostImpl : public WebKit::WebApplicationCacheHost { virtual bool swapCache(); private: - enum ShouldCaptureMainResponse { + enum IsNewMasterEntry { MAYBE, YES, NO @@ -53,10 +53,11 @@ class WebApplicationCacheHostImpl : public WebKit::WebApplicationCacheHost { appcache::Status status_; bool has_cached_status_; appcache::Status cached_status_; - WebKit::WebURLResponse main_response_; - GURL main_response_url_; - bool is_in_http_family_; - ShouldCaptureMainResponse should_capture_main_response_; + WebKit::WebURLResponse document_response_; + GURL document_url_; + bool is_scheme_supported_; + bool is_get_method_; + IsNewMasterEntry is_new_master_entry_; }; } // namespace diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index c7dbce7..5f843e5 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -1223,7 +1223,7 @@ 'type': '<(library)', 'msvs_guid': '0B945915-31A7-4A07-A5B5-568D737A39B1', 'dependencies': [ - '../build/temp_gyp/googleurl.gyp:googleurl', + '../net/net.gyp:net', 'webkit', ], 'sources': [ |