Servidor HTTP/2
HTTP/2 mejora la latencia mediante multiplexing de requests y compresión de headers. El servidor HTTP de Go negocia HTTP/2 automáticamente sobre TLS, por lo que servir HTTP/2 con Echo consiste en iniciar el servidor con un certificado.
1. Generar un certificado TLS X.509 autofirmado
Sección titulada «1. Generar un certificado TLS X.509 autofirmado»Ejecuta el siguiente comando para generar cert.pem y key.pem:
go run $GOROOT/src/crypto/tls/generate_cert.go --host localhost2. Crear un handler que refleje información del request
Sección titulada «2. Crear un handler que refleje información del request»e.GET("/request", func(c *echo.Context) error { req := c.Request() format := ` <code> Protocol: %s<br> Host: %s<br> Remote Address: %s<br> Method: %s<br> Path: %s<br> </code> ` return c.HTML(http.StatusOK, fmt.Sprintf(format, req.Proto, req.Host, req.RemoteAddr, req.Method, req.URL.Path))})3. Iniciar el servidor TLS
Sección titulada «3. Iniciar el servidor TLS»Inicia el servidor con el certificado y la key generados:
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)}Alternativamente, usa un http.Server personalizado con tu propio tls.Config:
s := http.Server{ Addr: ":1323", Handler: e, TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS12, }, // ReadTimeout: 30 * time.Second, // use custom timeouts}if err := s.ListenAndServeTLS("cert.pem", "key.pem"); err != nil && !errors.Is(err, http.ErrServerClosed) { e.Logger.Error("failed to start server", "error", err)}go run . -custom-server4. Verificar
Sección titulada «4. Verificar»Inicia el servidor y abre https://localhost:1323/request. Deberías ver una salida
similar a:
Protocol: HTTP/2.0Host: localhost:1323Remote Address: [::1]:60288Method: GETPath: /Código fuente
Sección titulada «Código fuente»package main
import ( "context" "crypto/tls" "errors" "flag" "fmt" "net/http"
"github.com/labstack/echo/v5")
func main() { customServer := flag.Bool("custom-server", false, "use a standard http.Server") flag.Parse() e := echo.New() e.GET("/request", func(c *echo.Context) error { req := c.Request() format := ` <code> Protocol: %s<br> Host: %s<br> Remote Address: %s<br> Method: %s<br> Path: %s<br> </code> ` return c.HTML(http.StatusOK, fmt.Sprintf(format, req.Proto, req.Host, req.RemoteAddr, req.Method, req.URL.Path)) }) if *customServer { customHTTPServer(e) return } 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) }}
// customHTTPServer demonstrates configuring TLS with a standard HTTP server.func customHTTPServer(e *echo.Echo) { s := http.Server{ Addr: ":1323", Handler: e, TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS12, }, // ReadTimeout: 30 * time.Second, // use custom timeouts } if err := s.ListenAndServeTLS("cert.pem", "key.pem"); err != nil && !errors.Is(err, http.ErrServerClosed) { e.Logger.Error("failed to start server", "error", err) }}