Commit 2730fd5b authored by Tsuyoshi Horo's avatar Tsuyoshi Horo Committed by Commit Bot

Move BundleBuilder in web_bundle_parser_unittest.cc to a new file

To use this class from other tests.

Bug: 1038346
Change-Id: I14ac4ec270219314a8a096319cc023842a01f55f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1989206Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarKunihiko Sakamoto <ksakamoto@chromium.org>
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#729521}
parent 1b99a064
......@@ -84,6 +84,12 @@ source_set("test_support") {
sources = [
"test_support/in_process_data_decoder.cc",
"test_support/in_process_data_decoder.h",
"test_support/web_bundle_builder.cc",
"test_support/web_bundle_builder.h",
]
deps = [
"//components/cbor",
]
public_deps = [
......
// Copyright 2020 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 "services/data_decoder/public/cpp/test_support/web_bundle_builder.h"
namespace data_decoder {
namespace test {
namespace {
cbor::Value CreateByteString(base::StringPiece s) {
return cbor::Value(base::as_bytes(base::make_span(s)));
}
cbor::Value CreateHeaderMap(const WebBundleBuilder::Headers& headers) {
cbor::Value::MapValue map;
for (const auto& pair : headers)
map.insert({CreateByteString(pair.first), CreateByteString(pair.second)});
return cbor::Value(std::move(map));
}
} // namespace
WebBundleBuilder::WebBundleBuilder(const std::string& fallback_url,
const std::string& manifest_url)
: fallback_url_(fallback_url) {
writer_config_.allow_invalid_utf8_for_testing = true;
if (!manifest_url.empty()) {
AddSection("manifest",
cbor::Value::InvalidUTF8StringValueForTesting(manifest_url));
}
}
WebBundleBuilder::~WebBundleBuilder() = default;
void WebBundleBuilder::AddExchange(base::StringPiece url,
const Headers& response_headers,
base::StringPiece payload) {
AddIndexEntry(url, "", {AddResponse(response_headers, payload)});
}
WebBundleBuilder::ResponseLocation WebBundleBuilder::AddResponse(
const Headers& headers,
base::StringPiece payload) {
// We assume that the size of the CBOR header of the responses array is 1,
// which is true only if the responses array has no more than 23 elements.
DCHECK_LT(responses_.size(), 23u)
<< "WebBundleBuilder cannot create bundles with more than 23 responses";
cbor::Value::ArrayValue response_array;
response_array.emplace_back(Encode(CreateHeaderMap(headers)));
response_array.emplace_back(CreateByteString(payload));
cbor::Value response(response_array);
int64_t response_length = EncodedLength(response);
ResponseLocation result = {current_responses_offset_, response_length};
current_responses_offset_ += response_length;
responses_.emplace_back(std::move(response));
return result;
}
void WebBundleBuilder::AddIndexEntry(
base::StringPiece url,
base::StringPiece variants_value,
std::vector<ResponseLocation> response_locations) {
cbor::Value::ArrayValue index_value_array;
index_value_array.emplace_back(CreateByteString(variants_value));
for (const auto& location : response_locations) {
index_value_array.emplace_back(location.offset);
index_value_array.emplace_back(location.length);
}
index_.insert({cbor::Value::InvalidUTF8StringValueForTesting(url),
cbor::Value(index_value_array)});
}
void WebBundleBuilder::AddSection(base::StringPiece name, cbor::Value section) {
section_lengths_.emplace_back(name);
section_lengths_.emplace_back(EncodedLength(section));
sections_.emplace_back(std::move(section));
}
void WebBundleBuilder::AddAuthority(cbor::Value::MapValue authority) {
authorities_.emplace_back(std::move(authority));
}
void WebBundleBuilder::AddVouchedSubset(cbor::Value::MapValue vouched_subset) {
vouched_subsets_.emplace_back(std::move(vouched_subset));
}
std::vector<uint8_t> WebBundleBuilder::CreateBundle() {
AddSection("index", cbor::Value(index_));
if (!authorities_.empty() || !vouched_subsets_.empty()) {
cbor::Value::ArrayValue signatures_section;
signatures_section.emplace_back(std::move(authorities_));
signatures_section.emplace_back(std::move(vouched_subsets_));
AddSection("signatures", cbor::Value(std::move(signatures_section)));
}
AddSection("responses", cbor::Value(responses_));
return Encode(CreateTopLevel());
}
cbor::Value WebBundleBuilder::CreateEncodedSigned(
base::StringPiece validity_url,
base::StringPiece auth_sha256,
int64_t date,
int64_t expires,
base::StringPiece url,
base::StringPiece header_sha256,
base::StringPiece payload_integrity_header) {
cbor::Value::ArrayValue subset_hash_value;
subset_hash_value.emplace_back(CreateByteString("")); // variants-value
subset_hash_value.emplace_back(CreateByteString(header_sha256));
subset_hash_value.emplace_back(payload_integrity_header);
cbor::Value::MapValue subset_hashes;
subset_hashes.emplace(url, std::move(subset_hash_value));
cbor::Value::MapValue signed_subset;
signed_subset.emplace("validity-url", validity_url);
signed_subset.emplace("auth-sha256", CreateByteString(auth_sha256));
signed_subset.emplace("date", date);
signed_subset.emplace("expires", expires);
signed_subset.emplace("subset-hashes", std::move(subset_hashes));
return cbor::Value(Encode(cbor::Value(signed_subset)));
}
cbor::Value WebBundleBuilder::CreateTopLevel() {
cbor::Value::ArrayValue toplevel_array;
toplevel_array.emplace_back(
CreateByteString(u8"\U0001F310\U0001F4E6")); // "🌐📦"
toplevel_array.emplace_back(CreateByteString(base::StringPiece("b1\0\0", 4)));
toplevel_array.emplace_back(
cbor::Value::InvalidUTF8StringValueForTesting(fallback_url_));
toplevel_array.emplace_back(Encode(cbor::Value(section_lengths_)));
toplevel_array.emplace_back(sections_);
toplevel_array.emplace_back(CreateByteString("")); // length (ignored)
return cbor::Value(toplevel_array);
}
std::vector<uint8_t> WebBundleBuilder::Encode(const cbor::Value& value) {
return *cbor::Writer::Write(value, writer_config_);
}
int64_t WebBundleBuilder::EncodedLength(const cbor::Value& value) {
return Encode(value).size();
}
} // namespace test
} // namespace data_decoder
// Copyright 2020 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.
#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
#define SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
#include <string>
#include <utility>
#include <vector>
#include "base/strings/string_piece.h"
#include "components/cbor/writer.h"
namespace data_decoder {
namespace test {
// This class can be used to create a Web Bundle binary in tests.
class WebBundleBuilder {
public:
using Headers = std::vector<std::pair<std::string, std::string>>;
struct ResponseLocation {
// /components/cbor uses int64_t for integer types.
int64_t offset;
int64_t length;
};
WebBundleBuilder(const std::string& fallback_url,
const std::string& manifest_url);
~WebBundleBuilder();
void AddExchange(base::StringPiece url,
const Headers& response_headers,
base::StringPiece payload);
ResponseLocation AddResponse(const Headers& headers,
base::StringPiece payload);
void AddIndexEntry(base::StringPiece url,
base::StringPiece variants_value,
std::vector<ResponseLocation> response_locations);
void AddSection(base::StringPiece name, cbor::Value section);
void AddAuthority(cbor::Value::MapValue authority);
void AddVouchedSubset(cbor::Value::MapValue vouched_subset);
std::vector<uint8_t> CreateBundle();
// Creates a signed-subset structure with single subset-hashes entry,
// and returns it as a CBOR bytestring.
cbor::Value CreateEncodedSigned(base::StringPiece validity_url,
base::StringPiece auth_sha256,
int64_t date,
int64_t expires,
base::StringPiece url,
base::StringPiece header_sha256,
base::StringPiece payload_integrity_header);
private:
cbor::Value CreateTopLevel();
std::vector<uint8_t> Encode(const cbor::Value& value);
int64_t EncodedLength(const cbor::Value& value);
cbor::Writer::Config writer_config_;
std::string fallback_url_;
cbor::Value::ArrayValue section_lengths_;
cbor::Value::ArrayValue sections_;
cbor::Value::MapValue index_;
cbor::Value::ArrayValue responses_;
cbor::Value::ArrayValue authorities_;
cbor::Value::ArrayValue vouched_subsets_;
// 1 for the CBOR header byte. See the comment at the top of AddResponse().
int64_t current_responses_offset_ = 1;
};
} // namespace test
} // namespace data_decoder
#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
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