Commit 9e89338a authored by kalman@chromium.org's avatar kalman@chromium.org

Extension Settings API: throttle the API in the same way that the Bookmarks API

is throttled.


BUG=98498
TEST=*ExtensionSettings*


Review URL: http://codereview.chromium.org/8491033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110854 0039d316-1c4b-4281-b951-d872f2087c98
parent 454a0c41
...@@ -152,7 +152,7 @@ class RemoveBookmarkFunction : public BookmarksFunction { ...@@ -152,7 +152,7 @@ class RemoveBookmarkFunction : public BookmarksFunction {
// BookmarksFunction: // BookmarksFunction:
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const; QuotaLimitHeuristics* heuristics) const OVERRIDE;
private: private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.remove") DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.remove")
...@@ -165,7 +165,7 @@ class RemoveTreeBookmarkFunction : public RemoveBookmarkFunction { ...@@ -165,7 +165,7 @@ class RemoveTreeBookmarkFunction : public RemoveBookmarkFunction {
class CreateBookmarkFunction : public BookmarksFunction { class CreateBookmarkFunction : public BookmarksFunction {
public: public:
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const; QuotaLimitHeuristics* heuristics) const OVERRIDE;
// BookmarksFunction: // BookmarksFunction:
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
...@@ -178,7 +178,7 @@ class MoveBookmarkFunction : public BookmarksFunction { ...@@ -178,7 +178,7 @@ class MoveBookmarkFunction : public BookmarksFunction {
static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids, static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids,
bool* invalid_id); bool* invalid_id);
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const; QuotaLimitHeuristics* heuristics) const OVERRIDE;
// BookmarksFunction: // BookmarksFunction:
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
...@@ -191,7 +191,7 @@ class UpdateBookmarkFunction : public BookmarksFunction { ...@@ -191,7 +191,7 @@ class UpdateBookmarkFunction : public BookmarksFunction {
static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids, static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids,
bool* invalid_id); bool* invalid_id);
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const; QuotaLimitHeuristics* heuristics) const OVERRIDE;
virtual bool RunImpl(); virtual bool RunImpl();
private: private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.update") DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.update")
......
...@@ -82,7 +82,7 @@ class ExtensionFunction ...@@ -82,7 +82,7 @@ class ExtensionFunction
// Returns a quota limit heuristic suitable for this function. // Returns a quota limit heuristic suitable for this function.
// No quota limiting by default. // No quota limiting by default.
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const {} QuotaLimitHeuristics* heuristics) const {}
// Called when the quota limit has been exceeded. The default implementation // Called when the quota limit has been exceeded. The default implementation
// returns an error. // returns an error.
......
...@@ -1602,7 +1602,7 @@ bool WebRequestHandlerBehaviorChanged::RunImpl() { ...@@ -1602,7 +1602,7 @@ bool WebRequestHandlerBehaviorChanged::RunImpl() {
} }
void WebRequestHandlerBehaviorChanged::GetQuotaLimitHeuristics( void WebRequestHandlerBehaviorChanged::GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const { QuotaLimitHeuristics* heuristics) const {
QuotaLimitHeuristic::Config config = { QuotaLimitHeuristic::Config config = {
20, // Refill 20 tokens per interval. 20, // Refill 20 tokens per interval.
base::TimeDelta::FromMinutes(10) // 10 minutes refill interval. base::TimeDelta::FromMinutes(10) // 10 minutes refill interval.
......
...@@ -360,7 +360,7 @@ class WebRequestHandlerBehaviorChanged : public SyncIOThreadExtensionFunction { ...@@ -360,7 +360,7 @@ class WebRequestHandlerBehaviorChanged : public SyncIOThreadExtensionFunction {
private: private:
virtual void GetQuotaLimitHeuristics( virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const OVERRIDE; QuotaLimitHeuristics* heuristics) const OVERRIDE;
// Handle quota exceeded gracefully: Only warn the user but still execute the // Handle quota exceeded gracefully: Only warn the user but still execute the
// function. // function.
virtual void OnQuotaExceeded() OVERRIDE; virtual void OnQuotaExceeded() OVERRIDE;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/extensions/settings/settings_api.h"
#include "chrome/browser/extensions/settings/settings_frontend.h" #include "chrome/browser/extensions/settings/settings_frontend.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -77,9 +79,10 @@ bool SettingsFunction::UseWriteResult( ...@@ -77,9 +79,10 @@ bool SettingsFunction::UseWriteResult(
// Concrete settings functions // Concrete settings functions
namespace {
// Adds all StringValues from a ListValue to a vector of strings. // Adds all StringValues from a ListValue to a vector of strings.
static void AddAllStringValues( void AddAllStringValues(const ListValue& from, std::vector<std::string>* to) {
const ListValue& from, std::vector<std::string>* to) {
DCHECK(to->empty()); DCHECK(to->empty());
std::string as_string; std::string as_string;
for (ListValue::const_iterator it = from.begin(); it != from.end(); ++it) { for (ListValue::const_iterator it = from.begin(); it != from.end(); ++it) {
...@@ -90,7 +93,7 @@ static void AddAllStringValues( ...@@ -90,7 +93,7 @@ static void AddAllStringValues(
} }
// Gets the keys of a DictionaryValue. // Gets the keys of a DictionaryValue.
static std::vector<std::string> GetKeys(const DictionaryValue& dict) { std::vector<std::string> GetKeys(const DictionaryValue& dict) {
std::vector<std::string> keys; std::vector<std::string> keys;
for (DictionaryValue::key_iterator it = dict.begin_keys(); for (DictionaryValue::key_iterator it = dict.begin_keys();
it != dict.end_keys(); ++it) { it != dict.end_keys(); ++it) {
...@@ -99,6 +102,32 @@ static std::vector<std::string> GetKeys(const DictionaryValue& dict) { ...@@ -99,6 +102,32 @@ static std::vector<std::string> GetKeys(const DictionaryValue& dict) {
return keys; return keys;
} }
// Creates quota heuristics for settings modification.
static void GetModificationQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) {
// A max of 1000 operations per hour.
QuotaLimitHeuristic::Config longLimitConfig = {
1000,
base::TimeDelta::FromHours(1)
};
heuristics->push_back(
new ExtensionsQuotaService::TimedLimit(
longLimitConfig, new QuotaLimitHeuristic::SingletonBucketMapper()));
// A max of 10 operations per minute, sustained over 10 minutes.
QuotaLimitHeuristic::Config shortLimitConfig = {
10,
base::TimeDelta::FromMinutes(1)
};
heuristics->push_back(
new ExtensionsQuotaService::SustainedLimit(
base::TimeDelta::FromMinutes(10),
shortLimitConfig,
new QuotaLimitHeuristic::SingletonBucketMapper()));
};
} // namespace
bool GetSettingsFunction::RunWithStorage( bool GetSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) { SettingsStorage* storage) {
...@@ -152,6 +181,11 @@ bool SetSettingsFunction::RunWithStorage( ...@@ -152,6 +181,11 @@ bool SetSettingsFunction::RunWithStorage(
observers, storage->Set(SettingsStorage::DEFAULTS, *input)); observers, storage->Set(SettingsStorage::DEFAULTS, *input));
} }
void SetSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
bool RemoveSettingsFunction::RunWithStorage( bool RemoveSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) { SettingsStorage* storage) {
...@@ -179,6 +213,11 @@ bool RemoveSettingsFunction::RunWithStorage( ...@@ -179,6 +213,11 @@ bool RemoveSettingsFunction::RunWithStorage(
}; };
} }
void RemoveSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
bool ClearSettingsFunction::RunWithStorage( bool ClearSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) { SettingsStorage* storage) {
...@@ -186,4 +225,9 @@ bool ClearSettingsFunction::RunWithStorage( ...@@ -186,4 +225,9 @@ bool ClearSettingsFunction::RunWithStorage(
return UseWriteResult(observers, storage->Clear()); return UseWriteResult(observers, storage->Clear());
} }
void ClearSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
} // namespace extensions } // namespace extensions
...@@ -66,6 +66,9 @@ class SetSettingsFunction : public SettingsFunction { ...@@ -66,6 +66,9 @@ class SetSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage( virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE; SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
}; };
class RemoveSettingsFunction : public SettingsFunction { class RemoveSettingsFunction : public SettingsFunction {
...@@ -76,6 +79,9 @@ class RemoveSettingsFunction : public SettingsFunction { ...@@ -76,6 +79,9 @@ class RemoveSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage( virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE; SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
}; };
class ClearSettingsFunction : public SettingsFunction { class ClearSettingsFunction : public SettingsFunction {
...@@ -86,6 +92,9 @@ class ClearSettingsFunction : public SettingsFunction { ...@@ -86,6 +92,9 @@ class ClearSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage( virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers, scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE; SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
}; };
} // namespace extensions } // namespace extensions
......
...@@ -285,6 +285,21 @@ chrome.test.runTests([ ...@@ -285,6 +285,21 @@ chrome.test.runTests([
succeed(); succeed();
} }
stage0(); stage0();
},
function throttling() {
// Should get throttled after 1000 calls.
var maxRequests = 1001;
function next() {
chrome.experimental.settings.clear((--maxRequests > 0) ? next : done);
}
function done() {
chrome.test.assertEq(
"This request exceeds available quota.",
chrome.extension.lastError.message);
succeed();
}
chrome.experimental.settings.clear(next);
} }
]); ]);
</script> </script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment