Some checks failed
Linting and tests / Linting (push) Failing after 37s
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package httpserver
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/coder/websocket"
|
|
)
|
|
|
|
const httpServerAddrEnvVar = "BUNKERD_HTTP_ADDRESS"
|
|
|
|
var (
|
|
errHTTPServerAddrInvalid = errors.New("BUNKERD_HTTP_ADDRESS environment variable contains invalid address to " +
|
|
"listen, should be 'host:port'")
|
|
errHTTPServerAddrNotFound = errors.New("BUNKERD_HTTP_ADDRESS environment variable empty")
|
|
)
|
|
|
|
func (h *httpServer) configureHTTPServer() error {
|
|
httpSrvAddr, found := os.LookupEnv(httpServerAddrEnvVar)
|
|
if !found {
|
|
return fmt.Errorf("configure HTTP server: get address from environment variable: %w", errHTTPServerAddrNotFound)
|
|
}
|
|
|
|
host, port, err := net.SplitHostPort(httpSrvAddr)
|
|
if err != nil {
|
|
return fmt.Errorf("configure HTTP server: validate HTTP server address: %w", err)
|
|
}
|
|
|
|
if httpSrvAddr != host+":"+port {
|
|
return fmt.Errorf("configure HTTP server: validate HTTP server address: %w", errHTTPServerAddrInvalid)
|
|
}
|
|
|
|
mux := new(http.ServeMux)
|
|
mux.HandleFunc("GET /api/v1/socket", h.handleWebsocketRequest)
|
|
|
|
h.httpSrv = &http.Server{
|
|
Addr: httpSrvAddr,
|
|
Handler: mux,
|
|
ReadHeaderTimeout: time.Second * 3,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *httpServer) handleWebsocketRequest(w http.ResponseWriter, r *http.Request) {
|
|
wsConn, err := websocket.Accept(w, r, &websocket.AcceptOptions{
|
|
OnPingReceived: func(_ context.Context, _ []byte) bool {
|
|
return true
|
|
},
|
|
})
|
|
if err != nil {
|
|
h.logger.Error("Failed to accept WS connection!", "error", err.Error())
|
|
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
if err := wsConn.CloseNow(); err != nil {
|
|
h.logger.Warn("Failed to close WS connection in defer!", "error", err.Error())
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (h *httpServer) startHTTPServer() {
|
|
h.logger.Info("Starting listening for HTTP requests.", "address", h.httpSrv.Addr)
|
|
|
|
if err := h.httpSrv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
h.logger.Warn("Error when listening to ", "error", err.Error())
|
|
}
|
|
}
|
|
|
|
func (h *httpServer) stopHTTPServer() error {
|
|
h.logger.Info("Stopping HTTP server...")
|
|
|
|
if err := h.httpSrv.Shutdown(h.app.ContextWithTimeout(time.Second * 3)); err != nil {
|
|
return fmt.Errorf("stopping HTTP server: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|