15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/io_buffer.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/load_flags.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_status_code.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_response_writer.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace autofill {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A URLFetcherResponseWriter that writes into a provided buffer.
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class UnownedStringWriter : public net::URLFetcherResponseWriter {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnownedStringWriter(std::string* data) : data_(data) {}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~UnownedStringWriter() {}
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int Initialize(const net::CompletionCallback& callback) OVERRIDE {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data_->clear();
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return net::OK;
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int Write(net::IOBuffer* buffer,
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    int num_bytes,
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    const net::CompletionCallback& callback) OVERRIDE {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data_->append(buffer->data(), num_bytes);
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return num_bytes;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int Finish(const net::CompletionCallback& callback) OVERRIDE {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return net::OK;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string* data_;  // weak reference.
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UnownedStringWriter);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ChromeMetadataSource::ChromeMetadataSource(
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& validation_data_url,
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    net::URLRequestContextGetter* getter)
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : validation_data_url_(validation_data_url),
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      getter_(getter) {}
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ChromeMetadataSource::~ChromeMetadataSource() {
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STLDeleteValues(&requests_);
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ChromeMetadataSource::Get(const std::string& key,
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               const Callback& downloaded) const {
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const_cast<ChromeMetadataSource*>(this)->Download(key, downloaded);
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ChromeMetadataSource::OnURLFetchComplete(const net::URLFetcher* source) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<const net::URLFetcher*, Request*>::iterator request =
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      requests_.find(source);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(request != requests_.end());
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool ok = source->GetResponseCode() == net::HTTP_OK;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<std::string> data(new std::string());
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ok)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data->swap(request->second->data);
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  request->second->callback(ok, request->second->key, data.release());
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete request->second;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  requests_.erase(request);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ChromeMetadataSource::Request::Request(const std::string& key,
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       scoped_ptr<net::URLFetcher> fetcher,
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       const Callback& callback)
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : key(key),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher(fetcher.Pass()),
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      callback(callback) {}
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ChromeMetadataSource::Download(const std::string& key,
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    const Callback& downloaded) {
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  GURL resource(validation_data_url_ + key);
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!resource.SchemeIsSecure()) {
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    downloaded(false, key, NULL);
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<net::URLFetcher> fetcher(
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::URLFetcher::Create(resource, net::URLFetcher::GET, this));
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  fetcher->SetLoadFlags(
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  fetcher->SetRequestContext(getter_);
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Request* request = new Request(key, fetcher.Pass(), downloaded);
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->fetcher->SaveResponseWithWriter(
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<net::URLFetcherResponseWriter>(
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          new UnownedStringWriter(&request->data)));
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  requests_[request->fetcher.get()] = request;
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->fetcher->Start();
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace autofill
111