diff options
Diffstat (limited to 'chrome/browser/history/web_history_service.cc')
-rw-r--r-- | chrome/browser/history/web_history_service.cc | 128 |
1 files changed, 104 insertions, 24 deletions
diff --git a/chrome/browser/history/web_history_service.cc b/chrome/browser/history/web_history_service.cc index fc4882e..42d177c 100644 --- a/chrome/browser/history/web_history_service.cc +++ b/chrome/browser/history/web_history_service.cc @@ -4,7 +4,10 @@ #include "chrome/browser/history/web_history_service.h" +#include "base/bind.h" #include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/string_number_conversions.h" #include "base/values.h" #include "chrome/browser/signin/oauth2_token_service.h" #include "chrome/browser/signin/oauth2_token_service_factory.h" @@ -23,9 +26,14 @@ namespace { const char kHistoryOAuthScope[] = "https://www.googleapis.com/auth/chromesync"; -const char kHistoryGetHistoryUrl[] = +const char kHistoryQueryHistoryUrl[] = "https://history.google.com/history/api/lookup?client=chrome"; +const char kHistoryDeleteHistoryUrl[] = + "https://history.google.com/history/api/delete?client=chrome"; + +const char kPostDataMimeType[] = "text/plain"; + // The maximum number of retries for the URLFetcher requests. const size_t kMaxRetries = 1; @@ -36,13 +44,25 @@ class RequestImpl : public WebHistoryService::Request, virtual ~RequestImpl() { } + // Returns the response code received from the server, which will only be + // valid if the request succeeded. + int response_code() { return response_code_; } + + // Returns the contents of the response body received from the server. + const std::string& response_body() { return response_body_; } + private: friend class history::WebHistoryService; + typedef base::Callback<void(Request*, bool)> CompletionCallback; + RequestImpl(Profile* profile, const std::string& url, - const WebHistoryService::QueryWebHistoryCallback& callback) - : profile_(profile), url_(GURL(url)), query_history_callback_(callback) { + const CompletionCallback& callback) + : profile_(profile), + url_(GURL(url)), + response_code_(0), + callback_(callback) { } // Tells the request to do its thang. @@ -58,20 +78,10 @@ class RequestImpl : public WebHistoryService::Request, // content::URLFetcherDelegate interface. virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { DCHECK_EQ(source, url_fetcher_.get()); - std::string result_body; - int response_code = url_fetcher_->GetResponseCode(); - url_fetcher_->GetResponseAsString(&result_body); + response_code_ = url_fetcher_->GetResponseCode(); + url_fetcher_->GetResponseAsString(&response_body_); url_fetcher_.reset(); - - if (response_code == net::HTTP_OK) { - scoped_ptr<base::Value> value(base::JSONReader::Read(result_body)); - if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) { - query_history_callback_.Run(this, - static_cast<DictionaryValue*>(value.get())); - return; - } - } - query_history_callback_.Run(this, NULL); + callback_.Run(this, true); } // OAuth2TokenService::Consumer interface. @@ -92,43 +102,74 @@ class RequestImpl : public WebHistoryService::Request, const GoogleServiceAuthError& error) OVERRIDE { token_request_.reset(); LOG(WARNING) << "Failed to get OAuth token: " << error.ToString(); - query_history_callback_.Run(this, NULL); + callback_.Run(this, false); } // Helper for creating a new URLFetcher for the API request. net::URLFetcher* CreateUrlFetcher(const std::string& access_token) { + net::URLFetcher::RequestType request_type = post_data_.empty() ? + net::URLFetcher::GET : net::URLFetcher::POST; net::URLFetcher* fetcher = net::URLFetcher::Create( - url_, net::URLFetcher::GET, this); + url_, request_type, this); fetcher->SetRequestContext(profile_->GetRequestContext()); fetcher->SetMaxRetriesOn5xx(kMaxRetries); fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); fetcher->AddExtraRequestHeader("Authorization: Bearer " + access_token); + if (request_type == net::URLFetcher::POST) + fetcher->SetUploadData(kPostDataMimeType, post_data_); return fetcher; } + void set_post_data(const std::string& post_data) { + post_data_ = post_data; + } + Profile* profile_; // The URL of the API endpoint. GURL url_; + // POST data to be sent with the request (may be empty). + std::string post_data_; + // The OAuth2 access token request. scoped_ptr<OAuth2TokenService::Request> token_request_; // Handles the actual API requests after the OAuth token is acquired. scoped_ptr<net::URLFetcher> url_fetcher_; - // The callback to execute when the query is complete, whether successful - // or not. - WebHistoryService::QueryWebHistoryCallback query_history_callback_; + // Holds the response code received from the server. + int response_code_; + + // Holds the response body received from the server. + std::string response_body_; + + // The callback to execute when the query is complete. + CompletionCallback callback_; }; +// Called when a query to web history has completed, successfully or not. +void QueryHistoryCompletionCallback( + const WebHistoryService::QueryWebHistoryCallback& callback, + WebHistoryService::Request* request, + bool success) { + RequestImpl* request_impl = static_cast<RequestImpl*>(request); + if (success && request_impl->response_code() == net::HTTP_OK) { + scoped_ptr<base::Value> value( + base::JSONReader::Read(request_impl->response_body())); + if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) + callback.Run(request, static_cast<DictionaryValue*>(value.get())); + } + callback.Run(request, NULL); +} + } // namespace -WebHistoryService::Request::~Request() { +WebHistoryService::Request::Request() { } -WebHistoryService::Request::Request() { +WebHistoryService::Request::~Request() { } WebHistoryService::WebHistoryService(Profile* profile) @@ -142,8 +183,47 @@ scoped_ptr<WebHistoryService::Request> WebHistoryService::QueryHistory( const string16& text_query, const QueryOptions& options, const WebHistoryService::QueryWebHistoryCallback& callback) { + // Wrap the original callback into a generic completion callback. + RequestImpl::CompletionCallback completion_callback = base::Bind( + &QueryHistoryCompletionCallback, callback); + + scoped_ptr<RequestImpl> request( + new RequestImpl(profile_, kHistoryQueryHistoryUrl, completion_callback)); + request->Start(); + return request.PassAs<Request>(); +} + +scoped_ptr<WebHistoryService::Request> WebHistoryService::ExpireHistoryBetween( + const std::set<GURL>& urls, + base::Time begin_time, + base::Time end_time, + const WebHistoryService::ExpireWebHistoryCallback& callback) { + + // Determine the timestamps representing the beginning and end of the day. + std::string min_timestamp(base::Int64ToString( + (begin_time - base::Time::FromJsTime(0)).InMicroseconds())); + std::string max_timestamp(base::Int64ToString( + (end_time - base::Time::FromJsTime(0)).InMicroseconds())); + + DictionaryValue delete_request; + ListValue* deletions = new ListValue; + delete_request.Set("del", deletions); + + for (std::set<GURL>::const_iterator it = urls.begin(); + it != urls.end(); ++it) { + DictionaryValue* deletion = new DictionaryValue; + deletion->SetString("type", "CHROME_HISTORY"); + deletion->SetString("url", it->spec()); + deletion->SetString("min_timestamp_usec", min_timestamp); + deletion->SetString("max_timestamp_usec", max_timestamp); + deletions->Append(deletion); + } + std::string post_data; + base::JSONWriter::Write(&delete_request, &post_data); + scoped_ptr<RequestImpl> request( - new RequestImpl(profile_, kHistoryGetHistoryUrl, callback)); + new RequestImpl(profile_, kHistoryDeleteHistoryUrl, callback)); + request->set_post_data(post_data); request->Start(); return request.PassAs<Request>(); } |