1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "net/base/io_buffer.h" 10 #include "net/base/load_flags.h" 11 #include "net/base/net_errors.h" 12 #include "net/http/http_status_code.h" 13 #include "net/url_request/url_fetcher.h" 14 #include "net/url_request/url_fetcher_response_writer.h" 15 #include "url/gurl.h" 16 17 namespace autofill { 18 19 namespace { 20 21 // A URLFetcherResponseWriter that writes into a provided buffer. 22 class UnownedStringWriter : public net::URLFetcherResponseWriter { 23 public: 24 UnownedStringWriter(std::string* data) : data_(data) {} 25 virtual ~UnownedStringWriter() {} 26 27 virtual int Initialize(const net::CompletionCallback& callback) OVERRIDE { 28 data_->clear(); 29 return net::OK; 30 } 31 32 virtual int Write(net::IOBuffer* buffer, 33 int num_bytes, 34 const net::CompletionCallback& callback) OVERRIDE { 35 data_->append(buffer->data(), num_bytes); 36 return num_bytes; 37 } 38 39 virtual int Finish(const net::CompletionCallback& callback) OVERRIDE { 40 return net::OK; 41 } 42 43 private: 44 std::string* data_; // weak reference. 45 46 DISALLOW_COPY_AND_ASSIGN(UnownedStringWriter); 47 }; 48 49 } // namespace 50 51 ChromeMetadataSource::ChromeMetadataSource( 52 const std::string& validation_data_url, 53 net::URLRequestContextGetter* getter) 54 : validation_data_url_(validation_data_url), 55 getter_(getter) {} 56 57 ChromeMetadataSource::~ChromeMetadataSource() { 58 STLDeleteValues(&requests_); 59 } 60 61 void ChromeMetadataSource::Get(const std::string& key, 62 const Callback& downloaded) const { 63 const_cast<ChromeMetadataSource*>(this)->Download(key, downloaded); 64 } 65 66 void ChromeMetadataSource::OnURLFetchComplete(const net::URLFetcher* source) { 67 std::map<const net::URLFetcher*, Request*>::iterator request = 68 requests_.find(source); 69 DCHECK(request != requests_.end()); 70 71 bool ok = source->GetResponseCode() == net::HTTP_OK; 72 scoped_ptr<std::string> data(new std::string()); 73 if (ok) 74 data->swap(request->second->data); 75 request->second->callback(ok, request->second->key, data.release()); 76 77 delete request->second; 78 requests_.erase(request); 79 } 80 81 ChromeMetadataSource::Request::Request(const std::string& key, 82 scoped_ptr<net::URLFetcher> fetcher, 83 const Callback& callback) 84 : key(key), 85 fetcher(fetcher.Pass()), 86 callback(callback) {} 87 88 void ChromeMetadataSource::Download(const std::string& key, 89 const Callback& downloaded) { 90 GURL resource(validation_data_url_ + key); 91 if (!resource.SchemeIsSecure()) { 92 downloaded(false, key, NULL); 93 return; 94 } 95 96 scoped_ptr<net::URLFetcher> fetcher( 97 net::URLFetcher::Create(resource, net::URLFetcher::GET, this)); 98 fetcher->SetLoadFlags( 99 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 100 fetcher->SetRequestContext(getter_); 101 102 Request* request = new Request(key, fetcher.Pass(), downloaded); 103 request->fetcher->SaveResponseWithWriter( 104 scoped_ptr<net::URLFetcherResponseWriter>( 105 new UnownedStringWriter(&request->data))); 106 requests_[request->fetcher.get()] = request; 107 request->fetcher->Start(); 108 } 109 110 } // namespace autofill 111