Configuring HTTPS and HTTP/2 Support in RoadRunner

Overview

RoadRunner provides built-in support for HTTPS and HTTP/2 protocols. This guide explains how to configure secure connections and leverage advanced HTTP features.

HTTPS Configuration

Enable HTTPS by adding the ssl section within the http configuration block:

http:
  # Server binding address
  address: 127.0.0.1:8080

  ssl:
    # HTTPS binding address (defaults to :443)
    address: :8892
    redirect: false
    cert: fixtures/server.crt
    key: fixtures/server.key
    root_ca: root.crt

  # HTTP/2 configuration
  http2:
    h2c: false
    max_concurrent_streams: 128

Forcing HTTPS Redirects

To automatically redirect incoming http:// requests to https://, enable the redirect option:

http:
  ssl:
    redirect: true

HTTP/2 Server Push

RoadRunner supports HTTP/2 push functionality through a special header provided in the PHP response. This allows sending resources to the client before they are requested:

// PHP example
return $response->withAddedHeader('http2-push', '/ styles.css');

Note that resource paths must be relative to the public application directory and must start with a forward slash.

Important: HTTP/2 push only functions when serving static content over HTTPS.

H2C (HTTP/2 over Clear Text)

You can enable HTTP/2 support over unencrypted TCP connections using H2C:

http:
  http2:
    h2c: true

FastCGI Frontend

The HTTP module includes FastCGI frontend support, which can be enabled as follows:

http:
  # HTTP service provides FastCGI as frontend
  fcgi:
    # FastCGI connection DSN. Supports TCP and Unix sockets.
    address: tcp://0.0.0.0:6920

Root Certificate Authority

Configure root CA support in your .rr.yaml file:

http:
  ssl:
    root_ca: root.crt

Serving Static Files

RoadRunner can serve static content directly without involving PHP workers.

Basic Configuration

Enable static content serving using the static block within the http section:

http:
  address: 127.0.0.1:44933
  static:
    dir: "."
    forbid: [""]
    allow: [".txt", ".php"]
    calculate_etag: false
    weak: false
    request:
      input: "custom-header"
    response:
      output: "output-header"

Configuration parameters explained:

  • dir: Directory path containing static files.
  • forbid: File extensions that should not be served.
  • allow: File extensions permitted for serving. If empty, all files except forbidden ones are served. When an extention appears in both allow and forbid, its treated as forbidden.
  • calculate_etag: Enable ETag calculation for static files.
  • weak: Use weak ETag generator (/W) which only uses filename for CRC32. When false, uses full file content for checksum.
  • request/response: Custom headers for static file requests and responses.

Combining with Other Middleware

To combine static content with other middleware, configure them in sequence. Note that static middleware always executes last, with the file server applying headers and gzip plugins:

http:
  address: 127.0.0.1:44933
  middleware: [ "headers", "gzip" ]
  headers:
    # configuration...
  static:
    dir: "."
    forbid: [""]
    allow: [".txt", ".php"]
    calculate_etag: false
    weak: false

Headers and CORS Configuration

RoadRunner can automatically manage request/response headers and handle Cross-Origin Resource Sharing (CORS).

CORS Setup

Enable CORS headers by adding the following configuration:

http:
  address: 127.0.0.1:44933
  middleware: ["headers"]
  headers:
    cors:
      allowed_origin: "*"
      allowed_headers: "*"
      allowed_methods: "GET,POST,PUT,DELETE"
      allow_credentials: true
      exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma"
      max_age: 600

Note: You must declare the "headers" middleware in your configuration.

Custom Headers

Configure custom headers for incoming requests and outgoing responses:

http:
  headers:
    # Headers added to every request sent to PHP
    request:
      Example-Request-Header: "Value"

    # Headers added to every response
    response:
      X-Powered-By: "RoadRunner"

Custom HTTP Middleware

RoadRunner's HTTP server uses Go's standard middleware pattern, allowing extension through custom or community-provided middleware plugins.

Middleware Implementation

A basic middleware implementation structure:

package middleware

import (
    "net/http"
)

const PluginName = "customMiddleware"

type CustomMiddleware struct{}

// Initialize the middleware plugin
func (m *CustomMiddleware) Init() error {
    return nil
}

// Middleware handler function
func (m *CustomMiddleware) Middleware(next http.Handler) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Process the request
        // Call next handler
        next.ServeHTTP(w, r)
    }
}

// Plugin name identification
func (m *CustomMiddleware) Name() string {
    return PluginName
}

Ensure your middleware implements the required interface and provides a unique name.

Registering Middleware

Register the middleware service in your main.go file to resolve dependencies correctly:

container, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel), endure.RetryOnFail(false))
if err != nil {
    panic(err)
}

// Register HTTP service
err = container.Register(&http.Service{})
if err != nil {
    panic(err)
}

// Register custom service
err = container.Register(&custom.Service{})
if err != nil {
    panic(err)
}

// Register middleware
err = container.RegisterAll(
    &middleware.CustomMiddleware{},
)

Using PSR7 Attributes

Pass values securely through the request attributes using the attributes package:

func (s *Service) middleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        attributes.Set(r, "key", "value")
        next(w, r)
    }
}

These attributes can then be accessed via ServerRequestInterface->getAttributes() in your PHP application.

Tags: roadrunner Golang HTTPS http2 PHP

Posted on Sun, 26 Jul 2026 16:38:45 +0000 by Magestic