Skip to content

gaby/http2

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

538 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTP2

http2 is an implementation of HTTP/2 protocol for fasthttp.

Features

  • 4x faster than net/http2 (533k vs 124k req/s)
  • Zero-allocation hot paths using sync.Pool
  • TLS (h2) and cleartext (h2c) support
  • Server push promise support (frame-level)
  • Response trailer support
  • Flow control with configurable window sizes
  • Graceful server shutdown
  • Connection lifecycle callbacks
  • Ping/RTT measurement
  • HPACK header compression with static table optimization

Download

go get github.com/dgrr/http2

Help

If you need any help to set up, contributing or understanding this repo, you can contact me on gofiber's Discord.

Server (TLS)

package main

import (
	"github.com/valyala/fasthttp"
	"github.com/dgrr/http2"
)

func main() {
    s := &fasthttp.Server{
        Handler: yourHandler,
        Name:    "HTTP2 test",
    }

    h2s := http2.ConfigureServer(s, http2.ServerConfig{
        MaxConcurrentStreams: 250,
    })
    defer h2s.Shutdown() // graceful shutdown
    
    s.ListenAndServeTLS(":443", "cert.pem", "key.pem")
}

Server (h2c / cleartext)

For internal services or behind TLS-terminating load balancers:

s := &fasthttp.Server{Handler: yourHandler}
http2.ConfigureServerH2C(s, http2.ServerConfig{})
s.ListenAndServe(":8080")

Client

The HTTP/2 client works with fasthttp's HostClient:

package main

import (
        "fmt"
        "log"

        "github.com/dgrr/http2"
        "github.com/valyala/fasthttp"
)

func main() {
        hc := &fasthttp.HostClient{
                Addr:  "api.binance.com:443",
        }

        if err := http2.ConfigureClient(hc, http2.ClientOpts{}); err != nil {
                log.Printf("%s doesn't support http/2\n", hc.Addr)
        }

        statusCode, body, err := hc.Get(nil, "https://api.binance.com/api/v3/time")
        if err != nil {
                log.Fatalln(err)
        }

        fmt.Printf("%d: %s\n", statusCode, body)
}

Response Trailers

Handlers can send HTTP/2 trailing headers (used by gRPC and other protocols):

handler := func(ctx *fasthttp.RequestCtx) {
    ctx.SetBodyString("hello")
    ctx.SetUserValue(http2.TrailerUserValueKey, map[string]string{
        "grpc-status":  "0",
        "grpc-message": "",
    })
}

Server Push

Handlers can initiate HTTP/2 server push for related resources:

handler := func(ctx *fasthttp.RequestCtx) {
    // Push is only available if the client supports it
    if push, ok := ctx.UserValue(http2.PusherUserValueKey).(func(string, string)); ok {
        push("GET", "/static/style.css")
        push("GET", "/static/app.js")
    }
    ctx.SetBodyString("<html>...</html>")
}

Server Configuration

http2.ConfigureServer(s, http2.ServerConfig{
    PingInterval:        10 * time.Second,
    MaxConcurrentStreams: 250,
    MaxHeaderListSize:   64 * 1024,
    MaxFrameSize:        32768,
    MaxWindowSize:       1 << 24,          // 16 MiB
    HandshakeTimeout:    5 * time.Second,
    EnqueueTimeout:      2 * time.Second,
    Debug:               false,
    OnNewConnection: func(c net.Conn) {
        log.Printf("new h2 conn from %s", c.RemoteAddr())
    },
    OnConnectionClosed: func(c net.Conn) {
        log.Printf("h2 conn closed from %s", c.RemoteAddr())
    },
})

Client Configuration

http2.ConfigureClient(hc, http2.ClientOpts{
    PingInterval:        3 * time.Second,
    MaxResponseTime:     time.Minute,
    MaxConns:            10,
    DialTimeout:         5 * time.Second,
    DisablePingChecking: false,
    OnRTT: func(rtt time.Duration) {
        log.Printf("RTT: %s", rtt)
    },
})

Monitoring

// Server
srv.ActiveConnections() // int64

// Client connection
conn.Stats() // ConnStats{streams, rtt, window, ...}
conn.RTT()
conn.ActiveStreams()
conn.ServerWindow()

Benchmarks

Benchmark code here.

fasthttp2

$  h2load --duration=10 -c10 -m1000 -t 4 https://localhost:8443
[...]
finished in 10.01s, 533808.90 req/s, 33.09MB/s
requests: 5338089 total, 5348089 started, 5338089 done, 5338089 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 5338089 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 330.90MB (346976335) total, 137.45MB (144128403) headers (space savings 57.14%), 101.82MB (106761780) data
                     min         max         mean         sd        +/- sd
time for request:     1.06ms    101.25ms     17.16ms     11.06ms    75.19%
time for connect:     5.21ms     17.36ms     12.60ms      3.56ms    70.00%
time to 1st byte:    11.32ms     35.27ms     18.84ms      6.85ms    80.00%
req/s           :   48976.50    59084.92    53359.02     3657.52    60.00%

net/http2

$  h2load --duration=10 -c10 -m1000 -t 4 https://localhost:8443
[...]
finished in 10.01s, 124812.90 req/s, 5.00MB/s
requests: 1248129 total, 1258129 started, 1248129 done, 1248129 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 1248247 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 50.00MB (52426258) total, 4.76MB (4995738) headers (space savings 95.83%), 23.81MB (24962580) data
                     min         max         mean         sd        +/- sd
time for request:      141us    140.75ms     19.69ms     11.34ms    76.79%
time for connect:     3.89ms     13.30ms      9.71ms      2.78ms    70.00%
time to 1st byte:    11.02ms     50.13ms     20.13ms     11.24ms    90.00%
req/s           :   11909.97    13162.89    12479.53      373.71    70.00%

About

HTTP/2 implementation for fasthttp

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Go 99.2%
  • Other 0.8%