Class Utilities
-
Method Summary
Modifier and TypeMethodDescriptionstatic ExecutorServicecreateVirtualThreadsNewThreadPerTaskExecutor(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 Stringstatic StringtrimAggressively(String string) A "stronger" version ofString.trim()which discards any kind of whitespace or invisible separator.static StringtrimAggressivelyToEmpty(String string) static StringtrimAggressivelyToNull(String string) static BooleanDoes 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:
trueif the runtime supports virtual threads,falseotherwise
-
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
MethodHandlereferences.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:
HostForwardedOriginX-Forwarded-ProtoX-Forwarded-ProtocolX-Url-SchemeFront-End-HttpsX-Forwarded-SslX-Forwarded-HostX-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.comhttp://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
nullif the input string isnullor the trimmed representation is of length0
-
trimAggressivelyToNull
-
trimAggressivelyToEmpty
-