High-performance HTTP server implementation built on Java 21 Virtual Threads for Helidon microservices framework
—
Complete HTTP/1.1 protocol implementation with connection management, request parsing, response generation, and upgrade capabilities for handling HTTP/1.1 communications.
Configuration interface for HTTP/1.1 protocol settings and behavior.
/**
* Configuration for HTTP/1.1 protocol.
*/
interface Http1Config extends Prototype.Api {
/**
* Create builder for HTTP/1.1 configuration.
* @return configuration builder
*/
static Builder builder();
/**
* Get maximum header size allowed.
* @return maximum header size in bytes
*/
int maxHeaderSize();
/**
* Get maximum initial line length.
* @return maximum initial line length
*/
int maxInitialLineLength();
/**
* Get maximum chunk size for chunked encoding.
* @return maximum chunk size
*/
int maxChunkSize();
/**
* Check if request validation is enabled.
* @return true if request validation enabled
*/
boolean validateRequestHeaders();
/**
* Check if host header validation is enabled.
* @return true if host header validation enabled
*/
boolean validateHostHeader();
/**
* Check if continue processing is enabled for Expect: 100-continue.
* @return true if continue processing enabled
*/
boolean continueImmediately();
/**
* Get connection idle timeout.
* @return idle timeout duration
*/
Duration connectionIdleTimeout();
/**
* Check if pipelining is enabled.
* @return true if HTTP/1.1 pipelining enabled
*/
boolean enablePipelining();
/**
* Get maximum number of pipelined requests.
* @return maximum pipelined requests
*/
int maxPipelinedRequests();
}Usage Examples:
import io.helidon.webserver.http1.Http1Config;
import java.time.Duration;
// Basic HTTP/1.1 configuration
Http1Config basicConfig = Http1Config.builder()
.maxHeaderSize(8192)
.maxInitialLineLength(4096)
.validateRequestHeaders(true)
.build();
// High-performance HTTP/1.1 configuration
Http1Config highPerfConfig = Http1Config.builder()
.maxHeaderSize(16384)
.maxInitialLineLength(8192)
.maxChunkSize(65536)
.validateRequestHeaders(true)
.validateHostHeader(true)
.continueImmediately(true)
.connectionIdleTimeout(Duration.ofMinutes(5))
.enablePipelining(true)
.maxPipelinedRequests(100)
.build();
// Use in server configuration
WebServerConfig serverConfig = WebServerConfig.builder()
.port(8080)
.addProtocol(highPerfConfig)
.routing(HttpRouting.builder()
.get("/", (req, res) -> res.send("Hello HTTP/1.1"))
.build())
.build();HTTP/1.1 connection implementation handling individual client connections.
/**
* HTTP/1.1 connection implementation.
*/
class Http1Connection implements ServerConnection {
/**
* Get connection channel.
* @return connection channel
*/
SocketChannel channel();
/**
* Get connection context.
* @return connection context
*/
ConnectionContext context();
/**
* Check if connection is secure (TLS).
* @return true if secure connection
*/
boolean isSecure();
/**
* Get local address.
* @return local socket address
*/
SocketAddress localAddress();
/**
* Get remote address.
* @return remote socket address
*/
SocketAddress remoteAddress();
/**
* Close the connection.
*/
void close();
/**
* Check if connection is still active.
* @return true if connection active
*/
boolean isActive();
/**
* Handle connection lifecycle.
*/
void handle();
}HTTP/1.1 server request implementation for processing incoming requests.
/**
* HTTP/1.1 server request implementation.
*/
class Http1ServerRequest implements ServerRequest {
/**
* Get HTTP method.
* @return HTTP method
*/
Method method();
/**
* Get request URI.
* @return request URI
*/
UriInfo requestedUri();
/**
* Get request headers.
* @return HTTP/1.1 headers
*/
Http1Headers headers();
/**
* Get request entity.
* @return request entity
*/
ServerRequestEntity entity();
/**
* Get path information.
* @return server request path
*/
ServerRequestPath path();
/**
* Get query parameters.
* @return query parameters
*/
Parameters query();
/**
* Get HTTP version.
* @return HTTP version (1.1)
*/
Version version();
/**
* Get connection information.
* @return connection details
*/
ConnectionInfo connectionInfo();
/**
* Get request context.
* @return request context
*/
Context context();
}HTTP/1.1 server response implementation for generating responses.
/**
* HTTP/1.1 server response implementation.
*/
class Http1ServerResponse implements ServerResponse {
/**
* Set response status.
* @param status HTTP status
* @return this response for chaining
*/
Http1ServerResponse status(Status status);
/**
* Set response headers.
* @param headers response headers
* @return this response for chaining
*/
Http1ServerResponse headers(WritableHeaders<?> headers);
/**
* Add response header.
* @param name header name
* @param value header value
* @return this response for chaining
*/
Http1ServerResponse header(String name, String value);
/**
* Set content type.
* @param contentType media type
* @return this response for chaining
*/
Http1ServerResponse contentType(MediaType contentType);
/**
* Send response with content.
* @param entity response content
*/
void send(String entity);
/**
* Send response with binary content.
* @param entity binary content
*/
void send(byte[] entity);
/**
* Send response with stream content.
* @param entity input stream
*/
void send(InputStream entity);
/**
* Send empty response.
*/
void send();
/**
* Get output stream for streaming responses.
* @return output stream
*/
OutputStream outputStream();
/**
* Check if headers have been sent.
* @return true if headers sent
*/
boolean headersSent();
/**
* Close the response.
*/
void close();
}HTTP/1.1 headers implementation with case-insensitive header handling.
/**
* HTTP/1.1 headers implementation.
*/
class Http1Headers implements ServerRequestHeaders {
/**
* Get header value.
* @param name header name (case-insensitive)
* @return optional header value
*/
Optional<String> first(String name);
/**
* Get all header values.
* @param name header name (case-insensitive)
* @return list of header values
*/
List<String> all(String name);
/**
* Check if header exists.
* @param name header name (case-insensitive)
* @return true if header exists
*/
boolean contains(String name);
/**
* Get all header names.
* @return set of header names
*/
Set<String> names();
/**
* Get content type header.
* @return optional media type
*/
Optional<MediaType> contentType();
/**
* Get content length header.
* @return optional content length
*/
OptionalLong contentLength();
/**
* Get accept header values.
* @return list of accepted media types
*/
List<MediaType> acceptedTypes();
/**
* Convert to map.
* @return map of headers
*/
Map<String, List<String>> toMap();
}Usage Examples:
// Custom HTTP/1.1 request handler
Handler http1Handler = (req, res) -> {
if (req instanceof Http1ServerRequest http1Request) {
// Access HTTP/1.1 specific features
Http1Headers headers = http1Request.headers();
Version version = http1Request.version(); // Will be HTTP/1.1
// Check specific HTTP/1.1 headers
Optional<String> connection = headers.first("Connection");
Optional<String> transferEncoding = headers.first("Transfer-Encoding");
boolean keepAlive = connection.map(c -> c.toLowerCase().contains("keep-alive"))
.orElse(false);
String response = String.format(
"HTTP Version: %s, Keep-Alive: %s",
version, keepAlive
);
if (res instanceof Http1ServerResponse http1Response) {
// HTTP/1.1 specific response handling
if (keepAlive) {
http1Response.header("Connection", "keep-alive");
}
http1Response.send(response);
}
}
};HTTP/1.1 request prologue (request line) parsing and handling.
/**
* HTTP/1.1 request prologue (request line).
*/
class Http1Prologue {
/**
* Get HTTP method from prologue.
* @return HTTP method
*/
Method method();
/**
* Get request URI from prologue.
* @return request URI
*/
UriInfo uri();
/**
* Get HTTP version from prologue.
* @return HTTP version
*/
Version version();
/**
* Get raw request line.
* @return raw request line string
*/
String rawRequestLine();
/**
* Parse prologue from request line.
* @param requestLine raw request line
* @return parsed prologue
*/
static Http1Prologue parse(String requestLine);
/**
* Validate prologue format.
* @return true if prologue is valid
*/
boolean isValid();
}Components for managing HTTP/1.1 connections and lifecycle.
/**
* HTTP/1.1 connection selector for choosing connections.
*/
class Http1ConnectionSelector implements ServerConnectionSelector {
/**
* Select connection for request.
* @param context connection context
* @return selected connection
*/
ServerConnection select(ConnectionContext context);
/**
* Release connection after use.
* @param connection connection to release
*/
void release(ServerConnection connection);
}
/**
* HTTP/1.1 connection provider for creating connections.
*/
class Http1ConnectionProvider implements ServerConnectionSelectorProvider {
/**
* Create connection selector.
* @param config connection selector configuration
* @return connection selector
*/
ServerConnectionSelector create(Http1ConnectionSelectorConfig config);
/**
* Get provider name.
* @return provider name
*/
String name();
/**
* Get configuration type.
* @return configuration class
*/
Class<? extends ProtocolConfig> configType();
}
/**
* HTTP/1.1 connection listener for connection events.
*/
interface Http1ConnectionListener {
/**
* Called when connection is established.
* @param connection the established connection
*/
void connectionOpened(Http1Connection connection);
/**
* Called when connection is closed.
* @param connection the closed connection
*/
void connectionClosed(Http1Connection connection);
/**
* Called when request is received.
* @param connection the connection
* @param request the received request
*/
void requestReceived(Http1Connection connection, Http1ServerRequest request);
/**
* Called when response is sent.
* @param connection the connection
* @param response the sent response
*/
void responseSent(Http1Connection connection, Http1ServerResponse response);
}Configuration components for HTTP/1.1 protocol setup.
/**
* HTTP/1.1 protocol configuration provider.
*/
class Http1ProtocolConfigProvider implements ProtocolConfigProvider {
/**
* Get configuration type supported by this provider.
* @return HTTP/1.1 configuration class
*/
Class<Http1Config> configType();
/**
* Create protocol configuration.
* @param config configuration source
* @return protocol configuration
*/
ProtocolConfig create(Config config);
/**
* Get provider name.
* @return provider name ("http_1_1")
*/
String protocolType();
}Http1Config keepAliveConfig = Http1Config.builder()
.connectionIdleTimeout(Duration.ofMinutes(5))
.enablePipelining(false) // Disable for better compatibility
.continueImmediately(true)
.build();
// Handler that works with keep-alive connections
Handler keepAliveHandler = (req, res) -> {
Http1Headers headers = ((Http1ServerRequest) req).headers();
Optional<String> connection = headers.first("Connection");
boolean keepAlive = connection
.map(c -> c.toLowerCase().contains("keep-alive"))
.orElse(req.version().equals(Version.V1_1)); // Default for HTTP/1.1
if (keepAlive) {
res.header("Connection", "keep-alive")
.header("Keep-Alive", "timeout=300, max=100");
} else {
res.header("Connection", "close");
}
res.send("Response with keep-alive handling");
};// Handler for chunked responses
Handler chunkedHandler = (req, res) -> {
Http1ServerResponse http1Response = (Http1ServerResponse) res;
http1Response.status(200)
.contentType(MediaType.TEXT_PLAIN)
.header("Transfer-Encoding", "chunked");
try (OutputStream out = http1Response.outputStream()) {
for (int i = 0; i < 10; i++) {
String chunk = "Chunk " + i + "\n";
out.write(chunk.getBytes());
out.flush();
Thread.sleep(100); // Simulate processing
}
} catch (Exception e) {
// Handle streaming error
}
};
// Configure chunked encoding limits
Http1Config chunkedConfig = Http1Config.builder()
.maxChunkSize(65536) // 64KB chunks
.validateRequestHeaders(true)
.build();// Strict HTTP/1.1 validation configuration
Http1Config strictConfig = Http1Config.builder()
.validateRequestHeaders(true)
.validateHostHeader(true)
.maxHeaderSize(8192)
.maxInitialLineLength(4096)
.build();
// Custom validation handler
Handler validationHandler = (req, res) -> {
Http1ServerRequest http1Req = (Http1ServerRequest) req;
Http1Headers headers = http1Req.headers();
// Validate required headers for HTTP/1.1
if (req.version().equals(Version.V1_1) && !headers.contains("Host")) {
res.status(400).send("Host header required for HTTP/1.1");
return;
}
// Validate content length for POST/PUT requests
if ((req.method().equals(Method.POST) || req.method().equals(Method.PUT))) {
if (!headers.contentLength().isPresent() &&
!headers.first("Transfer-Encoding").map(te -> te.contains("chunked")).orElse(false)) {
res.status(400).send("Content-Length or Transfer-Encoding required");
return;
}
}
// Validate content type for requests with body
if (req.entity().hasEntity() && !headers.contentType().isPresent()) {
res.status(400).send("Content-Type header required");
return;
}
res.send("Request validated successfully");
};// HTTP/1.1 upgrade support is handled through SPI
// See http1-spi.md for upgrade provider implementation
// Example usage in routing
Handler upgradeHandler = (req, res) -> {
Http1Headers headers = ((Http1ServerRequest) req).headers();
Optional<String> upgrade = headers.first("Upgrade");
Optional<String> connection = headers.first("Connection");
if (upgrade.isPresent() &&
connection.map(c -> c.toLowerCase().contains("upgrade")).orElse(false)) {
String upgradeProtocol = upgrade.get().toLowerCase();
if ("websocket".equals(upgradeProtocol)) {
// WebSocket upgrade would be handled by WebSocket upgrade provider
res.status(101)
.header("Upgrade", "websocket")
.header("Connection", "Upgrade")
.send();
} else {
res.status(400).send("Unsupported upgrade protocol: " + upgradeProtocol);
}
} else {
res.status(400).send("Invalid upgrade request");
}
};// High-performance HTTP/1.1 configuration
Http1Config performanceConfig = Http1Config.builder()
// Increase buffer sizes for high-throughput scenarios
.maxHeaderSize(32768)
.maxInitialLineLength(16384)
.maxChunkSize(131072) // 128KB chunks
// Enable pipelining for clients that support it
.enablePipelining(true)
.maxPipelinedRequests(50)
// Optimize timeouts
.connectionIdleTimeout(Duration.ofMinutes(2))
.continueImmediately(true)
// Enable validation for security
.validateRequestHeaders(true)
.validateHostHeader(true)
.build();
// Use with optimized connection configuration
ConnectionConfig connConfig = ConnectionConfig.builder()
.connectTimeout(Duration.ofSeconds(5))
.readTimeout(Duration.ofSeconds(30))
.idleTimeout(Duration.ofMinutes(2))
.maxConcurrentRequests(1000)
.initialBufferSize(32768)
.maxBufferSize(1048576)
.connectionPooling(true)
.build();
WebServerConfig optimizedServer = WebServerConfig.builder()
.port(8080)
.connection(connConfig)
.addProtocol(performanceConfig)
.routing(httpRouting)
.build();Install with Tessl CLI
npx tessl i tessl/maven-io-helidon-webserver--helidon-webserver