Commit 0a15edda authored by Dominic Battre's avatar Dominic Battre Committed by Commit Bot

Support API Server for ServerCacheReplayer

The ServerCacheReplayer replays captured communication with the autofill
server. With the switch of the legacy autofill server to the new API
server we want to keep using the traces recorded with the old server.

This CL extends the ServerCacheReplayer to intercept traffic to the old
and the new server, to read recorded traffice to the old and the new
server, and performs the conversion as necessary.

The ServerCacheReplayer is parameterized with a server type that is set
according to the features::kAutofillUseApi feature. If the feature is
configured to use the API server, the ServerCacheReplayer will re-encode
all stored network traffic to follow the new API server's format when
loading the data from disk. Analog steps are taken if the
ServerCacheReplayer is configured to serve as a legacy server.

Bug: 1079488
Change-Id: I59cb1fe50bddcc4bbc98b7a45fddc7dcc953eaf5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2209078Reviewed-by: default avatarVincent Boisselle <vincb@google.com>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/master@{#771954}
parent 03f08667
...@@ -207,7 +207,10 @@ class AutofillCapturedSitesInteractiveTest ...@@ -207,7 +207,10 @@ class AutofillCapturedSitesInteractiveTest
std::make_unique<test::ServerCacheReplayer>( std::make_unique<test::ServerCacheReplayer>(
GetParam().capture_file_path, GetParam().capture_file_path,
test::ServerCacheReplayer::kOptionFailOnInvalidJsonRecord | test::ServerCacheReplayer::kOptionFailOnInvalidJsonRecord |
test::ServerCacheReplayer::kOptionSplitRequestsByForm))); test::ServerCacheReplayer::kOptionSplitRequestsByForm,
base::FeatureList::IsEnabled(features::kAutofillUseApi)
? test::AutofillServerType::kApi
: test::AutofillServerType::kLegacy)));
} }
void TearDownOnMainThread() override { void TearDownOnMainThread() override {
...@@ -225,6 +228,7 @@ class AutofillCapturedSitesInteractiveTest ...@@ -225,6 +228,7 @@ class AutofillCapturedSitesInteractiveTest
// Allow access exception to live Autofill Server for // Allow access exception to live Autofill Server for
// overriding cache replay behavior. // overriding cache replay behavior.
host_resolver()->AllowDirectLookup("clients1.google.com"); host_resolver()->AllowDirectLookup("clients1.google.com");
host_resolver()->AllowDirectLookup("content-autofill.googleapis.com");
AutofillUiTest::SetUpInProcessBrowserTestFixture(); AutofillUiTest::SetUpInProcessBrowserTestFixture();
} }
...@@ -234,9 +238,9 @@ class AutofillCapturedSitesInteractiveTest ...@@ -234,9 +238,9 @@ class AutofillCapturedSitesInteractiveTest
// prediction. Test will check this attribute on all the relevant input // prediction. Test will check this attribute on all the relevant input
// elements in a form to determine if the form is ready for interaction. // elements in a form to determine if the form is ready for interaction.
feature_list_.InitWithFeatures( feature_list_.InitWithFeatures(
/*enabled_features=*/{features::kAutofillShowTypePredictions}, /*enabled_features=*/{features::kAutofillShowTypePredictions,
/*disabled_features=*/{features::kAutofillCacheQueryResponses, features::kAutofillUseApi},
features::kAutofillUseApi}); /*disabled_features=*/{features::kAutofillCacheQueryResponses});
command_line->AppendSwitch(switches::kShowAutofillTypePredictions); command_line->AppendSwitch(switches::kShowAutofillTypePredictions);
command_line->AppendSwitchASCII(::switches::kForceFieldTrials, command_line->AppendSwitchASCII(::switches::kForceFieldTrials,
"AutofillFieldMetadata/Enabled/"); "AutofillFieldMetadata/Enabled/");
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "components/autofill/core/browser/proto/api_v1.pb.h" #include "components/autofill/core/browser/proto/api_v1.pb.h"
#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/proto/server.pb.h"
#include "content/public/test/url_loader_interceptor.h" #include "content/public/test/url_loader_interceptor.h"
#include "third_party/protobuf/src/google/protobuf/stubs/statusor.h"
namespace autofill { namespace autofill {
namespace test { namespace test {
...@@ -38,14 +39,17 @@ std::ostream& operator<<( ...@@ -38,14 +39,17 @@ std::ostream& operator<<(
const autofill::AutofillQueryResponseContents& response); const autofill::AutofillQueryResponseContents& response);
std::ostream& operator<<(std::ostream& out, std::ostream& operator<<(std::ostream& out,
const autofill::AutofillQueryResponse& response); const autofill::AutofillQueryResponse& response);
enum class RequestType {
kQueryProtoGET,
kQueryProtoPOST,
kNone,
};
class LegacyEnv { class LegacyEnv {
public: public:
using Query = AutofillQueryContents; using Query = AutofillQueryContents;
using Response = AutofillQueryResponseContents; using Response = AutofillQueryResponseContents;
}; };
// Gets a key from a given query request.
std::string GetKeyFromQueryRequest(const AutofillQueryContents& query_request);
class ApiEnv { class ApiEnv {
public: public:
...@@ -53,7 +57,26 @@ class ApiEnv { ...@@ -53,7 +57,26 @@ class ApiEnv {
using Response = AutofillQueryResponse; using Response = AutofillQueryResponse;
}; };
enum class RequestType { kLegacyQueryProtoGET, kLegacyQueryProtoPOST }; // Gets a key from a given query request.
template <typename Env>
std::string GetKeyFromQuery(const typename Env::Query& query_request);
template <>
std::string GetKeyFromQuery<LegacyEnv>(const LegacyEnv::Query& query_request);
template <>
std::string GetKeyFromQuery<ApiEnv>(const ApiEnv::Query& query_request);
template <typename Env>
bool GetResponseForQuery(const ServerCache& cache,
const typename Env::Query& query,
std::string* http_text);
template <>
bool GetResponseForQuery<LegacyEnv>(const ServerCache& cache,
const typename LegacyEnv::Query& query,
std::string* http_text);
template <>
bool GetResponseForQuery<ApiEnv>(const ServerCache& cache,
const typename ApiEnv::Query& query,
std::string* http_text);
// Conversion between different versions of queries. // Conversion between different versions of queries.
template <typename ReadEnv, typename WriteEnv> template <typename ReadEnv, typename WriteEnv>
...@@ -91,6 +114,8 @@ enum class AutofillServerBehaviorType { ...@@ -91,6 +114,8 @@ enum class AutofillServerBehaviorType {
}; };
// Check for command line flags to determine Autofill Server Behavior type. // Check for command line flags to determine Autofill Server Behavior type.
AutofillServerBehaviorType ParseAutofillServerBehaviorType(); AutofillServerBehaviorType ParseAutofillServerBehaviorType();
// The type of server that shall be emulated.
enum class AutofillServerType { kLegacy, kApi };
// Replayer for Autofill Server cache. Can be used in concurrency. // Replayer for Autofill Server cache. Can be used in concurrency.
class ServerCacheReplayer { class ServerCacheReplayer {
...@@ -124,7 +149,10 @@ class ServerCacheReplayer { ...@@ -124,7 +149,10 @@ class ServerCacheReplayer {
// } // }
// You can set the replayer's behavior by setting |options| with a mix of // You can set the replayer's behavior by setting |options| with a mix of
// Options. Will crash if there is a failure when loading the cache. // Options. Will crash if there is a failure when loading the cache.
ServerCacheReplayer(const base::FilePath& json_file_path, int options); ServerCacheReplayer(
const base::FilePath& json_file_path,
int options,
AutofillServerType server_type = AutofillServerType::kLegacy);
// Constructs the replayer from an already populated cache. // Constructs the replayer from an already populated cache.
explicit ServerCacheReplayer(ServerCache server_cache, explicit ServerCacheReplayer(ServerCache server_cache,
bool split_requests_by_form = false); bool split_requests_by_form = false);
...@@ -134,25 +162,23 @@ class ServerCacheReplayer { ...@@ -134,25 +162,23 @@ class ServerCacheReplayer {
// key. Returns false if there was no match or the response could no be // key. Returns false if there was no match or the response could no be
// decompressed. Nothing will be assigned to |http_text| on error. Leaves a // decompressed. Nothing will be assigned to |http_text| on error. Leaves a
// log when there is an error. Can be used in concurrency. // log when there is an error. Can be used in concurrency.
bool GetResponseForQuery(const AutofillQueryContents& query, bool GetLegacyServerResponseForQuery(const AutofillQueryContents& query,
std::string* http_text) const; std::string* http_text) const;
bool GetApiServerResponseForQuery(const AutofillPageQueryRequest& query,
std::string* http_text) const;
const ServerCache& cache() const { return cache_; }
bool split_requests_by_form() const { return split_requests_by_form_; }
private: private:
// Server's cache. Will only be modified during construction of // Server's cache. Will only be modified during construction of
// ServerCacheReplayer. // ServerCacheReplayer.
ServerCache cache_; ServerCache cache_;
// Represents the cache at read time.
const ServerCache& const_cache_ = cache_;
// Controls the type of matching behavior. If False, will cache form signature // Controls the type of matching behavior. If False, will cache form signature
// groupings as they are recorded in the WPR archive. If True, will cache each // groupings as they are recorded in the WPR archive. If True, will cache each
// form individually and attempt to stitch them together on retrieval, which // form individually and attempt to stitch them together on retrieval, which
// allows a higher hit rate. // allows a higher hit rate.
const bool split_requests_by_form_; const bool split_requests_by_form_;
// Assumes key exists, and decompresses and returns http body which is stored
// at that location.
bool RetrieveAndDecompressStoredHTTP(const std::string& key,
std::string* decompressed_http) const;
}; };
// Url loader that intercepts Autofill Server calls and serves back cached // Url loader that intercepts Autofill Server calls and serves back cached
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
#include "chrome/browser/ui/tab_dialogs.h" #include "chrome/browser/ui/tab_dialogs.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/test_password_store.h" #include "components/password_manager/core/browser/test_password_store.h"
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
...@@ -167,7 +168,10 @@ class CapturedSitesPasswordManagerBrowserTest ...@@ -167,7 +168,10 @@ class CapturedSitesPasswordManagerBrowserTest
std::make_unique<ServerUrlLoader>(std::make_unique<ServerCacheReplayer>( std::make_unique<ServerUrlLoader>(std::make_unique<ServerCacheReplayer>(
GetParam().capture_file_path, GetParam().capture_file_path,
ServerCacheReplayer::kOptionFailOnInvalidJsonRecord | ServerCacheReplayer::kOptionFailOnInvalidJsonRecord |
ServerCacheReplayer::kOptionSplitRequestsByForm))); ServerCacheReplayer::kOptionSplitRequestsByForm,
base::FeatureList::IsEnabled(autofill::features::kAutofillUseApi)
? autofill::test::AutofillServerType::kApi
: autofill::test::AutofillServerType::kLegacy)));
} }
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment