2fas-server/internal/websocket/common/handler.go

101 lines
2.0 KiB
Go
Raw Normal View History

2022-12-31 10:22:38 +01:00
package common
import (
2023-07-05 15:35:44 +02:00
"net/http"
"os"
"time"
2022-12-31 10:22:38 +01:00
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
2023-01-30 19:59:42 +01:00
"github.com/twofas/2fas-server/internal/common/logging"
2023-04-11 23:39:25 +02:00
"github.com/twofas/2fas-server/internal/common/recovery"
2022-12-31 10:22:38 +01:00
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4 * 1024,
WriteBufferSize: 4 * 1024,
CheckOrigin: func(r *http.Request) bool {
allowedOrigin := os.Getenv("WEBSOCKET_ALLOWED_ORIGIN")
if allowedOrigin != "" {
return r.Header.Get("Origin") == allowedOrigin
}
return true
},
}
type ConnectionHandler struct {
channels map[string]*Hub
}
func NewConnectionHandler() *ConnectionHandler {
channels := make(map[string]*Hub)
return &ConnectionHandler{
channels: channels,
}
}
func (h *ConnectionHandler) Handler() gin.HandlerFunc {
2022-12-31 10:22:38 +01:00
return func(c *gin.Context) {
channel := c.Request.URL.Path
2023-02-01 13:05:12 +01:00
logging.WithDefaultField("channel", channel)
logging.Info("New channel subscriber")
2022-12-31 10:22:38 +01:00
hub := h.getHub(channel)
h.serveWs(hub, c.Writer, c.Request)
}
}
func (h *ConnectionHandler) getHub(channel string) *Hub {
var hub *Hub
hub, ok := h.channels[channel]
if !ok {
hub = NewHub()
go hub.Run()
h.channels[channel] = hub
2023-11-14 10:50:33 +01:00
logging.Errorf("Starting new hub, there are %d hubs in total", len(h.channels))
2022-12-31 10:22:38 +01:00
}
return hub
}
func (h *ConnectionHandler) serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
2023-07-05 15:35:44 +02:00
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logging.Errorf("Failed to upgrade connection: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
2022-12-31 10:22:38 +01:00
client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
client.hub.register <- client
2023-04-11 23:39:25 +02:00
go recovery.DoNotPanic(func() {
client.writePump()
})
go recovery.DoNotPanic(func() {
client.readPump()
})
2022-12-31 10:22:38 +01:00
2023-07-05 15:35:44 +02:00
go recovery.DoNotPanic(func() {
disconnectAfter := 3 * time.Minute
timeout := time.After(disconnectAfter)
2023-02-01 13:05:12 +01:00
2023-07-05 15:35:44 +02:00
<-timeout
logging.Info("Connection closed after", disconnectAfter)
2023-02-01 13:05:12 +01:00
2023-07-05 15:35:44 +02:00
client.hub.unregister <- client
client.conn.Close()
})
2022-12-31 10:22:38 +01:00
}