Commit b981293d authored by estade@chromium.org's avatar estade@chromium.org

[rAc - libaddressinput] Chrome downloader impl

based on https://codereview.chromium.org/96323002/ by Dan Beam

BUG=317838

Review URL: https://codereview.chromium.org/127223003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244003 0039d316-1c4b-4281-b951-d872f2087c98
parent dc9abbb8
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/libaddressinput/chromium/chrome_downloader_impl.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
ChromeDownloaderImpl::ChromeDownloaderImpl(net::URLRequestContextGetter* getter)
: getter_(getter) {}
ChromeDownloaderImpl::~ChromeDownloaderImpl() {
STLDeleteContainerPairPointers(requests_.begin(), requests_.end());
}
void ChromeDownloaderImpl::Download(
const std::string& url,
scoped_ptr<Callback> downloaded) {
net::URLFetcher* fetcher =
net::URLFetcher::Create(GURL(url), net::URLFetcher::GET, this);
fetcher->SetLoadFlags(
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
fetcher->SetRequestContext(getter_);
requests_[fetcher] = new Request(url, downloaded.Pass());
fetcher->Start();
}
void ChromeDownloaderImpl::OnURLFetchComplete(const net::URLFetcher* source) {
std::map<const net::URLFetcher*, Request*>::iterator request =
requests_.find(source);
DCHECK(request != requests_.end());
bool ok = source->GetResponseCode() == net::HTTP_OK;
std::string data;
if (ok)
source->GetResponseAsString(&data);
(*request->second->callback)(ok, request->second->url, data);
delete request->first;
delete request->second;
requests_.erase(request);
}
ChromeDownloaderImpl::Request::Request(const std::string& url,
scoped_ptr<Callback> callback)
: url(url),
callback(callback.Pass()) {}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_DOWNLOADER_IMPL_H_
#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_DOWNLOADER_IMPL_H_
#include <map>
#include <string>
#include "base/memory/scoped_vector.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/downloader.h"
namespace net {
class URLFetcher;
class URLRequestContextGetter;
}
// A class for downloading rules to let libaddressinput validate international
// addresses.
class ChromeDownloaderImpl : public i18n::addressinput::Downloader,
public net::URLFetcherDelegate {
public:
explicit ChromeDownloaderImpl(net::URLRequestContextGetter* getter);
virtual ~ChromeDownloaderImpl();
// i18n::addressinput::Downloader:
virtual void Download(const std::string& url,
scoped_ptr<Callback> downloaded) OVERRIDE;
// net::URLFetcherDelegate:
virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
private:
struct Request {
Request(const std::string& url, scoped_ptr<Callback> callback);
std::string url;
scoped_ptr<Callback> callback;
};
net::URLRequestContextGetter* const getter_; // weak
// Maps from active url fetcher to request metadata. Both the key and value
// are owned.
std::map<const net::URLFetcher*, Request*> requests_;
DISALLOW_COPY_AND_ASSIGN(ChromeDownloaderImpl);
};
#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_DOWNLOADER_IMPL_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/libaddressinput/chromium/chrome_downloader_impl.h"
#include "base/message_loop/message_loop_proxy.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
static const char kFakeUrl[] = "http://example.com";
class ChromeDownloaderImplTest : public testing::Test {
public:
ChromeDownloaderImplTest()
: success_(false),
fake_factory_(&factory_) {}
virtual ~ChromeDownloaderImplTest() {}
protected:
// Sets the response for the download.
void SetFakeResponse(const std::string& payload, net::HttpStatusCode code) {
fake_factory_.SetFakeResponse(GURL(kFakeUrl),
payload,
code,
net::URLRequestStatus::SUCCESS);
}
// Kicks off the download.
void Download() {
net::TestURLRequestContextGetter* getter =
new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
ChromeDownloaderImpl impl(getter);
impl.Download(kFakeUrl, BuildCallback());
base::MessageLoop::current()->RunUntilIdle();
}
const std::string& data() { return data_; }
bool success() { return success_; }
private:
scoped_ptr<ChromeDownloaderImpl::Callback> BuildCallback() {
return ::i18n::addressinput::BuildCallback(
this, &ChromeDownloaderImplTest::OnDownloaded);
}
// Callback for when download is finished.
void OnDownloaded(bool success,
const std::string& url,
const std::string& data) {
success_ = success;
data_ = data;
}
base::MessageLoop loop_;
net::URLFetcherImplFactory factory_;
net::FakeURLFetcherFactory fake_factory_;
std::string data_;
bool success_;
};
TEST_F(ChromeDownloaderImplTest, Success) {
const char kFakePayload[] = "ham hock";
SetFakeResponse(kFakePayload, net::HTTP_OK);
Download();
EXPECT_TRUE(success());
EXPECT_EQ(kFakePayload, data());
}
TEST_F(ChromeDownloaderImplTest, Failure) {
const char kFakePayload[] = "ham hock";
SetFakeResponse(kFakePayload, net::HTTP_INTERNAL_SERVER_ERROR);
Download();
EXPECT_FALSE(success());
EXPECT_EQ(std::string(), data());
}
...@@ -9,8 +9,7 @@ ...@@ -9,8 +9,7 @@
#include "base/prefs/value_map_pref_store.h" #include "base/prefs/value_map_pref_store.h"
#include "cpp/test/storage_test_runner.h" #include "cpp/test/storage_test_runner.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/callback.h"
namespace {
// Tests for ChromeStorageImpl object. // Tests for ChromeStorageImpl object.
class ChromeStorageImplTest : public testing::Test { class ChromeStorageImplTest : public testing::Test {
...@@ -30,5 +29,3 @@ class ChromeStorageImplTest : public testing::Test { ...@@ -30,5 +29,3 @@ class ChromeStorageImplTest : public testing::Test {
TEST_F(ChromeStorageImplTest, StandardStorageTests) { TEST_F(ChromeStorageImplTest, StandardStorageTests) {
EXPECT_NO_FATAL_FAILURE(runner_.RunAllTests()); EXPECT_NO_FATAL_FAILURE(runner_.RunAllTests());
} }
} // namespace
...@@ -88,7 +88,7 @@ class AddressValidator { ...@@ -88,7 +88,7 @@ class AddressValidator {
// which cannot be NULL. Does not take ownership of |load_rules_delegate|, // which cannot be NULL. Does not take ownership of |load_rules_delegate|,
// which can be NULL. The caller owns the result. // which can be NULL. The caller owns the result.
static scoped_ptr<AddressValidator> Build( static scoped_ptr<AddressValidator> Build(
scoped_ptr<const Downloader> downloader, scoped_ptr<Downloader> downloader,
scoped_ptr<Storage> storage, scoped_ptr<Storage> storage,
LoadRulesDelegate* load_rules_delegate); LoadRulesDelegate* load_rules_delegate);
......
...@@ -44,7 +44,7 @@ class Downloader { ...@@ -44,7 +44,7 @@ class Downloader {
// Downloads |url| and invokes the |downloaded| callback. // Downloads |url| and invokes the |downloaded| callback.
virtual void Download(const std::string& url, virtual void Download(const std::string& url,
scoped_ptr<Callback> downloaded) const = 0; scoped_ptr<Callback> downloaded) = 0;
}; };
} // namespace addressinput } // namespace addressinput
......
...@@ -42,7 +42,7 @@ class AddressValidatorImpl : public AddressValidator { ...@@ -42,7 +42,7 @@ class AddressValidatorImpl : public AddressValidator {
public: public:
// Takes ownership of |downloader| and |storage|. Does not take ownership of // Takes ownership of |downloader| and |storage|. Does not take ownership of
// |load_rules_delegate|. // |load_rules_delegate|.
AddressValidatorImpl(scoped_ptr<const Downloader> downloader, AddressValidatorImpl(scoped_ptr<Downloader> downloader,
scoped_ptr<Storage> storage, scoped_ptr<Storage> storage,
LoadRulesDelegate* load_rules_delegate) LoadRulesDelegate* load_rules_delegate)
: aggregator_(scoped_ptr<Retriever>(new Retriever( : aggregator_(scoped_ptr<Retriever>(new Retriever(
...@@ -116,7 +116,7 @@ AddressValidator::~AddressValidator() {} ...@@ -116,7 +116,7 @@ AddressValidator::~AddressValidator() {}
// static // static
scoped_ptr<AddressValidator> AddressValidator::Build( scoped_ptr<AddressValidator> AddressValidator::Build(
scoped_ptr<const Downloader> downloader, scoped_ptr<Downloader> downloader,
scoped_ptr<Storage> storage, scoped_ptr<Storage> storage,
LoadRulesDelegate* load_rules_delegate) { LoadRulesDelegate* load_rules_delegate) {
return scoped_ptr<AddressValidator>(new AddressValidatorImpl( return scoped_ptr<AddressValidator>(new AddressValidatorImpl(
......
...@@ -33,7 +33,7 @@ namespace i18n { ...@@ -33,7 +33,7 @@ namespace i18n {
namespace addressinput { namespace addressinput {
Retriever::Retriever(const std::string& validation_data_url, Retriever::Retriever(const std::string& validation_data_url,
scoped_ptr<const Downloader> downloader, scoped_ptr<Downloader> downloader,
scoped_ptr<Storage> storage) scoped_ptr<Storage> storage)
: lookup_key_util_(validation_data_url), : lookup_key_util_(validation_data_url),
downloader_(downloader.Pass()), downloader_(downloader.Pass()),
......
...@@ -44,7 +44,7 @@ class Retriever { ...@@ -44,7 +44,7 @@ class Retriever {
typedef i18n::addressinput::Callback<std::string, std::string> Callback; typedef i18n::addressinput::Callback<std::string, std::string> Callback;
Retriever(const std::string& validation_data_url, Retriever(const std::string& validation_data_url,
scoped_ptr<const Downloader> downloader, scoped_ptr<Downloader> downloader,
scoped_ptr<Storage> storage); scoped_ptr<Storage> storage);
~Retriever(); ~Retriever();
...@@ -69,7 +69,7 @@ class Retriever { ...@@ -69,7 +69,7 @@ class Retriever {
scoped_ptr<Callback> GetCallbackForKey(const std::string& key); scoped_ptr<Callback> GetCallbackForKey(const std::string& key);
const LookupKeyUtil lookup_key_util_; const LookupKeyUtil lookup_key_util_;
scoped_ptr<const Downloader> downloader_; scoped_ptr<Downloader> downloader_;
scoped_ptr<Storage> storage_; scoped_ptr<Storage> storage_;
// Holds pending requests. The callback pointers are owned. // Holds pending requests. The callback pointers are owned.
std::map<std::string, Callback*> requests_; std::map<std::string, Callback*> requests_;
......
...@@ -72,7 +72,7 @@ FakeDownloader::FakeDownloader() {} ...@@ -72,7 +72,7 @@ FakeDownloader::FakeDownloader() {}
FakeDownloader::~FakeDownloader() {} FakeDownloader::~FakeDownloader() {}
void FakeDownloader::Download(const std::string& url, void FakeDownloader::Download(const std::string& url,
scoped_ptr<Callback> downloaded) const { scoped_ptr<Callback> downloaded) {
std::map<std::string, std::string>::const_iterator data_it = std::map<std::string, std::string>::const_iterator data_it =
GetData().find(url); GetData().find(url);
bool success = data_it != GetData().end(); bool success = data_it != GetData().end();
......
...@@ -58,7 +58,7 @@ class FakeDownloader : public Downloader { ...@@ -58,7 +58,7 @@ class FakeDownloader : public Downloader {
// Downloader implementation. // Downloader implementation.
virtual void Download(const std::string& url, virtual void Download(const std::string& url,
scoped_ptr<Callback> downloaded) const; scoped_ptr<Callback> downloaded);
}; };
} // namespace addressinput } // namespace addressinput
......
...@@ -41,7 +41,7 @@ class RetrieverTest : public testing::Test { ...@@ -41,7 +41,7 @@ class RetrieverTest : public testing::Test {
protected: protected:
RetrieverTest() RetrieverTest()
: retriever_(FakeDownloader::kFakeDataUrl, : retriever_(FakeDownloader::kFakeDataUrl,
scoped_ptr<const Downloader>(new FakeDownloader), scoped_ptr<Downloader>(new FakeDownloader),
scoped_ptr<Storage>(new FakeStorage)), scoped_ptr<Storage>(new FakeStorage)),
success_(false), success_(false),
key_(), key_(),
...@@ -106,14 +106,14 @@ class FaultyDownloader : public Downloader { ...@@ -106,14 +106,14 @@ class FaultyDownloader : public Downloader {
// Downloader implementation. // Downloader implementation.
virtual void Download(const std::string& url, virtual void Download(const std::string& url,
scoped_ptr<Callback> downloaded) const { scoped_ptr<Callback> downloaded) {
(*downloaded)(false, url, "garbage"); (*downloaded)(false, url, "garbage");
} }
}; };
TEST_F(RetrieverTest, FaultyDownloader) { TEST_F(RetrieverTest, FaultyDownloader) {
Retriever bad_retriever(FakeDownloader::kFakeDataUrl, Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
scoped_ptr<const Downloader>(new FaultyDownloader), scoped_ptr<Downloader>(new FaultyDownloader),
scoped_ptr<Storage>(new FakeStorage)); scoped_ptr<Storage>(new FakeStorage));
bad_retriever.Retrieve(kKey, BuildCallback()); bad_retriever.Retrieve(kKey, BuildCallback());
...@@ -130,12 +130,12 @@ class HangingDownloader : public Downloader { ...@@ -130,12 +130,12 @@ class HangingDownloader : public Downloader {
// Downloader implementation. // Downloader implementation.
virtual void Download(const std::string& url, virtual void Download(const std::string& url,
scoped_ptr<Callback> downloaded) const {} scoped_ptr<Callback> downloaded) {}
}; };
TEST_F(RetrieverTest, RequestsDontStack) { TEST_F(RetrieverTest, RequestsDontStack) {
Retriever slow_retriever(FakeDownloader::kFakeDataUrl, Retriever slow_retriever(FakeDownloader::kFakeDataUrl,
scoped_ptr<const Downloader>(new HangingDownloader), scoped_ptr<Downloader>(new HangingDownloader),
scoped_ptr<Storage>(new FakeStorage)); scoped_ptr<Storage>(new FakeStorage));
slow_retriever.Retrieve(kKey, BuildCallback()); slow_retriever.Retrieve(kKey, BuildCallback());
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
'<(SHARED_INTERMEDIATE_DIR)/libaddressinput/', '<(SHARED_INTERMEDIATE_DIR)/libaddressinput/',
], ],
'sources': [ 'sources': [
'chromium/chrome_downloader_impl.cc',
'chromium/chrome_downloader_impl.h',
'chromium/chrome_storage_impl.cc', 'chromium/chrome_storage_impl.cc',
'chromium/chrome_storage_impl.h', 'chromium/chrome_storage_impl.h',
'chromium/json.cc', 'chromium/json.cc',
...@@ -117,8 +119,7 @@ ...@@ -117,8 +119,7 @@
'<(SHARED_INTERMEDIATE_DIR)/libaddressinput/', '<(SHARED_INTERMEDIATE_DIR)/libaddressinput/',
], ],
'sources': [ 'sources': [
'chromium/chrome_storage_impl.cc', 'chromium/chrome_downloader_impl_unittest.cc',
'chromium/chrome_storage_impl.h',
'chromium/chrome_storage_impl_unittest.cc', 'chromium/chrome_storage_impl_unittest.cc',
'<(libaddressinput_dir)/cpp/test/address_ui_test.cc', '<(libaddressinput_dir)/cpp/test/address_ui_test.cc',
'<(libaddressinput_dir)/cpp/test/fake_downloader.cc', '<(libaddressinput_dir)/cpp/test/fake_downloader.cc',
...@@ -148,6 +149,7 @@ ...@@ -148,6 +149,7 @@
'libaddressinput', 'libaddressinput',
'<(DEPTH)/base/base.gyp:base_prefs', '<(DEPTH)/base/base.gyp:base_prefs',
'<(DEPTH)/base/base.gyp:run_all_unittests', '<(DEPTH)/base/base.gyp:run_all_unittests',
'<(DEPTH)/net/net.gyp:net_test_support',
'<(DEPTH)/testing/gtest.gyp:gtest', '<(DEPTH)/testing/gtest.gyp:gtest',
], ],
}, },
......
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