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);