Skip to main content

Overview

The h2c middleware enables HTTP/2 cleartext (h2c) connections, allowing HTTP/2 over unencrypted connections for development and internal services. Use it when you need:
  • HTTP/2 without TLS
  • Development HTTP/2 testing
  • Internal service communication

Installation

import "github.com/go-mizu/mizu/middlewares/h2c"

Quick Start

app := mizu.New()

// Enable h2c
server := h2c.Server(app)
server.ListenAndServe(":8080")

Examples

Basic H2C Server

app := mizu.New()

app.Get("/", func(c *mizu.Ctx) error {
    return c.Text(200, "HTTP/2 Cleartext!")
})

// Wrap with h2c
server := h2c.Server(app)
log.Fatal(server.ListenAndServe(":8080"))

With Custom Server

app := mizu.New()

server := &http.Server{
    Addr:    ":8080",
    Handler: h2c.Handler(app),
}

server.ListenAndServe()

API Reference

Functions

// Server creates h2c-enabled server
func Server(handler http.Handler) *http.Server

// Handler wraps handler for h2c support
func Handler(handler http.Handler) http.Handler

Technical Details

Implementation Overview

The h2c middleware provides HTTP/2 cleartext support through two main mechanisms:
  1. HTTP/2 Prior Knowledge: Direct HTTP/2 connections where the client knows in advance that the server supports HTTP/2. Detected by checking ProtoMajor == 2.
  2. HTTP/2 Upgrade: HTTP/1.1 upgrade mechanism using the h2c upgrade protocol (RFC 7540, Section 3.2).

Core Components

Options Configuration

  • AllowUpgrade (default: true): Enables HTTP/1.1 to HTTP/2 upgrade requests
  • AllowDirect (default: true): Enables direct HTTP/2 connections with prior knowledge
  • OnUpgrade: Optional callback function triggered when an upgrade occurs

Context Information

The middleware stores connection information in the request context:
type Info struct {
    IsHTTP2  bool  // True if request uses HTTP/2
    Upgraded bool  // True if upgraded from HTTP/1.1
    Direct   bool  // True if direct HTTP/2 connection
}

Upgrade Detection

The middleware validates h2c upgrade requests by checking:
  • Connection header contains β€œUpgrade” token
  • Upgrade header equals β€œh2c” (case-insensitive)
  • HTTP2-Settings header is present

Connection Handling

  • Uses http.Hijacker interface to take over the TCP connection
  • Sends 101 Switching Protocols response
  • Manages connection lifecycle with buffered reading via BufferedConn

Helper Functions

  • GetInfo(c *mizu.Ctx): Retrieves h2c information from context
  • IsHTTP2(c *mizu.Ctx): Quick check if request is HTTP/2
  • ParseSettings(r *http.Request): Decodes base64-encoded HTTP2-Settings header
  • IsHTTP2Preface(data []byte): Validates HTTP/2 connection preface bytes

Security Warning

H2C transmits data unencrypted. Only use for:
  • Development environments
  • Internal services behind TLS termination
  • Testing scenarios

Best Practices

  • Never use h2c in production over public networks
  • Use behind TLS-terminating load balancer
  • Test with curl --http2-prior-knowledge

Testing

The h2c middleware includes comprehensive test coverage for all functionality:
Test CaseDescriptionExpected Behavior
TestNewBasic middleware creationMiddleware initializes with default options and processes HTTP/1.1 requests
TestDetectHTTP1HTTP/1.1 detectionCorrectly identifies HTTP/1.x requests, sets IsHTTP2 to false
TestIsH2CUpgradeUpgrade request validationValidates h2c upgrade headers (Connection, Upgrade, HTTP2-Settings)
TestContainsTokenHeader token parsingCorrectly parses comma-separated header values
TestGetInfoContext info retrievalRetrieves h2c info from request context
TestIsHTTP2HTTP/2 detection helperReturns correct boolean for HTTP/2 detection
TestParseSettingsHTTP2-Settings parsingDecodes base64-encoded settings header
TestParseSettingsEmptyEmpty settings handlingReturns nil for missing HTTP2-Settings header
TestParseSettingsInvalidInvalid settings handlingReturns error for malformed base64
TestOnUpgradeUpgrade callbackExecutes OnUpgrade callback when upgrade occurs
TestServerHandlerServerHandler creationCreates handler with h2c support
TestWrapHandler wrappingWraps standard http.Handler with h2c support
TestIsHTTP2PrefacePreface detectionValidates HTTP/2 connection preface bytes
TestDetectDetection-only modeDetects h2c without handling upgrade
TestWithOptionsDisabledDisabled optionsRespects AllowUpgrade and AllowDirect settings
TestBufferedConnBuffered connectionHandles buffered reading with Peek and Read
TestGetInfo_NoContextMissing context infoReturns empty Info when middleware not used
TestDetect_WithH2CUpgradeUpgrade detectionCorrectly detects and marks upgrade requests
TestServerHandler_WithH2CUpgradeHandler upgrade flowProcesses h2c upgrade in ServerHandler
TestServerHandler_UpgradeDisabledDisabled upgrade handlingFalls back to handler when upgrade disabled
TestInfo_FieldsInfo struct fieldsValidates Info struct field values
TestConnectionPrefacePreface constantVerifies correct HTTP/2 preface constant
TestWithOptions_HTTP2PriorKnowledgePrior knowledge handlingDetects direct HTTP/2 connections
TestWithOptions_H2CUpgradeWithCallbackUpgrade with callbackExecutes callback during upgrade
TestHandleUpgrade_NonHijackableNon-hijackable fallbackFalls back to HTTP/1.1 when hijack unsupported
TestServerHandler_HTTP2PriorKnowledgePrior knowledge in handlerHandles HTTP/2 prior knowledge in ServerHandler
TestServerHandler_H2CUpgrade_WithHijackSuccessful hijackSuccessfully hijacks connection for upgrade
TestServerHandler_H2CUpgrade_HijackErrorHijack error handlingFalls back to handler on hijack error
TestServerHandler_NonHijackableHandler fallbackFalls back when ResponseWriter not hijackable
TestDetect_HTTP2PriorKnowledgePrior knowledge detectionDetects HTTP/2 prior knowledge in Detect mode
TestBufferedConn_UnderlyingUnderlying connection opsValidates Write, Close operations on BufferedConn
TestWithOptions_H2CUpgrade_HijackErrorMiddleware hijack errorHandles hijack errors in middleware
TestBufferedConn_NetConnInterfacenet.Conn interfaceValidates complete net.Conn interface implementation