Skip to content

Conversation

@laeubi
Copy link

@laeubi laeubi commented Dec 23, 2025

HTTP Protocol Upgrade Support for JDK HTTP Server

Motivation

The com.sun.net.httpserver.HttpServer API currently lacks the ability to perform HTTP protocol upgrades as defined in RFC 7230 Section 6.7. This limitation prevents developers from implementing modern protocols that rely on the HTTP upgrade mechanism, most notably WebSocket (RFC 6455), but also other protocols like HTTP/2 over HTTP/1.1, Server-Sent Events with upgrade paths, and custom application protocols.

Current Limitations

Applications using the JDK HTTP server today cannot:

  • Implement WebSocket endpoints without third-party servers
  • Support bidirectional real-time communication patterns
  • Upgrade from HTTP/1.1 to other protocols within the same connection
  • Take control of the underlying socket for custom protocol handling

This forces developers to either:

  1. Use external server frameworks (Jetty, Tomcat, etc.) for WebSocket support
  2. Implement separate TCP server infrastructure alongside HTTP endpoints
  3. Rely on polling or other inefficient communication patterns

Proposed Solution

This PR introduces a minimal, extensible API for HTTP protocol upgrades that:

  1. Enables Protocol Switching: Allows handlers to upgrade from HTTP to any protocol (WebSocket, custom protocols, etc.)
  2. Provides Raw Socket Access: Gives upgrade handlers direct access to input/output streams for complete protocol control
  3. Maintains API Consistency: Follows existing HttpExchange patterns with familiar method signatures
  4. Simplifies Upgrade Flow: Automatically sends the HTTP 101 response, removing boilerplate from handlers

API Design Principles

Simplicity over Flexibility

  • The upgrade() method implicitly sends HTTP 101 "Switching Protocols" since it's the only valid success response per RFC 7230
  • If an upgrade cannot proceed, handlers simply call sendResponseHeaders() with an appropriate error code instead

Clear Lifecycle Boundaries

  • After upgrade() is called, the HTTP exchange is complete and the upgrade handler takes full ownership
  • The server no longer manages the connection, preventing state confusion

Functional Interface Design

  • HttpUpgradeHandler is a @FunctionalInterface enabling lambda expressions for concise handler implementations

Use Cases Enabled

WebSocket Implementation

server.createContext("/websocket", exchange -> {
    if ("websocket".equalsIgnoreCase(exchange.getRequestHeaders().getFirst("Upgrade"))) {
        // Validate Sec-WebSocket-Key, set Sec-WebSocket-Accept header
        exchange.getResponseHeaders().set("Upgrade", "websocket");
        exchange.getResponseHeaders().set("Connection", "Upgrade");
        
        exchange.upgrade((input, output) -> {
            // Implement WebSocket frame handling
        });
    } else {
        exchange.sendResponseHeaders(400, -1);
    }
});

Custom Protocol Implementation

exchange.upgrade((input, output) -> {
    // Full control over socket streams for custom protocols
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = input.read(buffer)) != -1) {
        // Process custom protocol messages
        output.write(transformData(buffer, bytesRead));
    }
});

Implementation Approach

This proof-of-concept demonstrates:

  • Two new public APIs: HttpExchange.upgrade() and HttpUpgradeHandler
  • Internal state tracking to prevent misuse (e.g., calling upgrade after headers sent)
  • Proper HTTP 101 response generation with upgrade headers
  • Stream handoff to upgrade handlers after HTTP exchange completion
  • Comprehensive test coverage with a custom echo protocol

Discussion Points

  1. Thread Management: Should upgrade handlers run on the existing server thread pool or require explicit executor configuration?
  2. Stream Lifecycle: Should the server close streams after handler completion, or should handlers have full responsibility?
  3. Security Considerations: Should there be built-in limits or hooks for upgrade validation?
  4. Module Placement: Should HttpUpgradeHandler remain in jdk.httpserver or move to a separate API module?
  5. Future WebSocket API: Should we consider a companion JEP for a standard WebSocket API built on this foundation?

Benefits to the Java Ecosystem

  • Reduces Dependency Burden: Applications can implement WebSocket without heavyweight server frameworks
  • Improves Developer Experience: Consistent API for both HTTP and upgraded protocol handling
  • Enables Innovation: Developers can experiment with custom protocols without forking server implementations
  • Standards Compliance: Properly implements RFC 7230 upgrade mechanism

This PR serves as a minimal viable implementation to demonstrate feasibility and gather community feedback on API design before a formal JEP process.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Error

 ⚠️ OCA signatory status must be verified

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28961/head:pull/28961
$ git checkout pull/28961

Update a local copy of the PR:
$ git checkout pull/28961
$ git pull https://git.openjdk.org/jdk.git pull/28961/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28961

View PR using the GUI difftool:
$ git pr show -t 28961

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28961.diff

@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label Dec 23, 2025
@bridgekeeper
Copy link

bridgekeeper bot commented Dec 23, 2025

Hi @laeubi, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user laeubi" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@openjdk
Copy link

openjdk bot commented Dec 23, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk
Copy link

openjdk bot commented Dec 23, 2025

@laeubi The following label will be automatically applied to this pull request:

  • net

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@laeubi
Copy link
Author

laeubi commented Dec 24, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

net [email protected] oca Needs verification of OCA signatory status

Development

Successfully merging this pull request may close these issues.

1 participant