keys/server/keys.go
2025-05-13 13:53:21 +02:00

106 lines
2.4 KiB
Go

package main
import (
"fmt"
"net/http"
"os"
"syscall"
"time"
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
"github.com/labstack/gommon/log"
)
func keys(c echo.Context) error {
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
if err != nil {
return err
}
defer ws.Close()
id := uuid.New()
idRaw := c.QueryParam("id")
if idRaw != "" {
updatedId, err := uuid.Parse(idRaw)
if err != nil {
log.Errorf("failed to parse id: %s", id)
} else {
id = updatedId
}
}
now := time.Now()
client := Client{
ID: id,
Name: "Dummy",
Connected: true,
ConnectedAt: now,
DisconnectedAt: now,
CreatedAt: now,
UpdatedAt: now,
ExitWanted: false,
conn: ws,
}
clients = append(clients, &client)
fmt.Printf("%s client %s connected\n", time.Now().Format(TimeFormat), client.ID.String())
err = ws.WriteMessage(websocket.TextMessage, []byte("welcome"))
if err != nil {
log.Error(err)
}
f, err := os.OpenFile(filename(dataDir, client.ID.String(), now.Format(DateFormat)), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil {
log.Error(err)
fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.ID)
now = time.Now()
client.Connected = false
client.DisconnectedAt = now
client.UpdatedAt = now
return c.NoContent(http.StatusInternalServerError)
}
defer f.Close()
close := func() {
_ = ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
_ = ws.Close()
now = time.Now()
client.ExitWanted = true
client.Connected = false
client.DisconnectedAt = now
client.UpdatedAt = now
}
for {
if client.ExitWanted {
close()
fmt.Printf("%s client %s disconnected\n", time.Now().Format(TimeFormat), client.ID.String())
break
}
_, msg, err := ws.ReadMessage()
if err != nil {
log.Error(err)
close()
fmt.Printf("%s client %s crashed (websocket error)\n", time.Now().Format(TimeFormat), client.ID.String())
return c.NoContent(http.StatusInternalServerError)
}
_, err = f.Write(msg)
if err != nil {
log.Error(err)
close()
fmt.Printf("%s client %s crashed (file write error)\n", time.Now().Format(TimeFormat), client.ID.String())
return c.NoContent(http.StatusInternalServerError)
}
}
return c.NoContent(http.StatusOK)
}