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

cmcfarlen pushed a commit to branch 10.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit dbc07f88e5d5da08bf114d4ce57a0bdb198dd998
Author: Masaori Koshiba <[email protected]>
AuthorDate: Fri May 15 08:25:32 2026 +0900

    Restore a shortcut in hot loop in _mime_hdr_field_list_search_by_string 
(#13119)
    
    * Restore a shortcut in hot loop in _mime_hdr_field_list_search_by_string
    
    * Add ts::iequals(const std::string_view &, const std::string_view &)
    
    * Address issue from Copilot
    
    (cherry picked from commit e766d7a547ffd639899543e6eaed7037975930dd)
---
 include/tsutil/StringCompare.h        | 49 +++++++++++++++++++++++++++++++++++
 src/proxy/hdrs/MIME.cc                |  7 +++--
 src/proxy/http/HttpSM.cc              |  3 ++-
 src/proxy/http/HttpTransactHeaders.cc |  3 ++-
 4 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/include/tsutil/StringCompare.h b/include/tsutil/StringCompare.h
new file mode 100644
index 0000000000..fa054ccf4e
--- /dev/null
+++ b/include/tsutil/StringCompare.h
@@ -0,0 +1,49 @@
+/** @file
+
+  Helper for std::string_view comparison
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include <strings.h>
+#include <string_view>
+
+namespace ts
+{
+/**
+  Returns true iff @a lhs and @a rhs compare equal, ignoring case.
+
+  Prefer this over libswoc's @c strcasecmp(std::string_view, std::string_view) 
when you only need
+  an equality check: this short-circuits on length mismatch, whereas the 
libswoc version must keep
+  comparing bytes to produce a correct ordering result even when the lengths 
differ.
+
+  For case-sensitive comparison, use @c std::string_view::operator==.
+ */
+inline bool
+iequals(std::string_view lhs, std::string_view rhs) noexcept
+{
+  if (lhs.size() != rhs.size()) {
+    return false;
+  }
+
+  return ::strncasecmp(lhs.data(), rhs.data(), lhs.size()) == 0;
+}
+} // namespace ts
diff --git a/src/proxy/hdrs/MIME.cc b/src/proxy/hdrs/MIME.cc
index 869468a8cc..66f95c6bf2 100644
--- a/src/proxy/hdrs/MIME.cc
+++ b/src/proxy/hdrs/MIME.cc
@@ -24,6 +24,9 @@
 #include "tscore/ink_defs.h"
 #include "tscore/ink_platform.h"
 #include "tscore/ink_memory.h"
+
+#include "tsutil/StringCompare.h"
+
 #include <cassert>
 #include <cctype>
 #include <cstdio>
@@ -1161,8 +1164,8 @@ _mime_hdr_field_list_search_by_string(MIMEHdrImpl *mh, 
std::string_view field_na
     too_far_field = &(fblock->m_field_slots[fblock->m_freetop]);
     while (field < too_far_field) {
       if (field->is_live() &&
-          strcasecmp(std::string_view{field->m_ptr_name, 
static_cast<std::string_view::size_type>(field->m_len_name)},
-                     field_name) == 0) {
+          ts::iequals(std::string_view{field->m_ptr_name, 
static_cast<std::string_view::size_type>(field->m_len_name)},
+                      field_name)) {
         return field;
       }
       ++field;
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index 71a7b8181c..4a862bd177 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -25,6 +25,7 @@
 #include "proxy/http/HttpConfig.h"
 #include "tscore/ink_hrtime.h"
 #include "tsutil/Metrics.h"
+#include "tsutil/StringCompare.h"
 #include "tsutil/ts_bw_format.h"
 #include "proxy/ProxyTransaction.h"
 #include "proxy/http/HttpSM.h"
@@ -791,7 +792,7 @@ HttpSM::state_read_client_request_header(int event, void 
*data)
         (t_state.hdr_info.client_request.method_get_wksidx() == 
HTTP_WKSIDX_POST ||
          t_state.hdr_info.client_request.method_get_wksidx() == 
HTTP_WKSIDX_PUT)) {
       auto 
expect{t_state.hdr_info.client_request.value_get(static_cast<std::string_view>(MIME_FIELD_EXPECT))};
-      if (strcasecmp(expect, 
static_cast<std::string_view>(HTTP_VALUE_100_CONTINUE)) == 0) {
+      if (ts::iequals(expect, 
static_cast<std::string_view>(HTTP_VALUE_100_CONTINUE))) {
         // When receive an "Expect: 100-continue" request from client, ATS 
sends a "100 Continue" response to client
         // immediately, before receive the real response from original server.
         if (t_state.http_config_param->send_100_continue_response) {
diff --git a/src/proxy/http/HttpTransactHeaders.cc 
b/src/proxy/http/HttpTransactHeaders.cc
index 11e00c1bc1..fab348dd52 100644
--- a/src/proxy/http/HttpTransactHeaders.cc
+++ b/src/proxy/http/HttpTransactHeaders.cc
@@ -40,6 +40,7 @@
 
 #include "iocore/utils/Machine.h"
 #include "tsutil/DbgCtl.h"
+#include "tsutil/StringCompare.h"
 
 using namespace std::literals;
 
@@ -898,7 +899,7 @@ 
HttpTransactHeaders::remove_100_continue_headers(HttpTransact::State *s, HTTPHdr
 {
   auto 
expect{s->hdr_info.client_request.value_get(static_cast<std::string_view>(MIME_FIELD_EXPECT))};
 
-  if (strcasecmp(expect, 
static_cast<std::string_view>(HTTP_VALUE_100_CONTINUE)) == 0) {
+  if (ts::iequals(expect, 
static_cast<std::string_view>(HTTP_VALUE_100_CONTINUE))) {
     outgoing->field_delete(static_cast<std::string_view>(MIME_FIELD_EXPECT));
   }
 }

Reply via email to