Skip to content

Commit 510f5d3

Browse files
authored
Merge pull request #117 from carlopi/duckdb_user_agent
Set User-Agent to DuckDB's custom db.config.UserAgent()
2 parents 8f71403 + b2607bd commit 510f5d3

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

extension/httpfs/httpfs.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ unique_ptr<HTTPParams> HTTPFSUtil::InitializeParameters(optional_ptr<FileOpener>
5757
FileOpener::TryGetCurrentSetting(opener, "hf_max_per_page", result->hf_max_per_page, info);
5858
FileOpener::TryGetCurrentSetting(opener, "unsafe_disable_etag_checks", result->unsafe_disable_etag_checks, info);
5959

60+
{
61+
auto db = FileOpener::TryGetDatabase(opener);
62+
if (db) {
63+
result->user_agent = StringUtil::Format("%s %s", db->config.UserAgent(), DuckDB::SourceID());
64+
}
65+
}
66+
6067
// HTTP Secret lookups
6168
KeyValueSecretReader settings_reader(*opener, info, "http");
6269

@@ -101,11 +108,20 @@ void HTTPClientCache::StoreClient(unique_ptr<HTTPClient> client) {
101108
clients.push_back(std::move(client));
102109
}
103110

111+
static void AddUserAgentIfAvailable(HTTPFSParams &http_params, HTTPHeaders &header_map) {
112+
if (!http_params.user_agent.empty()) {
113+
header_map.Insert("User-Agent", http_params.user_agent);
114+
}
115+
}
116+
104117
unique_ptr<HTTPResponse> HTTPFileSystem::PostRequest(FileHandle &handle, string url, HTTPHeaders header_map,
105118
string &buffer_out, char *buffer_in, idx_t buffer_in_len,
106119
string params) {
107120
auto &hfh = handle.Cast<HTTPFileHandle>();
108121
auto &http_util = hfh.http_params.http_util;
122+
123+
AddUserAgentIfAvailable(hfh.http_params, header_map);
124+
109125
PostRequestInfo post_request(url, header_map, hfh.http_params, const_data_ptr_cast(buffer_in), buffer_in_len);
110126
auto result = http_util.Request(post_request);
111127
buffer_out = std::move(post_request.buffer_out);
@@ -116,6 +132,9 @@ unique_ptr<HTTPResponse> HTTPFileSystem::PutRequest(FileHandle &handle, string u
116132
char *buffer_in, idx_t buffer_in_len, string params) {
117133
auto &hfh = handle.Cast<HTTPFileHandle>();
118134
auto &http_util = hfh.http_params.http_util;
135+
136+
AddUserAgentIfAvailable(hfh.http_params, header_map);
137+
119138
string content_type = "application/octet-stream";
120139
PutRequestInfo put_request(url, header_map, hfh.http_params, (const_data_ptr_t)buffer_in, buffer_in_len,
121140
content_type);
@@ -125,6 +144,9 @@ unique_ptr<HTTPResponse> HTTPFileSystem::PutRequest(FileHandle &handle, string u
125144
unique_ptr<HTTPResponse> HTTPFileSystem::HeadRequest(FileHandle &handle, string url, HTTPHeaders header_map) {
126145
auto &hfh = handle.Cast<HTTPFileHandle>();
127146
auto &http_util = hfh.http_params.http_util;
147+
148+
AddUserAgentIfAvailable(hfh.http_params, header_map);
149+
128150
auto http_client = hfh.GetClient();
129151

130152
HeadRequestInfo head_request(url, header_map, hfh.http_params);
@@ -137,6 +159,9 @@ unique_ptr<HTTPResponse> HTTPFileSystem::HeadRequest(FileHandle &handle, string
137159
unique_ptr<HTTPResponse> HTTPFileSystem::DeleteRequest(FileHandle &handle, string url, HTTPHeaders header_map) {
138160
auto &hfh = handle.Cast<HTTPFileHandle>();
139161
auto &http_util = hfh.http_params.http_util;
162+
163+
AddUserAgentIfAvailable(hfh.http_params, header_map);
164+
140165
auto http_client = hfh.GetClient();
141166
DeleteRequestInfo delete_request(url, header_map, hfh.http_params);
142167
auto response = http_util.Request(delete_request, http_client);
@@ -160,6 +185,8 @@ unique_ptr<HTTPResponse> HTTPFileSystem::GetRequest(FileHandle &handle, string u
160185
auto &hfh = handle.Cast<HTTPFileHandle>();
161186
auto &http_util = hfh.http_params.http_util;
162187

188+
AddUserAgentIfAvailable(hfh.http_params, header_map);
189+
163190
D_ASSERT(hfh.cached_file_handle);
164191

165192
auto http_client = hfh.GetClient();
@@ -209,6 +236,8 @@ unique_ptr<HTTPResponse> HTTPFileSystem::GetRangeRequest(FileHandle &handle, str
209236
auto &hfh = handle.Cast<HTTPFileHandle>();
210237
auto &http_util = hfh.http_params.http_util;
211238

239+
AddUserAgentIfAvailable(hfh.http_params, header_map);
240+
212241
// send the Range header to read only subset of file
213242
string range_expr = "bytes=" + to_string(file_offset) + "-" + to_string(file_offset + buffer_out_len - 1);
214243
header_map.Insert("Range", range_expr);

extension/httpfs/include/httpfs_client.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct HTTPFSParams : public HTTPParams {
2222
bool enable_server_cert_verification = DEFAULT_ENABLE_SERVER_CERT_VERIFICATION;
2323
bool enable_curl_server_cert_verification = true;
2424
idx_t hf_max_per_page = DEFAULT_HF_MAX_PER_PAGE;
25+
string user_agent = {""};
2526
string ca_cert_file;
2627
string bearer_token;
2728
bool unsafe_disable_etag_checks {false};

0 commit comments

Comments
 (0)