Skip to content

Commit 160f21a

Browse files
authored
Make the language reported via headers configurable (#6264)
1 parent 6c5e04d commit 160f21a

File tree

6 files changed

+80
-19
lines changed

6 files changed

+80
-19
lines changed

Firestore/Source/API/FIRFirestore.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ @implementation FIRFirestore {
9696
+ (void)initialize {
9797
if (self == [FIRFirestore class]) {
9898
SetThrowHandler(ObjcThrowHandler);
99+
Firestore::SetClientLanguage("gl-objc/");
99100
}
100101
}
101102

Firestore/core/src/api/firestore.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "Firestore/core/src/local/leveldb_persistence.h"
3232
#include "Firestore/core/src/model/document_key.h"
3333
#include "Firestore/core/src/model/resource_path.h"
34+
#include "Firestore/core/src/remote/grpc_connection.h"
3435
#include "Firestore/core/src/util/async_queue.h"
3536
#include "Firestore/core/src/util/executor.h"
3637
#include "Firestore/core/src/util/hard_assert.h"
@@ -49,6 +50,7 @@ using core::Transaction;
4950
using local::LevelDbPersistence;
5051
using model::DocumentKey;
5152
using model::ResourcePath;
53+
using remote::GrpcConnection;
5254
using util::AsyncQueue;
5355
using util::Empty;
5456
using util::Executor;
@@ -191,6 +193,10 @@ void Firestore::DisableNetwork(util::StatusCallback callback) {
191193
client_->DisableNetwork(std::move(callback));
192194
}
193195

196+
void Firestore::SetClientLanguage(std::string language_token) {
197+
GrpcConnection::SetClientLanguage(std::move(language_token));
198+
}
199+
194200
std::unique_ptr<ListenerRegistration> Firestore::AddSnapshotsInSyncListener(
195201
std::unique_ptr<core::EventListener<Empty>> listener) {
196202
EnsureClientConfigured();

Firestore/core/src/api/firestore.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ class Firestore : public std::enable_shared_from_this<Firestore> {
9595
void EnableNetwork(util::StatusCallback callback);
9696
void DisableNetwork(util::StatusCallback callback);
9797

98+
/**
99+
* Sets the language of the public API in the format of
100+
* "gl-<language>/<version>" where version might be blank, e.g. `gl-objc/`.
101+
*/
102+
static void SetClientLanguage(std::string language_token);
103+
98104
private:
99105
void EnsureClientConfigured();
100106
core::DatabaseInfo MakeDatabaseInfo() const;

Firestore/core/src/remote/grpc_connection.cc

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "absl/memory/memory.h"
3636
#include "absl/strings/str_cat.h"
3737
#include "grpcpp/create_channel.h"
38+
#include "grpcpp/grpcpp.h"
3839

3940
namespace firebase {
4041
namespace firestore {
@@ -119,8 +120,59 @@ class HostConfigMap {
119120
};
120121

121122
HostConfigMap& Config() {
122-
static HostConfigMap config_by_host_;
123-
return config_by_host_;
123+
static HostConfigMap config_by_host;
124+
return config_by_host;
125+
}
126+
127+
std::string GetCppLanguageToken() {
128+
const char* cpp_version = [] {
129+
switch (__cplusplus) {
130+
case 199711L:
131+
return "1998";
132+
case 201103L:
133+
return "2011";
134+
case 201402L:
135+
return "2014";
136+
case 201703L:
137+
return "2017";
138+
case 202002L:
139+
return "2020";
140+
default:
141+
return "";
142+
}
143+
}();
144+
145+
return StringFormat("gl-cpp/%s", cpp_version);
146+
}
147+
148+
class ClientLanguageToken {
149+
using Guard = std::lock_guard<std::mutex>;
150+
151+
public:
152+
void Set(std::string value) {
153+
Guard guard(mutex_);
154+
value_ = std::move(value);
155+
}
156+
157+
const std::string& Get() const {
158+
Guard guard(mutex_);
159+
return value_;
160+
}
161+
162+
private:
163+
std::string value_ = GetCppLanguageToken();
164+
mutable std::mutex mutex_;
165+
};
166+
167+
ClientLanguageToken& LanguageToken() {
168+
static ClientLanguageToken token;
169+
return token;
170+
}
171+
172+
void AddCloudApiHeader(grpc::ClientContext& context) {
173+
auto api_tokens = StringFormat("%s fire/%s grpc/%s", LanguageToken().Get(),
174+
kFirestoreVersionString, grpc::Version());
175+
context.AddMetadata(kXGoogAPIClientHeader, api_tokens);
124176
}
125177

126178
#if __APPLE__
@@ -173,16 +225,7 @@ std::unique_ptr<grpc::ClientContext> GrpcConnection::CreateContext(
173225
context->AddMetadata(kAuthorizationHeader, absl::StrCat("Bearer ", token));
174226
}
175227

176-
// TODO(dimond): This should ideally also include the gRPC version, however,
177-
// gRPC defines the version as a macro, so it would be hardcoded based on
178-
// version we have at compile time of the Firestore library, rather than the
179-
// version available at runtime/at compile time by the user of the library.
180-
//
181-
// TODO(varconst): this should be configurable (e.g., "gl-cpp" or similar for
182-
// C++ SDK, etc.).
183-
context->AddMetadata(
184-
kXGoogAPIClientHeader,
185-
StringFormat("gl-objc/ fire/%s grpc/", kFirestoreVersionString));
228+
AddCloudApiHeader(*context);
186229

187230
// This header is used to improve routing and project isolation by the
188231
// backend.
@@ -307,17 +350,20 @@ void GrpcConnection::Unregister(GrpcCall* call) {
307350
active_calls_.erase(found);
308351
}
309352

310-
/*static*/ void GrpcConnection::UseTestCertificate(
311-
const std::string& host,
312-
const Path& certificate_path,
313-
const std::string& target_name) {
314-
Config().UseTestCertificate(host, certificate_path, target_name);
353+
void GrpcConnection::SetClientLanguage(std::string language_token) {
354+
LanguageToken().Set(std::move(language_token));
315355
}
316356

317-
/*static*/ void GrpcConnection::UseInsecureChannel(const std::string& host) {
357+
void GrpcConnection::UseInsecureChannel(const std::string& host) {
318358
Config().UseInsecureChannel(host);
319359
}
320360

361+
void GrpcConnection::UseTestCertificate(const std::string& host,
362+
const Path& certificate_path,
363+
const std::string& target_name) {
364+
Config().UseTestCertificate(host, certificate_path, target_name);
365+
}
366+
321367
} // namespace remote
322368
} // namespace firestore
323369
} // namespace firebase

Firestore/core/src/remote/grpc_connection.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class GrpcConnection {
8585
void Register(GrpcCall* call);
8686
void Unregister(GrpcCall* call);
8787

88+
static void SetClientLanguage(std::string language_token);
89+
8890
/**
8991
* Don't use SSL, send all traffic unencrypted. Call before creating any
9092
* streams or calls.

scripts/style.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ case "$version" in
5353
*)
5454
echo "Please upgrade to clang-format version 10."
5555
echo "If it's installed via homebrew you can run:"
56-
echo "brew install clang-format"
56+
echo "brew upgrade clang-format"
5757
exit 1
5858
;;
5959
esac

0 commit comments

Comments
 (0)