Skip to content

Commit 2e81b11

Browse files
authored
feat(bigtable): preserve base64 padding on bigtable-features header (googleapis#16108)
1 parent dda3c4a commit 2e81b11

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

google/cloud/bigtable/internal/bigtable_stub_factory.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ std::string CreateFeaturesMetadata(bool is_direct_path) {
6060
proto.set_traffic_director_enabled(true);
6161
proto.set_direct_access_requested(true);
6262
}
63-
return internal::UrlsafeBase64Encode(proto.SerializeAsString());
63+
return internal::UrlsafeBase64EncodeWithPadding(proto.SerializeAsString());
6464
}
6565

6666
std::string FeaturesMetadata() {

google/cloud/internal/base64_transforms.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,30 @@ StatusOr<std::vector<std::uint8_t>> Base64DecodeToBytes(
104104

105105
/**
106106
* Returns a Base64-encoded version of @p bytes. Using the URL- and
107-
* filesystem-safe alphabet, making these adjustments:
107+
* filesystem-safe alphabet, retaining trailing '=' padding characters.
108108
* - Replace '+' with '-'
109109
* - Replace '/' with '_'
110-
* - Right-trim '=' characters
111110
*/
112111
template <typename Collection>
113-
inline std::string UrlsafeBase64Encode(Collection const& bytes) {
112+
inline std::string UrlsafeBase64EncodeWithPadding(Collection const& bytes) {
114113
Base64Encoder encoder;
115114
for (auto c : bytes) encoder.PushBack(c);
116115
std::string b64str = std::move(encoder).FlushAndPad();
117116
std::replace(b64str.begin(), b64str.end(), '+', '-');
118117
std::replace(b64str.begin(), b64str.end(), '/', '_');
118+
return b64str;
119+
}
120+
121+
/**
122+
* Returns a Base64-encoded version of @p bytes. Using the URL- and
123+
* filesystem-safe alphabet, making these adjustments:
124+
* - Replace '+' with '-'
125+
* - Replace '/' with '_'
126+
* - Right-trim '=' characters
127+
*/
128+
template <typename Collection>
129+
inline std::string UrlsafeBase64Encode(Collection const& bytes) {
130+
std::string b64str = UrlsafeBase64EncodeWithPadding(bytes);
119131
auto end_pos = b64str.find_last_not_of('=');
120132
if (end_pos != std::string::npos) {
121133
b64str.resize(end_pos + 1);

google/cloud/internal/base64_transforms_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ TEST(Base64, UrlsafeBase64Encode) {
153153
EXPECT_EQ("TG9yZ-W0gaXBz_dW1cMACg", UrlsafeBase64Encode(input));
154154
}
155155

156+
TEST(Base64, UrlsafeBase64EncodeWithPadding) {
157+
std::vector<std::uint8_t> input{
158+
0x4c, 0x6f, 0x72, 0x67, 0xe5, 0xb4, 0x81, 0xa5,
159+
0xc1, 0xcf, 0xf7, 0x56, 0xd5, 0xc3, 0x00, 0x0a,
160+
};
161+
EXPECT_EQ("TG9yZ-W0gaXBz_dW1cMACg==", UrlsafeBase64EncodeWithPadding(input));
162+
}
163+
156164
TEST(Base64, Base64Decode) {
157165
// Produced input using:
158166
// echo 'TG9yZ+W0gaXBz/dW1cMACg==' | openssl base64 -d | od -t x1

0 commit comments

Comments
 (0)