<div dir="ltr">My first thought is that if you are computing the string maybe you'd want to look at the request. Or set a header for content type.<br><br>I'm not going to push hard until valhalla is at least in preview (+ we've already talked it to death) but a <font face="monospace">Body</font><font face="arial, sans-serif"> abstraction would probably solve your use-case more robustly than yet another method there.</font><br><br><font face="monospace">exchange -> exchange.sendResponse(200, Body.of("example"));</font><br style="font-family:monospace"></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, Apr 28, 2025 at 5:28 AM Pavel Rappo <<a href="mailto:pavel.rappo@gmail.com">pavel.rappo@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I'm using HttpServer to implement an HTTP probe [^1] that provides<br>
application state at the time of probing. I find that convenience<br>
handlers provided by HttpHandlers are insufficient for my use case. I<br>
also find that implementing a custom HttpHandler is tricky without the<br>
help of documentation.<br>
<br>
Perhaps my use case is typical enough so that HttpHandlers could<br>
provide a new convenience handler. That handler would send a<br>
dynamically supplied string, rather than a static string. If you also<br>
find it useful, I'd appreciate it if we could discuss it. Before I<br>
create a JBS issue, please have a look at this crude patch to see if<br>
it makes sense to you in principle. Thanks.<br>
<br>
[^1]: <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/" rel="noreferrer" target="_blank">https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/</a><br>
<br>
diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandlers.java<br>
b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandlers.java<br>
index 03642033914..987de0ede5d 100644<br>
--- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandlers.java<br>
+++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandlers.java<br>
@@ -25,9 +25,11 @@<br>
<br>
package com.sun.net.httpserver;<br>
<br>
+import java.io.OutputStream;<br>
import java.nio.charset.StandardCharsets;<br>
import java.util.Objects;<br>
import java.util.function.Predicate;<br>
+import java.util.function.Supplier;<br>
<br>
/**<br>
* Implementations of {@link com.sun.net.httpserver.HttpHandler HttpHandler}<br>
@@ -140,28 +142,60 @@ public static HttpHandler<br>
handleOrElse(Predicate<Request> handlerTest,<br>
* @throws NullPointerException if headers or body are null<br>
*/<br>
public static HttpHandler of(int statusCode, Headers headers,<br>
String body) {<br>
+ Objects.requireNonNull(body);<br>
+ return of(statusCode, headers, () -> body);<br>
+ }<br>
+<br>
+ /**<br>
+ * Returns an {@code HttpHandler} that sends a response<br>
comprising the given<br>
+ * {@code statusCode}, {@code headers}, and {@code body}.<br>
+ *<br>
+ * <p> This method creates a handler that reads and discards the request<br>
+ * body before it sets the response state and sends the response.<br>
+ *<br>
+ * <p> {@code headers} are the effective headers of the response. The<br>
+ * response <i>body bytes</i> are a {@code UTF-8} encoded byte sequence of<br>
+ * a string, which is supplied by {@code bodySupplier}<br>
immediately after the request body is read. The response headers<br>
+ * {@linkplain HttpExchange#sendResponseHeaders(int, long) are sent} with<br>
+ * the given {@code statusCode} and the body bytes' length (or {@code -1}<br>
+ * if the body is empty). The body bytes are then sent as response body,<br>
+ * unless the body is empty, in which case no response body is sent.<br>
+ *<br>
+ * @param statusCode a response status code<br>
+ * @param headers a headers<br>
+ * @param bodySupplier a supplier for the response body string<br>
+ * @return a handler<br>
+ * @throws IllegalArgumentException if statusCode is not a positive 3-digit<br>
+ * integer, as per rfc2616, section 6.1.1<br>
+ * @throws NullPointerException if headers or body are null<br>
+ */<br>
+ public static HttpHandler of(int statusCode, Headers headers,<br>
Supplier<String> bodySupplier) {<br>
if (statusCode < 100 || statusCode > 999)<br>
throw new IllegalArgumentException("statusCode must be 3-digit: "<br>
+ statusCode);<br>
Objects.requireNonNull(headers);<br>
- Objects.requireNonNull(body);<br>
+ Objects.requireNonNull(bodySupplier);<br>
<br>
final var headersCopy = Headers.of(headers);<br>
- final var bytes = body.getBytes(StandardCharsets.UTF_8);<br>
<br>
return exchange -> {<br>
try (exchange) {<br>
- exchange.getRequestBody().readAllBytes();<br>
+<br>
exchange.getRequestBody().transferTo(OutputStream.nullOutputStream());<br>
// discard<br>
exchange.getResponseHeaders().putAll(headersCopy);<br>
- if (exchange.getRequestMethod().equals("HEAD")) {<br>
-<br>
exchange.getResponseHeaders().set("Content-Length",<br>
Integer.toString(bytes.length));<br>
- exchange.sendResponseHeaders(statusCode, -1);<br>
- }<br>
- else if (bytes.length == 0) {<br>
- exchange.sendResponseHeaders(statusCode, -1);<br>
+ var body = bodySupplier.get();<br>
+ if (body == null) {<br>
+ exchange.sendResponseHeaders(500, -1); //<br>
Internal Server Error<br>
} else {<br>
- exchange.sendResponseHeaders(statusCode, bytes.length);<br>
- exchange.getResponseBody().write(bytes);<br>
+ final var bytes = body.getBytes(StandardCharsets.UTF_8);<br>
+ if (exchange.getRequestMethod().equals("HEAD")) {<br>
+<br>
exchange.getResponseHeaders().set("Content-Length",<br>
Integer.toString(bytes.length));<br>
+ exchange.sendResponseHeaders(statusCode, -1);<br>
+ } else if (bytes.length == 0) {<br>
+ exchange.sendResponseHeaders(statusCode, -1);<br>
+ } else {<br>
+ exchange.sendResponseHeaders(statusCode, bytes.length);<br>
+ exchange.getResponseBody().write(bytes);<br>
+ }<br>
}<br>
}<br>
};<br>
diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/HttpHandlersTest.java<br>
b/test/jdk/com/sun/net/httpserver/simpleserver/HttpHandlersTest.java<br>
index 85d271e44fa..d64fa03740f 100644<br>
--- a/test/jdk/com/sun/net/httpserver/simpleserver/HttpHandlersTest.java<br>
+++ b/test/jdk/com/sun/net/httpserver/simpleserver/HttpHandlersTest.java<br>
@@ -81,7 +81,7 @@ public void testNull() {<br>
final var headers = new Headers();<br>
final var body = "";<br>
assertThrows(NPE, () -> HttpHandlers.of(200, null, body));<br>
- assertThrows(NPE, () -> HttpHandlers.of(200, headers, null));<br>
+ assertThrows(NPE, () -> HttpHandlers.of(200, headers, (String) null));<br>
}<br>
<br>
@Test<br>
</blockquote></div>