Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: components/variations/service/variations_service.cc

Issue 1404583004: Support gzip-compressed seed data from the variations server. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolved comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/variations/service/variations_service.cc
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
index 2607ead57724737db0340ed82737a38d348fc3c2..68af875655f212929c32b664e8d52701cc347fa5 100644
--- a/components/variations/service/variations_service.cc
+++ b/components/variations/service/variations_service.cc
@@ -10,6 +10,7 @@
#include "base/metrics/sparse_histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
+#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "base/task_runner_util.h"
#include "base/timer/elapsed_timer.h"
@@ -214,6 +215,54 @@ std::string GetHeaderValue(const net::HttpResponseHeaders* headers,
return value;
}
+// Returns the list of values for |name| from |headers|. If the header in not
+// set, return an empty list.
+std::vector<std::string> GetHeaderValuesList(
+ const net::HttpResponseHeaders* headers, const base::StringPiece& name) {
Alexei Svitkine (slow) 2015/10/16 15:16:44 Nit: Prefer 1 param per line if the first one wrap
veranika 2015/10/16 21:01:00 Done.
+ std::vector<std::string> values;
+ void* iter = NULL;
+ std::string value;
+ while (headers->EnumerateHeader(&iter, name, &value)) {
+ values.push_back(value);
+ }
+ return values;
+}
+
+// Looks for delta and gzip compression instance manipulation flags set by the
+// server in |headers|. Checks the order of flags and presence of unknown
+// instance manipulations. If successful, |is_delta_compressed| and
+// |is_gzip_compressed| contain compression flags and true is returned.
+bool GetInstanceManipulations(const net::HttpResponseHeaders* headers,
+ bool* is_delta_compressed,
+ bool* is_gzip_compressed) {
+ std::vector<std::string> ims = GetHeaderValuesList(headers, "IM");
+ const auto delta_im = std::find(ims.begin(), ims.end(), "x-bm");
+ const auto gzip_im = std::find(ims.begin(), ims.end(), "gzip");
+ *is_delta_compressed = delta_im != ims.end();
+ *is_gzip_compressed = gzip_im != ims.end();
+
+ // The IM field should not have anything but x-bm and gzip.
+ size_t im_count = (*is_delta_compressed ? 1 : 0) +
+ (*is_gzip_compressed ? 1 : 0);
+ if (im_count != ims.size()) {
+ DVLOG(1) << "Unrecognized instance manipulations in "
+ << base::JoinString(ims, ",")
+ << "; only x-bm and gzip are supported";
+ return false;
+ }
+
+ // The IM field defines order in which instance manipulations were applied.
+ // The client requests and supports gzip-compressed delta-compressed seeds,
+ // but not vice versa.
+ if (*is_delta_compressed && *is_gzip_compressed && delta_im > gzip_im) {
+ DVLOG(1) << "Unsupported instance manipulations order: "
+ << "requested x-bm,gzip but received gzip,x-bm";
+ return false;
+ }
+
+ return true;
+}
+
} // namespace
VariationsService::VariationsService(
@@ -474,6 +523,7 @@ void VariationsService::DoActualFetch() {
net::LOAD_DO_NOT_SAVE_COOKIES);
pending_seed_request_->SetRequestContext(client_->GetURLRequestContext());
pending_seed_request_->SetMaxRetriesOn5xx(kMaxRetrySeedFetch);
+ bool enable_deltas = false;
if (!seed_store_.variations_serial_number().empty() &&
!disable_deltas_for_next_request_) {
// If the current seed includes a country code, deltas are not supported (as
@@ -484,12 +534,16 @@ void VariationsService::DoActualFetch() {
// that have an old seed with a country code becomes miniscule.
if (!seed_store_.seed_has_country_code()) {
// Tell the server that delta-compressed seeds are supported.
- pending_seed_request_->AddExtraRequestHeader("A-IM:x-bm");
+ enable_deltas = true;
}
// Get the seed only if its serial number doesn't match what we have.
pending_seed_request_->AddExtraRequestHeader(
"If-None-Match:" + seed_store_.variations_serial_number());
}
+ // Tell the server that delta-compressed and gzipped seeds are supported.
+ const char * supported_im = enable_deltas ? "A-IM:x-bm,gzip" : "A-IM:gzip";
Alexei Svitkine (slow) 2015/10/16 15:16:44 Nit: No space between char and *.
veranika 2015/10/16 21:01:00 Done.
+ pending_seed_request_->AddExtraRequestHeader(supported_im);
+
pending_seed_request_->Start();
const base::TimeTicks now = base::TimeTicks::Now();
@@ -510,13 +564,14 @@ bool VariationsService::StoreSeed(const std::string& seed_data,
const std::string& seed_signature,
const std::string& country_code,
const base::Time& date_fetched,
- bool is_delta_compressed) {
+ bool is_delta_compressed,
+ bool is_gzip_compressed) {
DCHECK(thread_checker_.CalledOnValidThread());
scoped_ptr<variations::VariationsSeed> seed(new variations::VariationsSeed);
if (!seed_store_.StoreSeedData(seed_data, seed_signature, country_code,
date_fetched, is_delta_compressed,
- seed.get())) {
+ is_gzip_compressed, seed.get())) {
return false;
}
RecordLastFetchTime();
@@ -630,9 +685,18 @@ void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) {
net::HttpResponseHeaders* headers = request->GetResponseHeaders();
const std::string signature = GetHeaderValue(headers, "X-Seed-Signature");
const std::string country_code = GetHeaderValue(headers, "X-Country");
Alexei Svitkine (slow) 2015/10/16 15:16:44 Nit: Can you move these two lines to right above t
veranika 2015/10/16 21:01:00 Done.
- const bool is_delta_compressed = (GetHeaderValue(headers, "IM") == "x-bm");
+
+ bool is_delta_compressed;
+ bool is_gzip_compressed;
+ if (!GetInstanceManipulations(headers, &is_delta_compressed,
+ &is_gzip_compressed)) {
+ // Details of errors are logged by GetInstanceManipulations, just return.
Alexei Svitkine (slow) 2015/10/16 15:16:44 What I'd like in this comment is why it's okay to
veranika 2015/10/16 21:01:00 Done.
+ return;
Alexei Svitkine (slow) 2015/10/16 15:16:44 Also, it would be good to log this case in a histo
veranika 2015/10/16 21:01:00 Done.
+ }
+
const bool store_success = StoreSeed(seed_data, signature, country_code,
- response_date, is_delta_compressed);
+ response_date, is_delta_compressed,
+ is_gzip_compressed);
if (!store_success && is_delta_compressed) {
disable_deltas_for_next_request_ = true;
request_scheduler_->ScheduleFetchShortly();

Powered by Google App Engine
This is Rietveld 408576698