This is an automated email from the ASF dual-hosted git repository.
masaori335 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new e766d7a547 Restore a shortcut in hot loop in
_mime_hdr_field_list_search_by_string (#13119)
e766d7a547 is described below
commit e766d7a547ffd639899543e6eaed7037975930dd
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
---
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 fc7fac251c..f8e25de040 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 12af2570b2..f1a113047a 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));
}
}