This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 5272a68c13 GH-48966: [C++] Fix cookie duplication in the Flight SQL 
ODBC driver and the Flight Client (#48967)
5272a68c13 is described below

commit 5272a68c134deea82040f2f29bb6257ad7b52be0
Author: Jianfeng Mao <[email protected]>
AuthorDate: Mon Jan 26 18:23:21 2026 -0700

    GH-48966: [C++] Fix cookie duplication in the Flight SQL ODBC driver and 
the Flight Client (#48967)
    
    
    ### Rationale for this change
    
    The bug breaks a Flight SQL server that refreshens the auth token when 
cookie authentication is enabled
    
    ### What changes are included in this PR?
    
    1. In the ODBC layer, removed the code that adds a 2nd 
ClientCookieMiddlewareFactory in the client options (the 1st one is registered 
in `BuildFlightClientOptions`). This fixes the issue of the duplicate header 
cookie fields.
    2. In the flight client layer, uses the case-insensitive equality 
comparator instead of the case-insensitive less-than comparator for the cookies 
cache which is an unordered map. This fixes the issue of duplicate cookie keys.
    
    ### Are these changes tested?
    Manually on Windows, and CI
    
    ### Are there any user-facing changes?
    
    No
    * GitHub Issue: #48966
    
    Authored-by: jianfengmao <[email protected]>
    Signed-off-by: David Li <[email protected]>
---
 cpp/src/arrow/flight/cookie_internal.cc                          | 5 +++++
 cpp/src/arrow/flight/cookie_internal.h                           | 8 +++++++-
 cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc | 3 ---
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/cpp/src/arrow/flight/cookie_internal.cc 
b/cpp/src/arrow/flight/cookie_internal.cc
index 99fa8b238d..df09a77afb 100644
--- a/cpp/src/arrow/flight/cookie_internal.cc
+++ b/cpp/src/arrow/flight/cookie_internal.cc
@@ -64,6 +64,11 @@ size_t CaseInsensitiveHash::operator()(const std::string& 
key) const {
   return std::hash<std::string>{}(upper_string);
 }
 
+bool CaseInsensitiveEqual::operator()(const std::string& lhs,
+                                      const std::string& rhs) const {
+  return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
+}
+
 Cookie Cookie::Parse(std::string_view cookie_header_value) {
   // Parse the cookie string. If the cookie has an expiration, record it.
   // If the cookie has a max-age, calculate the current time + max_age and set 
that as
diff --git a/cpp/src/arrow/flight/cookie_internal.h 
b/cpp/src/arrow/flight/cookie_internal.h
index 62c0390c58..98b936edb3 100644
--- a/cpp/src/arrow/flight/cookie_internal.h
+++ b/cpp/src/arrow/flight/cookie_internal.h
@@ -41,6 +41,12 @@ class ARROW_FLIGHT_EXPORT CaseInsensitiveComparator {
   bool operator()(const std::string& t1, const std::string& t2) const;
 };
 
+/// \brief Case insensitive equality comparator for use by unordered cookie 
map.
+class ARROW_FLIGHT_EXPORT CaseInsensitiveEqual {
+ public:
+  bool operator()(const std::string& lhs, const std::string& rhs) const;
+};
+
 /// \brief Case insensitive hasher for use by cookie caching map. Cookies are 
not
 /// case-sensitive.
 class ARROW_FLIGHT_EXPORT CaseInsensitiveHash {
@@ -117,7 +123,7 @@ class ARROW_FLIGHT_EXPORT CookieCache {
 
   // Mutex must be used to protect cookie cache.
   std::mutex mutex_;
-  std::unordered_map<std::string, Cookie, CaseInsensitiveHash, 
CaseInsensitiveComparator>
+  std::unordered_map<std::string, Cookie, CaseInsensitiveHash, 
CaseInsensitiveEqual>
       cookies;
 };
 
diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc 
b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc
index 422c45fc05..8b2b564d8d 100644
--- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc
+++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc
@@ -157,9 +157,6 @@ void FlightSqlConnection::Connect(const ConnPropertyMap& 
properties,
     client_options_ =
         BuildFlightClientOptions(properties, missing_attr, flight_ssl_configs);
 
-    const std::shared_ptr<ClientMiddlewareFactory>& cookie_factory = 
GetCookieFactory();
-    client_options_.middleware.push_back(cookie_factory);
-
     std::unique_ptr<FlightClient> flight_client;
     ThrowIfNotOK(FlightClient::Connect(location, 
client_options_).Value(&flight_client));
     PopulateMetadataSettings(properties);

Reply via email to