summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-18 01:05:09 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-18 01:05:09 +0000
commit7e8e3dd7b1633874650f8de9a818aca8cb594f5b (patch)
tree5a973e64a1b5ca1a243744e2a9aa4a336a699985 /webkit
parent8b2034f851b1b41c2ec6539c057b63c92ef7289c (diff)
downloadchromium_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.cc25
-rw-r--r--webkit/appcache/appcache_host.h21
-rw-r--r--webkit/appcache/appcache_interfaces.cc26
-rw-r--r--webkit/appcache/appcache_interfaces.h15
-rw-r--r--webkit/appcache/appcache_request_handler.cc37
-rw-r--r--webkit/appcache/appcache_request_handler.h18
-rw-r--r--webkit/appcache/web_application_cache_host_impl.cc59
-rw-r--r--webkit/appcache/web_application_cache_host_impl.h11
-rw-r--r--webkit/webkit.gyp2
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': [