add /stats endpoint.
This commit is contained in:
parent
9771b551df
commit
bbae073104
@ -33,6 +33,7 @@ For n.eko room management software visit https://github.com/m1k1o/neko-rooms.
|
|||||||
- Added `VIDEO_BITRATE` and `AUDIO_BITRATE` in kbit/s to control stream quality (in collaboration with @mbattista).
|
- Added `VIDEO_BITRATE` and `AUDIO_BITRATE` in kbit/s to control stream quality (in collaboration with @mbattista).
|
||||||
- Added `MAX_FPS`, where you can specify max WebRTC frame rate. When set to `0`, frame rate won't be capped and you can enjoy your real `60fps` experience. Originally, it was constant at `25fps`.
|
- Added `MAX_FPS`, where you can specify max WebRTC frame rate. When set to `0`, frame rate won't be capped and you can enjoy your real `60fps` experience. Originally, it was constant at `25fps`.
|
||||||
- Invite links. You can invite people and they don't need to enter passwords by themselves (and get confused about user accounts that do not exits). You can put your password in URL using `?pwd=<your-password>` and it will be automatically used when logging in.
|
- Invite links. You can invite people and they don't need to enter passwords by themselves (and get confused about user accounts that do not exits). You can put your password in URL using `?pwd=<your-password>` and it will be automatically used when logging in.
|
||||||
|
- Added `/stats?pwd=<admin>` endpoint to get total active connections.
|
||||||
|
|
||||||
### Bugs
|
### Bugs
|
||||||
- Fixed minor gst pipeline bug.
|
- Fixed minor gst pipeline bug.
|
||||||
|
@ -2,6 +2,7 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -23,7 +24,7 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
|
func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
|
||||||
logger := log.With().Str("module", "webrtc").Logger()
|
logger := log.With().Str("module", "http").Logger()
|
||||||
|
|
||||||
router := chi.NewRouter()
|
router := chi.NewRouter()
|
||||||
// router.Use(middleware.Recoverer) // Recover from panics without crashing server
|
// router.Use(middleware.Recoverer) // Recover from panics without crashing server
|
||||||
@ -34,6 +35,31 @@ func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
|
|||||||
webSocketHandler.Upgrade(w, r)
|
webSocketHandler.Upgrade(w, r)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.Get("/stats", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
password := r.URL.Query().Get("pwd")
|
||||||
|
isAdmin, err := webSocketHandler.IsAdmin(password)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusForbidden)
|
||||||
|
fmt.Fprint(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isAdmin {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
fmt.Fprint(w, "bad authorization")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(struct{
|
||||||
|
Connections uint32 `json:"connections"`
|
||||||
|
}{
|
||||||
|
Connections: webSocketHandler.TotalConns(),
|
||||||
|
}); err != nil {
|
||||||
|
logger.Warn().Err(err).Msg("failed writing json error response")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
router.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("true"))
|
w.Write([]byte("true"))
|
||||||
})
|
})
|
||||||
|
@ -12,4 +12,6 @@ type WebSocketHandler interface {
|
|||||||
Start() error
|
Start() error
|
||||||
Shutdown() error
|
Shutdown() error
|
||||||
Upgrade(w http.ResponseWriter, r *http.Request) error
|
Upgrade(w http.ResponseWriter, r *http.Request) error
|
||||||
|
TotalConns() uint32
|
||||||
|
IsAdmin(password string) (bool, error)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package websocket
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@ -38,6 +39,7 @@ func New(sessions types.SessionManager, remote types.RemoteManager, broadcast ty
|
|||||||
banned: make(map[string]bool),
|
banned: make(map[string]bool),
|
||||||
locked: false,
|
locked: false,
|
||||||
},
|
},
|
||||||
|
conns: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ type WebSocketHandler struct {
|
|||||||
remote types.RemoteManager
|
remote types.RemoteManager
|
||||||
conf *config.WebSocket
|
conf *config.WebSocket
|
||||||
handler *MessageHandler
|
handler *MessageHandler
|
||||||
|
conns uint32
|
||||||
shutdown chan bool
|
shutdown chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,18 +182,38 @@ func (ws *WebSocketHandler) Upgrade(w http.ResponseWriter, r *http.Request) erro
|
|||||||
Str("address", connection.RemoteAddr().String()).
|
Str("address", connection.RemoteAddr().String()).
|
||||||
Msg("new connection created")
|
Msg("new connection created")
|
||||||
|
|
||||||
|
atomic.AddUint32(&ws.conns, uint32(1))
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
ws.logger.
|
ws.logger.
|
||||||
Debug().
|
Debug().
|
||||||
Str("session", id).
|
Str("session", id).
|
||||||
Str("address", connection.RemoteAddr().String()).
|
Str("address", connection.RemoteAddr().String()).
|
||||||
Msg("session ended")
|
Msg("session ended")
|
||||||
|
|
||||||
|
atomic.AddUint32(&ws.conns, ^uint32(0))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ws.handle(connection, id)
|
ws.handle(connection, id)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ws *WebSocketHandler) TotalConns() uint32 {
|
||||||
|
return atomic.LoadUint32(&ws.conns)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebSocketHandler) IsAdmin(password string) (bool, error) {
|
||||||
|
if password == ws.conf.AdminPassword {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if password == ws.conf.Password {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, fmt.Errorf("invalid password")
|
||||||
|
}
|
||||||
|
|
||||||
func (ws *WebSocketHandler) authenticate(r *http.Request) (string, string, bool, error) {
|
func (ws *WebSocketHandler) authenticate(r *http.Request) (string, string, bool, error) {
|
||||||
ip := r.RemoteAddr
|
ip := r.RemoteAddr
|
||||||
|
|
||||||
@ -208,15 +231,8 @@ func (ws *WebSocketHandler) authenticate(r *http.Request) (string, string, bool,
|
|||||||
return "", ip, false, fmt.Errorf("no password provided")
|
return "", ip, false, fmt.Errorf("no password provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if passwords[0] == ws.conf.AdminPassword {
|
isAdmin, err := ws.IsAdmin(passwords[0])
|
||||||
return id, ip, true, nil
|
return id, ip, isAdmin, err
|
||||||
}
|
|
||||||
|
|
||||||
if passwords[0] == ws.conf.Password {
|
|
||||||
return id, ip, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", ip, false, fmt.Errorf("invalid password: %s", passwords[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WebSocketHandler) handle(connection *websocket.Conn, id string) {
|
func (ws *WebSocketHandler) handle(connection *websocket.Conn, id string) {
|
||||||
|
Reference in New Issue
Block a user