@@ -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+
104117unique_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
125144unique_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
137159unique_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);
0 commit comments