12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher_delegate.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/safe_json_parser.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_flags.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_status.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse";
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebstoreDataFetcher::WebstoreDataFetcher(
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebstoreDataFetcherDelegate* delegate,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* request_context,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& referrer_url,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string webstore_item_id)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : delegate_(delegate),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_context_(request_context),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      referrer_url_(referrer_url),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id_(webstore_item_id) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebstoreDataFetcher::~WebstoreDataFetcher() {}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreDataFetcher::Start() {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL webstore_data_url(extension_urls::GetWebstoreItemJsonDataURL(id_));
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_url_fetcher_.reset(net::URLFetcher::Create(
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      webstore_data_url, net::URLFetcher::GET, this));
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_url_fetcher_->SetRequestContext(request_context_);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_url_fetcher_->SetReferrer(referrer_url_.spec());
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           net::LOAD_DISABLE_CACHE);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_url_fetcher_->Start();
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebstoreDataFetcher::OnJsonParseSuccess(
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<base::Value> parsed_json) {
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!parsed_json->IsType(base::Value::TYPE_DICTIONARY)) {
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    OnJsonParseFailure(kInvalidWebstoreResponseError);
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  delegate_->OnWebstoreResponseParseSuccess(
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      static_cast<base::DictionaryValue*>(parsed_json.release()));
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebstoreDataFetcher::OnJsonParseFailure(
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& error) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_->OnWebstoreResponseParseFailure(error);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreDataFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(webstore_data_url_fetcher_.get(), source);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<net::URLFetcher> fetcher(webstore_data_url_fetcher_.Pass());
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!fetcher->GetStatus().is_success() ||
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->GetResponseCode() != 200) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->OnWebstoreRequestFailure();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string webstore_json_data;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->GetResponseAsString(&webstore_json_data);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<SafeJsonParser> parser =
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new SafeJsonParser(webstore_json_data,
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                         base::Bind(&WebstoreDataFetcher::OnJsonParseSuccess,
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    AsWeakPtr()),
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                         base::Bind(&WebstoreDataFetcher::OnJsonParseFailure,
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    AsWeakPtr()));
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The parser will call us back via one of the callbacks.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser->Start();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
90