Class Utilities
-
Method Summary
Modifier and TypeMethodDescriptionstatic ExecutorService
createVirtualThreadsNewThreadPerTaskExecutor
(String threadNamePrefix, Thread.UncaughtExceptionHandler uncaughtExceptionHandler) Provides a virtual-thread-per-task executor service if supported by the runtime.static byte[]
extractCharsetFromHeaders
(Map<String, Set<String>> headers) extractCharsetFromHeaderValue
(String contentTypeHeaderValue) extractClientUrlPrefixFromHeaders
(Map<String, Set<String>> headers) Best-effort attempt to determine a client's URL prefix by examining request headers.extractContentTypeFromHeaders
(Map<String, Set<String>> headers) extractContentTypeFromHeaderValue
(String contentTypeHeaderValue) extractCookiesFromHeaders
(Map<String, Set<String>> headers) localesFromAcceptLanguageHeaderValue
(String acceptLanguageHeaderValue) static String
static String
trimAggressively
(String string) A "stronger" version ofString.trim()
which discards any kind of whitespace or invisible separator.static String
trimAggressivelyToEmpty
(String string) static String
trimAggressivelyToNull
(String string) static Boolean
Does the platform runtime support virtual threads (either Java 19 and 20 w/preview enabled or Java 21+)?
-
Method Details
-
virtualThreadsAvailable
Does the platform runtime support virtual threads (either Java 19 and 20 w/preview enabled or Java 21+)?- Returns:
true
if the runtime supports virtual threads,false
otherwise
-
createVirtualThreadsNewThreadPerTaskExecutor
@Nonnull public static ExecutorService createVirtualThreadsNewThreadPerTaskExecutor(@Nonnull String threadNamePrefix, @Nonnull Thread.UncaughtExceptionHandler uncaughtExceptionHandler) Provides a virtual-thread-per-task executor service if supported by the runtime.In order to support Soklet users who are not yet ready to enable virtual threads (those not running either Java 19 and 20 w/preview enabled or Java 21+), we compile Soklet with a source level < 19 and avoid any hard references to virtual threads by dynamically creating our executor service via
MethodHandle
references.You should not call this method if
virtualThreadsAvailable()
isfalse
.// This method is effectively equivalent to this code return Executors.newThreadPerTaskExecutor( Thread.ofVirtual() .name(threadNamePrefix) .uncaughtExceptionHandler(uncaughtExceptionHandler) .factory() );
- Parameters:
threadNamePrefix
- thread name prefix for the virtual thread factory builderuncaughtExceptionHandler
- uncaught exception handler for the virtual thread factory builder- Returns:
- a virtual-thread-per-task executor service
- Throws:
IllegalStateException
- if the runtime environment does not support virtual threads
-
emptyByteArray
-
extractQueryParametersFromQuery
-
extractQueryParametersFromUrl
-
extractCookiesFromHeaders
-
normalizedPathForUrl
-
localesFromAcceptLanguageHeaderValue
-
extractClientUrlPrefixFromHeaders
@Nonnull public static Optional<String> extractClientUrlPrefixFromHeaders(@Nonnull Map<String, Set<String>> headers) Best-effort attempt to determine a client's URL prefix by examining request headers.A URL prefix in this context is defined as
<scheme>://host<:optional port>
, but no path or query components.Soklet is generally the "last hop" behind a load balancer/reverse proxy and does get accessed directly by clients.
Normally a load balancer/reverse proxy/other upstream proxies will provide information about the true source of the request through headers like the following:
Host
Forwarded
Origin
X-Forwarded-Proto
X-Forwarded-Protocol
X-Url-Scheme
Front-End-Https
X-Forwarded-Ssl
X-Forwarded-Host
X-Forwarded-Port
This method may take these and other headers into account when determining URL prefix.
For example, the following would be legal URL prefixes returned from this method:
https://www.soklet.com
http://www.fake.com:1234
The following would NOT be legal URL prefixes:
www.soklet.com
(missing protocol)https://www.soklet.com/
(trailing slash)https://www.soklet.com/test
(trailing slash, path)https://www.soklet.com/test?abc=1234
(trailing slash, path, query)
- Parameters:
headers
- HTTP request headers- Returns:
- the URL prefix, or
Optional.empty()
if it could not be determined
-
extractContentTypeFromHeaders
-
extractContentTypeFromHeaderValue
-
extractCharsetFromHeaders
-
extractCharsetFromHeaderValue
-
trimAggressively
A "stronger" version ofString.trim()
which discards any kind of whitespace or invisible separator.In a web environment with user-supplied inputs, this is the behavior we want the vast majority of the time. For example, users copy-paste URLs from Microsoft Word or Outlook and it's easy to accidentally include a
U+202F "Narrow No-Break Space (NNBSP)"
character at the end, which might break parsing.See https://www.compart.com/en/unicode/U+202F for details.
- Parameters:
string
- the string to trim- Returns:
- the trimmed string, or
null
if the input string isnull
or the trimmed representation is of length0
-
trimAggressivelyToNull
-
trimAggressivelyToEmpty
-