You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2021/10/31 18:47:55 UTC

[httpcomponents-core] branch master updated: Utility method to convert strings to their lower case representation

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

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/master by this push:
     new d0bf278  Utility method to convert strings to their lower case representation
d0bf278 is described below

commit d0bf278d200d8e1131008d0507923912107d2360
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Oct 31 19:12:12 2021 +0100

    Utility method to convert strings to their lower case representation
---
 .../http2/impl/DefaultH2RequestConverter.java      |  3 +--
 .../http2/impl/DefaultH2ResponseConverter.java     |  4 ++--
 .../core5/http2/examples/H2FileServerExample.java  |  4 ++--
 .../hc/core5/testing/nio/H2IntegrationTest.java    |  3 +--
 .../hc/core5/testing/nio/Http1IntegrationTest.java |  3 +--
 .../java/org/apache/hc/core5/http/ContentType.java |  5 ++---
 .../java/org/apache/hc/core5/http/HttpHost.java    |  3 +--
 .../org/apache/hc/core5/http/config/Registry.java  |  4 ++--
 .../hc/core5/http/config/RegistryBuilder.java      |  4 ++--
 .../hc/core5/http/message/BasicNameValuePair.java  |  4 ++--
 .../apache/hc/core5/http/message/HeaderGroup.java  |  4 ++--
 .../http/protocol/RequestHandlerRegistry.java      |  8 ++++----
 .../main/java/org/apache/hc/core5/net/Host.java    |  3 +--
 .../java/org/apache/hc/core5/net/URIBuilder.java   |  5 ++---
 .../hc/core5/reactor/InternalDataChannel.java      |  6 +++---
 .../java/org/apache/hc/core5/util/TextUtils.java   | 15 ++++++++++++++
 .../http/examples/AsyncFileServerExample.java      |  4 ++--
 .../http/examples/AsyncReverseProxyExample.java    | 24 +++++++++++-----------
 .../http/examples/ClassicReverseProxyExample.java  | 24 +++++++++++-----------
 19 files changed, 69 insertions(+), 61 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
index 7771ee5..ad94312 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
@@ -31,7 +31,6 @@ import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -193,7 +192,7 @@ public final class DefaultH2RequestConverter implements H2MessageConverter<HttpR
             if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
                 throw new ProtocolException("Header '%s: %s' is illegal for HTTP/2 messages", name, value);
             }
-            headers.add(new BasicHeader(name.toLowerCase(Locale.ROOT), value));
+            headers.add(new BasicHeader(TextUtils.toLowerCase(name), value));
         }
 
         return headers;
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
index 5f887d0..db71166 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
@@ -30,7 +30,6 @@ package org.apache.hc.core5.http2.impl;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -42,6 +41,7 @@ import org.apache.hc.core5.http.message.BasicHeader;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http2.H2MessageConverter;
 import org.apache.hc.core5.http2.H2PseudoResponseHeaders;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * HTTP/2 response converter.
@@ -126,7 +126,7 @@ public class DefaultH2ResponseConverter implements H2MessageConverter<HttpRespon
             if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
                 throw new ProtocolException("Header '%s: %s' is illegal for HTTP/2 messages", name, value);
             }
