// 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_metadata_source.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/http/http_status_code.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_response_writer.h" #include "url/gurl.h" namespace autofill { namespace { // A URLFetcherResponseWriter that writes into a provided buffer. class UnownedStringWriter : public net::URLFetcherResponseWriter { public: UnownedStringWriter(std::string* data) : data_(data) {} virtual ~UnownedStringWriter() {} virtual int Initialize(const net::CompletionCallback& callback) OVERRIDE { data_->clear(); return net::OK; } virtual int Write(net::IOBuffer* buffer, int num_bytes, const net::CompletionCallback& callback) OVERRIDE { data_->append(buffer->data(), num_bytes); return num_bytes; } virtual int Finish(const net::CompletionCallback& callback) OVERRIDE { return net::OK; } private: std::string* data_; // weak reference. DISALLOW_COPY_AND_ASSIGN(UnownedStringWriter); }; } // namespace ChromeMetadataSource::ChromeMetadataSource( const std::string& validation_data_url, net::URLRequestContextGetter* getter) : validation_data_url_(validation_data_url), getter_(getter) {} ChromeMetadataSource::~ChromeMetadataSource() { STLDeleteValues(&requests_); } void ChromeMetadataSource::Get(const std::string& key, const Callback& downloaded) const { const_cast(this)->Download(key, downloaded); } void ChromeMetadataSource::OnURLFetchComplete(const net::URLFetcher* source) { std::map::iterator request = requests_.find(source); DCHECK(request != requests_.end()); bool ok = source->GetResponseCode() == net::HTTP_OK; scoped_ptr data(new std::string()); if (ok) data->swap(request->second->data); request->second->callback(ok, request->second->key, data.release()); delete request->second; requests_.erase(request); } ChromeMetadataSource::Request::Request(const std::string& key, scoped_ptr fetcher, const Callback& callback) : key(key), fetcher(fetcher.Pass()), callback(callback) {} void ChromeMetadataSource::Download(const std::string& key, const Callback& downloaded) { GURL resource(validation_data_url_ + key); if (!resource.SchemeIsSecure()) { downloaded(false, key, NULL); return; } scoped_ptr fetcher( net::URLFetcher::Create(resource, net::URLFetcher::GET, this)); fetcher->SetLoadFlags( net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); fetcher->SetRequestContext(getter_); Request* request = new Request(key, fetcher.Pass(), downloaded); request->fetcher->SaveResponseWithWriter( scoped_ptr( new UnownedStringWriter(&request->data))); requests_[request->fetcher.get()] = request; request->fetcher->Start(); } } // namespace autofill