blob: c0eb082d9e8c6ae71c8623e7bf773a8914f66d78 [file] [log] [blame]
// Copyright 2016 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 "components/ntp_snippets/ntp_snippets_fetcher.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
#include "google_apis/google_api_keys.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
using net::URLFetcher;
using net::URLRequestContextGetter;
using net::HttpRequestHeaders;
using net::URLRequestStatus;
namespace ntp_snippets {
const char kContentSnippetsServerFormat[] =
"https://chromereader-pa.googleapis.com/v1/fetch?key=%s";
const char kRequestParameterFormat[] =
"{"
" \"response_detail_level\": \"STANDARD\","
" \"advanced_options\": {"
" \"local_scoring_params\": {"
" \"content_params\": {"
" \"only_return_personalized_results\": false"
" },"
" \"content_restricts\": {"
" \"type\": \"METADATA\","
" \"value\": \"TITLE\""
" },"
" \"content_restricts\": {"
" \"type\": \"METADATA\","
" \"value\": \"SNIPPET\""
" },"
" \"content_restricts\": {"
" \"type\": \"METADATA\","
" \"value\": \"THUMBNAIL\""
" }"
"%s"
" },"
" \"global_scoring_params\": {"
" \"num_to_return\": 10"
" }"
" }"
"}";
const char kHostRestrictFormat[] =
" ,\"content_selectors\": {"
" \"type\": \"HOST_RESTRICT\","
" \"value\": \"%s\""
" }";
NTPSnippetsFetcher::NTPSnippetsFetcher(
scoped_refptr<base::SequencedTaskRunner> file_task_runner,
scoped_refptr<URLRequestContextGetter> url_request_context_getter,
bool is_stable_channel)
: file_task_runner_(file_task_runner),
url_request_context_getter_(url_request_context_getter),
is_stable_channel_(is_stable_channel) {}
NTPSnippetsFetcher::~NTPSnippetsFetcher() {
}
scoped_ptr<NTPSnippetsFetcher::SnippetsAvailableCallbackList::Subscription>
NTPSnippetsFetcher::AddCallback(const SnippetsAvailableCallback& callback) {
return callback_list_.Add(callback);
}
void NTPSnippetsFetcher::FetchSnippets(const std::set<std::string>& hosts) {
// TODO(treib): What to do if there's already a pending request?
const std::string& key = is_stable_channel_
? google_apis::GetAPIKey()
: google_apis::GetNonStableAPIKey();
std::string url =
base::StringPrintf(kContentSnippetsServerFormat, key.c_str());
url_fetcher_ = URLFetcher::Create(GURL(url), URLFetcher::POST, this);
url_fetcher_->SetRequestContext(url_request_context_getter_.get());
url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES);
HttpRequestHeaders headers;
headers.SetHeader("Content-Type", "application/json; charset=UTF-8");
url_fetcher_->SetExtraRequestHeaders(headers.ToString());
std::string host_restricts;
for (const std::string& host : hosts)
host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str());
url_fetcher_->SetUploadData("application/json",
base::StringPrintf(kRequestParameterFormat,
host_restricts.c_str()));
// Fetchers are sometimes cancelled because a network change was detected.
url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
// Try to make fetching the files bit more robust even with poor connection.
url_fetcher_->SetMaxRetriesOn5xx(3);
url_fetcher_->Start();
}
////////////////////////////////////////////////////////////////////////////////
// URLFetcherDelegate overrides
void NTPSnippetsFetcher::OnURLFetchComplete(const URLFetcher* source) {
DCHECK_EQ(url_fetcher_.get(), source);
const URLRequestStatus& status = source->GetStatus();
if (!status.is_success()) {
DLOG(WARNING) << "URLRequestStatus error " << status.error()
<< " while trying to download " << source->GetURL().spec();
return;
}
int response_code = source->GetResponseCode();
if (response_code != net::HTTP_OK) {
DLOG(WARNING) << "HTTP error " << response_code
<< " while trying to download " << source->GetURL().spec();
return;
}
std::string response;
bool stores_result_to_string = source->GetResponseAsString(&response);
DCHECK(stores_result_to_string);
callback_list_.Notify(response);
}
} // namespace ntp_snippets