-            headers.add(new BasicHeader(name.toLowerCase(Locale.ROOT), value));
+            headers.add(new BasicHeader(TextUtils.toLowerCase(name), value));
         }
         return headers;
     }
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
index 5104751..c4d24f0 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
@@ -32,7 +32,6 @@ import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.List;
-import java.util.Locale;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
@@ -63,6 +62,7 @@ import org.apache.hc.core5.http2.impl.nio.bootstrap.H2ServerBootstrap;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.util.TextUtils;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
@@ -169,7 +169,7 @@ public class H2FileServerExample {
                         } else {
 
                             final ContentType contentType;
-                            final String filename = file.getName().toLowerCase(Locale.ROOT);
+                            final String filename = TextUtils.toLowerCase(file.getName());
                             if (filename.endsWith(".txt")) {
                                 contentType = ContentType.TEXT_PLAIN;
                             } else if (filename.endsWith(".html") || filename.endsWith(".htm")) {
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
index cb761b3..19c127e 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
@@ -46,7 +46,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Queue;
 import java.util.StringTokenizer;
@@ -860,7 +859,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
         Assert.assertEquals(2, trailers.size());
         final Map<String, String> map = new HashMap<>();
         for (final Header header: trailers) {
-            map.put(header.getName().toLowerCase(Locale.ROOT), header.getValue());
+            map.put(TextUtils.toLowerCase(header.getName()), header.getValue());
         }
         final String digest = TextUtils.toHexString(entityConsumer.getDigest());
         Assert.assertEquals("MD5", map.get("digest-algo"));
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 3a05ffb..f27927f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -47,7 +47,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Queue;
 import java.util.Random;
@@ -1618,7 +1617,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
         Assert.assertEquals(2, trailers.size());
         final Map<String, String> map = new HashMap<>();
         for (final Header header: trailers) {
-            map.put(header.getName().toLowerCase(Locale.ROOT), header.getValue());
+            map.put(TextUtils.toLowerCase(header.getName()), header.getValue());
         }
         final String digest = TextUtils.toHexString(entityConsumer.getDigest());
         Assert.assertEquals("MD5", map.get("digest-algo"));
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/ContentType.java b/httpcore5/src/main/java/org/apache/hc/core5/http/ContentType.java
index bfcbcb4..4fae21c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/ContentType.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/ContentType.java
@@ -36,7 +36,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 import org.apache.hc.core5.annotation.Contract;
@@ -312,7 +311,7 @@ public final class ContentType implements Serializable {
      * @return content type
      */
     public static ContentType create(final String mimeType, final Charset charset) {
-        final String normalizedMimeType = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.ROOT);
+        final String normalizedMimeType = TextUtils.toLowerCase(Args.notBlank(mimeType, "MIME type"));
         Args.check(valid(normalizedMimeType), "MIME type may not contain reserved characters");
         return new ContentType(normalizedMimeType, charset);
     }
@@ -386,7 +385,7 @@ public final class ContentType implements Serializable {
      */
     public static ContentType create(
             final String mimeType, final NameValuePair... params) throws UnsupportedCharsetException {
-        final String type = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.ROOT);
+        final String type = TextUtils.toLowerCase(Args.notBlank(mimeType, "MIME type"));
         Args.check(valid(type), "MIME type may not contain reserved characters");
         return create(mimeType, params, true);
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/HttpHost.java b/httpcore5/src/main/java/org/apache/hc/core5/http/HttpHost.java
index d2b38e5..ea8c984 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/HttpHost.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/HttpHost.java
@@ -31,7 +31,6 @@ import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.Locale;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
@@ -83,7 +82,7 @@ public final class HttpHost implements NamedEndpoint, Serializable {
     public HttpHost(final String scheme, final InetAddress address, final String hostname, final int port) {
         Args.containsNoBlanks(hostname, "Host name");
         this.host = new Host(hostname, port);
-        this.schemeName = scheme != null ? scheme.toLowerCase(Locale.ROOT) : DEFAULT_SCHEME.id;
+        this.schemeName = scheme != null ? TextUtils.toLowerCase(scheme) : DEFAULT_SCHEME.id;
         this.address = address;
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/config/Registry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/config/Registry.java
index 3373806..c9d9ed8 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/config/Registry.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/config/Registry.java
@@ -27,12 +27,12 @@
 
 package org.apache.hc.core5.http.config;
 
-import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * Generic registry of items keyed by low-case string ID.
@@ -54,7 +54,7 @@ public final class Registry<I> implements Lookup<I> {
         if (key == null) {
             return null;
         }
-        return map.get(key.toLowerCase(Locale.ROOT));
+        return map.get(TextUtils.toLowerCase(key));
     }
 
     @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/config/RegistryBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/config/RegistryBuilder.java
index 8cbd540..3f804b5 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/config/RegistryBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/config/RegistryBuilder.java
@@ -28,10 +28,10 @@
 package org.apache.hc.core5.http.config;
 
 import java.util.HashMap;
-import java.util.Locale;
 import java.util.Map;
 
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * Builder for {@link Registry} instances.
@@ -54,7 +54,7 @@ public final class RegistryBuilder<I> {
     public RegistryBuilder<I> register(final String id, final I item) {
         Args.notEmpty(id, "ID");
         Args.notNull(item, "Item");
-        items.put(id.toLowerCase(Locale.ROOT), item);
+        items.put(TextUtils.toLowerCase(id), item);
         return this;
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicNameValuePair.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicNameValuePair.java
index 28e6407..b121cf2 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicNameValuePair.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicNameValuePair.java
@@ -28,13 +28,13 @@
 package org.apache.hc.core5.http.message;
 
 import java.io.Serializable;
-import java.util.Locale;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.http.NameValuePair;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.LangUtils;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * Basic implementation of {@link NameValuePair}.
@@ -101,7 +101,7 @@ public class BasicNameValuePair implements NameValuePair, Serializable {
     @Override
     public int hashCode() {
         int hash = LangUtils.HASH_SEED;
-        hash = LangUtils.hashCode(hash, this.name.toLowerCase(Locale.ROOT));
+        hash = LangUtils.hashCode(hash, TextUtils.toLowerCase(this.name));
         hash = LangUtils.hashCode(hash, this.value);
         return hash;
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/HeaderGroup.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/HeaderGroup.java
index fb39384..0d04d35 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/HeaderGroup.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/HeaderGroup.java
@@ -32,13 +32,13 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.MessageHeaders;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.util.CharArrayBuffer;
 import org.apache.hc.core5.util.LangUtils;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * A class for combining a set of headers. This class allows for multiple headers with the same name
@@ -195,7 +195,7 @@ public class HeaderGroup implements MessageHeaders, Serializable {
                 valueBuffer.append(hdrs[i].getValue());
             }
 
-            return new BasicHeader(name.toLowerCase(Locale.ROOT), valueBuffer.toString());
+            return new BasicHeader(TextUtils.toLowerCase(name), valueBuffer.toString());
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
index 8262898..deabcd1 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
@@ -27,7 +27,6 @@
 
 package org.apache.hc.core5.http.protocol;
 
-import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -39,6 +38,7 @@ import org.apache.hc.core5.http.HttpRequestMapper;
 import org.apache.hc.core5.http.MisdirectedRequestException;
 import org.apache.hc.core5.net.URIAuthority;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.TextUtils;
 
 /**
  * Generic registry of request handlers that can be resolved by properties of request messages.
@@ -59,7 +59,7 @@ public class RequestHandlerRegistry<T> implements HttpRequestMapper<T> {
     private final ConcurrentMap<String, LookupRegistry<T>> virtualMap;
 
     public RequestHandlerRegistry(final String canonicalHostName, final Supplier<LookupRegistry<T>> registrySupplier) {
-        this.canonicalHostName = Args.notNull(canonicalHostName, "Canonical hostname").toLowerCase(Locale.ROOT);
+        this.canonicalHostName = TextUtils.toLowerCase(Args.notNull(canonicalHostName, "Canonical hostname"));
         this.registrySupplier = registrySupplier != null ? registrySupplier : UriPatternMatcher::new;
         this.primary = this.registrySupplier.get();
         this.virtualMap = new ConcurrentHashMap<>();
@@ -88,7 +88,7 @@ public class RequestHandlerRegistry<T> implements HttpRequestMapper<T> {
     @Override
     public T resolve(final HttpRequest request, final HttpContext context) throws MisdirectedRequestException {
         final URIAuthority authority = request.getAuthority();
-        final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
+        final String key = authority != null ? TextUtils.toLowerCase(authority.getHostName()) : null;
         final LookupRegistry<T> patternMatcher = getPatternMatcher(key);
         if (patternMatcher == null) {
             throw new MisdirectedRequestException("Not authoritative");
@@ -106,7 +106,7 @@ public class RequestHandlerRegistry<T> implements HttpRequestMapper<T> {
         if (object == null) {
             return;
         }
-        final String key = hostname != null ? hostname.toLowerCase(Locale.ROOT) : null;
+        final String key = TextUtils.toLowerCase(hostname);
         if (hostname == null || hostname.equals(canonicalHostName) || hostname.equals(LOCALHOST)) {
             primary.register(uriPattern, object);
         } else {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java b/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java
index 2feda01..3ef6192 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java
@@ -28,7 +28,6 @@ package org.apache.hc.core5.net;
 
 import java.io.Serializable;
 import java.net.URISyntaxException;
-import java.util.Locale;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
@@ -55,7 +54,7 @@ public final class Host implements NamedEndpoint, Serializable {
         super();
         this.name = Args.notNull(name, "Host name");
         this.port = Ports.checkWithDefault(port);
-        this.lcName = this.name.toLowerCase(Locale.ROOT);
+        this.lcName = TextUtils.toLowerCase(this.name);
     }
 
     static Host parse(final CharSequence s, final Tokenizer.Cursor cursor) throws URISyntaxException {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
index 74ece31..6e2cce3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
@@ -37,7 +37,6 @@ import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collections;
 import java.util.List;
-import java.util.Locale;
 import java.util.Stack;
 
 import org.apache.hc.core5.http.HttpHost;
@@ -1011,7 +1010,7 @@ public class URIBuilder {
     public URIBuilder normalizeSyntax() {
         final String scheme = this.scheme;
         if (scheme != null) {
-            this.scheme = scheme.toLowerCase(Locale.ROOT);
+            this.scheme = TextUtils.toLowerCase(scheme);
         }
 
         if (this.pathRootless) {
@@ -1028,7 +1027,7 @@ public class URIBuilder {
 
         final String host = this.host;
         if (host != null) {
-            this.host = host.toLowerCase(Locale.ROOT);
+            this.host = TextUtils.toLowerCase(host);
         }
 
         if (this.pathSegments != null) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index 82cc940..b069cc3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -32,7 +32,6 @@ import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
-import java.util.Locale;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -57,6 +56,7 @@ import org.apache.hc.core5.reactor.ssl.TlsDetails;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Asserts;
+import org.apache.hc.core5.util.TextUtils;
 import org.apache.hc.core5.util.Timeout;
 
 final class InternalDataChannel extends InternalChannel implements ProtocolIOSession {
@@ -413,7 +413,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
     @Override
     public void switchProtocol(final String protocolId, final FutureCallback<ProtocolIOSession> callback) {
         Args.notEmpty(protocolId, "Application protocol ID");
-        final ProtocolUpgradeHandler upgradeHandler = protocolUpgradeHandlerMap.get(protocolId.toLowerCase(Locale.ROOT));
+        final ProtocolUpgradeHandler upgradeHandler = protocolUpgradeHandlerMap.get(TextUtils.toLowerCase(protocolId));
         if (upgradeHandler != null) {
             upgradeHandler.upgrade(this, callback);
         } else {
@@ -425,7 +425,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
     public void registerProtocol(final String protocolId, final ProtocolUpgradeHandler upgradeHandler) {
         Args.notEmpty(protocolId, "Application protocol ID");
         Args.notNull(upgradeHandler, "Protocol upgrade handler");
-        protocolUpgradeHandlerMap.put(protocolId.toLowerCase(Locale.ROOT), upgradeHandler);
+        protocolUpgradeHandlerMap.put(TextUtils.toLowerCase(protocolId), upgradeHandler);
     }
 
     @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/util/TextUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/util/TextUtils.java
index 431dd75..a8b6a6e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/util/TextUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/util/TextUtils.java
@@ -27,6 +27,8 @@
 
 package org.apache.hc.core5.util;
 
+import java.util.Locale;
+
 /**
  * @since 4.3
  */
@@ -126,4 +128,17 @@ public final class TextUtils {
         return buffer.toString();
     }
 
+    /**
+     * Returns lower case representation of the given string
+     * using {@link Locale#ROOT}.
+     *
+     * @since 5.2
+     */
+    public static String toLowerCase(final String s) {
+        if (s == null) {
+            return null;
+        }
+        return s.toLowerCase(Locale.ROOT);
+    }
+
 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
index 6ada5ce..b4817bc 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
@@ -31,7 +31,6 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.Locale;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
@@ -58,6 +57,7 @@ import org.apache.hc.core5.http.protocol.HttpDateGenerator;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.util.TextUtils;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
@@ -133,7 +133,7 @@ public class AsyncFileServerExample {
                         } else {
 
                             final ContentType contentType;
-                            final String filename = file.getName().toLowerCase(Locale.ROOT);
+                            final String filename = TextUtils.toLowerCase(file.getName());
                             if (filename.endsWith(".txt")) {
                                 contentType = ContentType.TEXT_PLAIN;
                             } else if (filename.endsWith(".html") || filename.endsWith(".htm")) {
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
index b0f3288..96726c7 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
@@ -37,7 +37,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -80,6 +79,7 @@ import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.ConnPoolStats;
 import org.apache.hc.core5.pool.PoolStats;
 import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.util.TextUtils;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
 
@@ -449,15 +449,15 @@ public class AsyncReverseProxyExample {
     private static class OutgoingExchangeHandler implements AsyncClientExchangeHandler {
 
         private final static Set<String> HOP_BY_HOP = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-                        HttpHeaders.HOST.toLowerCase(Locale.ROOT),
-                        HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ROOT),
-                        HttpHeaders.TRANSFER_ENCODING.toLowerCase(Locale.ROOT),
-                        HttpHeaders.CONNECTION.toLowerCase(Locale.ROOT),
-                        HttpHeaders.KEEP_ALIVE.toLowerCase(Locale.ROOT),
-                        HttpHeaders.PROXY_AUTHENTICATE.toLowerCase(Locale.ROOT),
-                        HttpHeaders.TE.toLowerCase(Locale.ROOT),
-                        HttpHeaders.TRAILER.toLowerCase(Locale.ROOT),
-                        HttpHeaders.UPGRADE.toLowerCase(Locale.ROOT))));
+                TextUtils.toLowerCase(HttpHeaders.HOST),
+                TextUtils.toLowerCase(HttpHeaders.CONTENT_LENGTH),
+                TextUtils.toLowerCase(HttpHeaders.TRANSFER_ENCODING),
+                TextUtils.toLowerCase(HttpHeaders.CONNECTION),
+                TextUtils.toLowerCase(HttpHeaders.KEEP_ALIVE),
+                TextUtils.toLowerCase(HttpHeaders.PROXY_AUTHENTICATE),
+                TextUtils.toLowerCase(HttpHeaders.TE),
+                TextUtils.toLowerCase(HttpHeaders.TRAILER),
+                TextUtils.toLowerCase(HttpHeaders.UPGRADE))));
 
         private final HttpHost targetHost;
         private final AsyncClientEndpoint clientEndpoint;
@@ -484,7 +484,7 @@ public class AsyncReverseProxyExample {
                         incomingRequest.getPath());
                 for (final Iterator<Header> it = incomingRequest.headerIterator(); it.hasNext(); ) {
                     final Header header = it.next();
-                    if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT))) {
+                    if (!HOP_BY_HOP.contains(TextUtils.toLowerCase(header.getName()))) {
                         outgoingRequest.addHeader(header);
                     }
                 }
@@ -551,7 +551,7 @@ public class AsyncReverseProxyExample {
                 final HttpResponse outgoingResponse = new BasicHttpResponse(incomingResponse.getCode());
                 for (final Iterator<Header> it = incomingResponse.headerIterator(); it.hasNext(); ) {
                     final Header header = it.next();
-                    if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT))) {
+                    if (!HOP_BY_HOP.contains(TextUtils.toLowerCase(header.getName()))) {
                         outgoingResponse.addHeader(header);
                     }
                 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
index c066aec..b2fc535 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
@@ -34,7 +34,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Locale;
 import java.util.Set;
 
 import org.apache.hc.core5.http.ClassicHttpRequest;
@@ -61,6 +60,7 @@ import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.ConnPoolStats;
 import org.apache.hc.core5.pool.PoolStats;
+import org.apache.hc.core5.util.TextUtils;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
 
@@ -187,15 +187,15 @@ public class ClassicReverseProxyExample {
     }
 
     private final static Set<String> HOP_BY_HOP = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-            HttpHeaders.HOST.toLowerCase(Locale.ROOT),
-            HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ROOT),
-            HttpHeaders.TRANSFER_ENCODING.toLowerCase(Locale.ROOT),
-            HttpHeaders.CONNECTION.toLowerCase(Locale.ROOT),
-            HttpHeaders.KEEP_ALIVE.toLowerCase(Locale.ROOT),
-            HttpHeaders.PROXY_AUTHENTICATE.toLowerCase(Locale.ROOT),
-            HttpHeaders.TE.toLowerCase(Locale.ROOT),
-            HttpHeaders.TRAILER.toLowerCase(Locale.ROOT),
-            HttpHeaders.UPGRADE.toLowerCase(Locale.ROOT))));
+            TextUtils.toLowerCase(HttpHeaders.HOST),
+            TextUtils.toLowerCase(HttpHeaders.CONTENT_LENGTH),
+            TextUtils.toLowerCase(HttpHeaders.TRANSFER_ENCODING),
+            TextUtils.toLowerCase(HttpHeaders.CONNECTION),
+            TextUtils.toLowerCase(HttpHeaders.KEEP_ALIVE),
+            TextUtils.toLowerCase(HttpHeaders.PROXY_AUTHENTICATE),
+            TextUtils.toLowerCase(HttpHeaders.TE),
+            TextUtils.toLowerCase(HttpHeaders.TRAILER),
+            TextUtils.toLowerCase(HttpHeaders.UPGRADE))));
 
 
     static class ProxyHandler implements HttpRequestHandler  {
@@ -224,7 +224,7 @@ public class ClassicReverseProxyExample {
                     incomingRequest.getPath());
             for (final Iterator<Header> it = incomingRequest.headerIterator(); it.hasNext(); ) {
                 final Header header = it.next();
-                if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT))) {
+                if (!HOP_BY_HOP.contains(TextUtils.toLowerCase(header.getName()))) {
                     outgoingRequest.addHeader(header);
                 }
             }
@@ -234,7 +234,7 @@ public class ClassicReverseProxyExample {
             outgoingResponse.setCode(incomingResponse.getCode());
             for (final Iterator<Header> it = incomingResponse.headerIterator(); it.hasNext(); ) {
                 final Header header = it.next();
-                if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT))) {
+                if (!HOP_BY_HOP.contains(TextUtils.toLowerCase(header.getName()))) {
                     outgoingResponse.addHeader(header);
                 }
             }