HTTP/2 Server Push
HTTP/2 server push lets the server send resources to the client before they are requested, eliminating a round trip for assets the page is known to need. This recipe pushes a page’s CSS, JavaScript, and image alongside the HTML response.
1. Register a route to serve web assets
Section titled “1. Register a route to serve web assets”e.Static("/", "static")2. Serve index.html and push its dependencies
Section titled “2. Serve index.html and push its dependencies”Unwrap the response to access the underlying http.ResponseWriter, then push each
asset if the writer implements http.Pusher:
e.GET("/", func(c *echo.Context) (err error) { rw, err := echo.UnwrapResponse(c.Response()) if err != nil { return } if pusher, ok := rw.ResponseWriter.(http.Pusher); ok { if err = pusher.Push("/app.css", nil); err != nil { return } if err = pusher.Push("/app.js", nil); err != nil { return } if err = pusher.Push("/echo.png", nil); err != nil { return } } return c.File("index.html")})3. Start the TLS server
Section titled “3. Start the TLS server”sc := echo.StartConfig{Address: ":1323"}if err := sc.StartTLS(context.Background(), e, "cert.pem", "key.pem"); err != nil { e.Logger.Error("failed to start server", "error", err)}Source code
Section titled “Source code”index.html
Section titled “index.html”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>HTTP/2 Server Push</title> <link rel="stylesheet" href="/app.css"> <script src="/app.js"></script></head><body> <img class="echo" src="/echo.png"> <h2>The following static files are served via HTTP/2 server push</h2> <ul> <li><code>/app.css</code></li> <li><code>/app.js</code></li> <li><code>/echo.png</code></li> </ul></body></html>server.go
Section titled “server.go”package main
import ( "context" "net/http"
"github.com/labstack/echo/v5")
func main() { e := echo.New() e.Static("/", "static") e.GET("/", func(c *echo.Context) (err error) { rw, err := echo.UnwrapResponse(c.Response()) if err != nil { return } if pusher, ok := rw.ResponseWriter.(http.Pusher); ok { if err = pusher.Push("/app.css", nil); err != nil { return } if err = pusher.Push("/app.js", nil); err != nil { return } if err = pusher.Push("/echo.png", nil); err != nil { return } } return c.File("index.html") })
sc := echo.StartConfig{Address: ":1323"} if err := sc.StartTLS(context.Background(), e, "cert.pem", "key.pem"); err != nil { e.Logger.Error("failed to start server", "error", err) }}