Google Cloud Storage C++ Client 2.13.0
A C++ Client Library for Google Cloud Storage
Loading...
Searching...
No Matches
well_known_headers.h
1// Copyright 2018 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_WELL_KNOWN_HEADERS_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_WELL_KNOWN_HEADERS_H
17
18#include "google/cloud/storage/version.h"
19#include "google/cloud/internal/random.h"
20#include "google/cloud/optional.h"
21#include "absl/types/optional.h"
22#include <algorithm>
23#include <cstdint>
24#include <iostream>
25#include <limits>
26#include <random>
27#include <string>
28
29namespace google {
30namespace cloud {
31namespace storage {
32GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
33namespace internal {
34/**
35 * Defines well-known request headers using the CRTP.
36 *
37 * @tparam H the type we will use to represent the header.
38 * @tparam T the C++ type of the query parameter
39 */
40template <typename H, typename T>
41class WellKnownHeader {
42 public:
43 WellKnownHeader() = default;
44 explicit WellKnownHeader(T value) : value_(std::move(value)) {}
45
46 char const* header_name() const { return H::header_name(); }
47 bool has_value() const { return value_.has_value(); }
48 T const& value() const { return value_.value(); }
49 template <typename U>
50 T value_or(U&& default_val) {
51 return value_.value_or(std::forward<U>(default_val));
52 }
53
54 private:
55 absl::optional<T> value_;
56};
57
58template <typename H, typename T>
59std::ostream& operator<<(std::ostream& os, WellKnownHeader<H, T> const& rhs) {
60 if (rhs.has_value()) {
61 return os << rhs.header_name() << ": " << rhs.value();
62 }
63 return os << rhs.header_name() << ": <not set>";
64}
65} // namespace internal
66
67/**
68 * Set the MIME content type of an object.
69 *
70 * This optional parameter sets the content-type of an object during uploads,
71 * without having to configure all the other metadata attributes.
72 */
73struct ContentType
74 : public internal::WellKnownHeader<ContentType, std::string> {
75 using WellKnownHeader<ContentType, std::string>::WellKnownHeader;
76 static char const* header_name() { return "content-type"; }
77};
78
79/**
80 * An option to inject custom headers into the request.
81 *
82 * In some cases it is necessary to inject a custom header into the request. For
83 * example, because the protocol has added new headers and the library has not
84 * been updated to support them, or because
85 */
86class CustomHeader
87 : public internal::WellKnownHeader<CustomHeader, std::string> {
88 public:
89 CustomHeader() = default;
90 explicit CustomHeader(std::string name, std::string value)
91 : WellKnownHeader(std::move(value)), name_(std::move(name)) {}
92
93 std::string const& custom_header_name() const { return name_; }
94
95 private:
96 std::string name_;
97};
98
99std::ostream& operator<<(std::ostream& os, CustomHeader const& rhs);
100
101/**
102 * A pre-condition: apply this operation only if the HTTP Entity Tag matches.
103 *
104 * [HTTP Entity Tags](https://en.wikipedia.org/wiki/HTTP_ETag) allow
105 * applications to conditionally execute a query only if the target resource
106 * matches the expected state. This can be useful, for example, to implement
107 * optimistic concurrency control in the application.
108 */
109struct IfMatchEtag
110 : public internal::WellKnownHeader<IfMatchEtag, std::string> {
111 using WellKnownHeader<IfMatchEtag, std::string>::WellKnownHeader;
112 static char const* header_name() { return "If-Match"; }
113};
114
115/**
116 * A pre-condition: apply this operation only if the HTTP Entity Tag does not
117 * match.
118 *
119 * [HTTP Entity Tags](https://en.wikipedia.org/wiki/HTTP_ETag) allow
120 * applications to conditionally execute a query only if the target resource
121 * matches the expected state. This can be useful, for example, to implement
122 * optimistic concurrency control in the application.
123 */
124struct IfNoneMatchEtag
125 : public internal::WellKnownHeader<IfNoneMatchEtag, std::string> {
126 using WellKnownHeader<IfNoneMatchEtag, std::string>::WellKnownHeader;
127 static char const* header_name() { return "If-None-Match"; }
128};
129
130/**
131 * A simple wrapper for the encryption key attributes.
132 *
133 * Most request options have primitive types such as integers or strings.
134 * Encryption keys, in contrast, must include the algorithm, the
135 * (base64-encoded) key, and the (base64-encoded) hash of the key. This
136 * structure provides a simple container for these three values.
137 */
138struct EncryptionKeyData {
139 std::string algorithm;
140 std::string key;
141 std::string sha256;
142};
143
144/**
145 * Formats a (potentially binary) encryption key in the format required by the
146 * Google Cloud Storage API.
147 *
148 * @param key a binary key, must have exactly 32 bytes.
149 */
150EncryptionKeyData EncryptionDataFromBinaryKey(std::string const& key);
151
152/**
153 * Formats an encryption key in base64 format to the data structure required by
154 * the Google Cloud Storage API.
155 *
156 * @param key a base64-encoded key, must have exactly 32 bytes when decoded.
157 */
158EncryptionKeyData EncryptionDataFromBase64Key(std::string const& key);
159
160/**
161 * An optional parameter to set the Customer-Supplied Encryption key.
162 *
163 * Application developers can generate their own encryption keys to protect the
164 * data in GCS. This is known as a Customer-Supplied Encryption key (CSEK). If
165 * the application provides a CSEK, GCS does not retain the key. The object
166 * data, the object CRC32 checksum, and its MD5 hash (if applicable) are all
167 * encrypted with this key, and the key is required to read any of these
168 * elements back.
169 *
170 * Care must be taken to save and protect these keys, if lost, the data is not
171 * recoverable. Also, applications should avoid generating predictable keys,
172 * as this weakens the encryption.
173 *
174 * This option is used in read (download), write (upload), copy, and compose
175 * operations. Note that copy and compose operations use the same key for the
176 * source and destination objects.
177 *
178 * @see https://cloud.google.com/storage/docs/encryption/customer-supplied-keys
179 * for a detailed description of how Customer Supplied Encryption keys are
180 * used in GCS.
181 */
182struct EncryptionKey
183 : public internal::WellKnownHeader<EncryptionKey, EncryptionKeyData> {
184 using WellKnownHeader<EncryptionKey, EncryptionKeyData>::WellKnownHeader;
185
186 /**
187 * Create an encryption key parameter from a binary key.
188 *
189 * @param key a binary key, must have exactly 32 bytes.
190 */
191 static EncryptionKey FromBinaryKey(std::string const& key);
192
193 /**
194 * Creates an encryption key parameter from a key in base64 format.
195 *
196 * @param key a base64-encoded key, must have exactly 32 bytes when decoded.
197 */
198 static EncryptionKey FromBase64Key(std::string const& key);
199
200 static char const* prefix() { return "x-goog-encryption-"; }
201};
202
203std::ostream& operator<<(std::ostream& os, EncryptionKey const& rhs);
204
205/**
206 * An optional parameter to set the Customer-Supplied Encryption key for rewrite
207 * source object.
208 *
209 * Application developers can generate their own encryption keys to protect the
210 * data in GCS. This is known as a Customer-Supplied Encryption key (CSEK). If
211 * the application provides a CSEK, GCS does not retain the key. The object
212 * data, the object CRC32 checksum, and its MD5 hash (if applicable) are all
213 * encrypted with this key, and the key is required to read any of these
214 * elements back.
215 *
216 * Care must be taken to save and protect these keys, if lost, the data is not
217 * recoverable. Also, applications should avoid generating predictable keys,
218 * as this weakens the encryption.
219 *
220 * This option is used only in rewrite operations and it defines the key used
221 * for the source object.
222 *
223 * @see https://cloud.google.com/storage/docs/encryption/customer-supplied-keys
224 * for a detailed description of how Customer Supplied Encryption keys are
225 * used in GCS.
226 */
228 : public internal::WellKnownHeader<SourceEncryptionKey, EncryptionKeyData> {
229 using WellKnownHeader<SourceEncryptionKey,
230 EncryptionKeyData>::WellKnownHeader;
231
232 /**
233 * Creates a source encryption key parameter from a binary key.
234 *
235 * @param key a binary key, must have exactly 32 bytes.
236 */
237 static SourceEncryptionKey FromBinaryKey(std::string const& key);
238
239 /**
240 * Creates an encryption key parameter from a key in base64 format.
241 *
242 * @param key a base64-encoded key, must have exactly 32 bytes when decoded.
243 */
244 static SourceEncryptionKey FromBase64Key(std::string const& key);
245
246 static char const* prefix() { return "x-goog-copy-source-encryption-"; }
247};
248
249std::ostream& operator<<(std::ostream& os, SourceEncryptionKey const& rhs);
250
251/**
252 * Creates an encryption key parameter from a pseudo-random number generator.
253 *
254 * @tparam Generator the pseudo-random number generator type, it must meet the
255 * `UniformRandomBitGenerator` requirements.
256 * @param gen the pseudo-random number generator.
257 *
258 * @par Example
259 * @snippet storage_object_csek_samples.cc generate encryption key
260 *
261 * @see https://en.cppreference.com/w/cpp/numeric/random for a general
262 * overview of C++ pseudo-random number support.
263 *
264 * @see
265 * https://en.cppreference.com/w/cpp/numeric/random/UniformRandomBitGenerator
266 * for a more detailed overview of the requirements for generators.
267 */
268template <typename Generator>
270 auto constexpr kKeySize = 256 / std::numeric_limits<unsigned char>::digits;
271 auto constexpr kMinChar = (std::numeric_limits<char>::min)();
272 auto constexpr kMaxChar = (std::numeric_limits<char>::max)();
273 std::uniform_int_distribution<int> uni(kMinChar, kMaxChar);
274 std::string key(static_cast<std::size_t>(kKeySize), ' ');
275 std::generate_n(key.begin(), key.size(),
276 [&uni, &gen] { return static_cast<char>(uni(gen)); });
278}
279
280/**
281 * Modify the accepted encodings.
282 *
283 * When using HTTP, GCS decompresses gzip-encoded objects by default:
284 *
285 * https://cloud.google.com/storage/docs/transcoding
286 *
287 * Setting this option to `gzip` disables automatic decompression. This can be
288 * useful for applications wanting to operate with the compressed data. Setting
289 * this option to `identity`, or not setting this option, returns decompressed
290 * data.
291 *
292 * @note Note that decompressive transcoding only apply to objects that are
293 * compressed with `gzip` and have their `content_encoding()` attribute set
294 * accordingly. At the time of this writing GCS does not decompress objects
295 * stored with other compression algorithms, nor does it detect the object
296 * compression based on the object name or its contents.
297 *
298 * @see `AcceptEncodingGzip()` is a helper function to disable decompressive
299 * encoding.
300 */
301struct AcceptEncoding
302 : public internal::WellKnownHeader<AcceptEncoding, std::string> {
303 using WellKnownHeader<AcceptEncoding, std::string>::WellKnownHeader;
304 static char const* header_name() { return "Accept-Encoding"; }
305};
306
307inline AcceptEncoding AcceptEncodingGzip() { return AcceptEncoding("gzip"); }
308
310 return AcceptEncoding("identity");
311}
312
313GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
314} // namespace storage
315} // namespace cloud
316} // namespace google
317
318#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_WELL_KNOWN_HEADERS_H
An option to inject custom headers into the request.
Definition: well_known_headers.h:87
CustomHeader(std::string name, std::string value)
Definition: well_known_headers.h:90
std::string const & custom_header_name() const
Definition: well_known_headers.h:93
Contains all the Google Cloud Storage C++ client APIs.
Definition: auto_finalize.h:24
AcceptEncoding AcceptEncodingIdentity()
Definition: well_known_headers.h:309
EncryptionKeyData EncryptionDataFromBase64Key(std::string const &key)
Formats an encryption key in base64 format to the data structure required by the Google Cloud Storage...
EncryptionKeyData EncryptionDataFromBinaryKey(std::string const &key)
Formats a (potentially binary) encryption key in the format required by the Google Cloud Storage API.
AcceptEncoding AcceptEncodingGzip()
Definition: well_known_headers.h:307
EncryptionKeyData CreateKeyFromGenerator(Generator &gen)
Creates an encryption key parameter from a pseudo-random number generator.
Definition: well_known_headers.h:269
Modify the accepted encodings.
Definition: well_known_headers.h:302
static char const * header_name()
Definition: well_known_headers.h:304
Set the MIME content type of an object.
Definition: well_known_headers.h:74
static char const * header_name()
Definition: well_known_headers.h:76
A simple wrapper for the encryption key attributes.
Definition: well_known_headers.h:138
std::string algorithm
Definition: well_known_headers.h:139
std::string sha256
Definition: well_known_headers.h:141
std::string key
Definition: well_known_headers.h:140
An optional parameter to set the Customer-Supplied Encryption key.
Definition: well_known_headers.h:183
static char const * prefix()
Definition: well_known_headers.h:200
static EncryptionKey FromBinaryKey(std::string const &key)
Create an encryption key parameter from a binary key.
static EncryptionKey FromBase64Key(std::string const &key)
Creates an encryption key parameter from a key in base64 format.
A pre-condition: apply this operation only if the HTTP Entity Tag matches.
Definition: well_known_headers.h:110
static char const * header_name()
Definition: well_known_headers.h:112
A pre-condition: apply this operation only if the HTTP Entity Tag does not match.
Definition: well_known_headers.h:125
static char const * header_name()
Definition: well_known_headers.h:127
An optional parameter to set the Customer-Supplied Encryption key for rewrite source object.
Definition: well_known_headers.h:228
static SourceEncryptionKey FromBase64Key(std::string const &key)
Creates an encryption key parameter from a key in base64 format.
static char const * prefix()
Definition: well_known_headers.h:246
static SourceEncryptionKey FromBinaryKey(std::string const &key)
Creates a source encryption key parameter from a binary key.