add screenshot function.

This commit is contained in:
Miroslav Šedivý 2022-09-17 18:17:04 +02:00
parent 057ab2d886
commit ca6c24dee1
5 changed files with 43 additions and 2 deletions

View File

@ -6,6 +6,7 @@
- Added `m1k1o/neko:vivaldi` tag (thanks @Xeddius).
- Added `m1k1o/neko:opera` tag (thanks @prophetofxenu).
- Added `NEKO_PATH_PREFIX`.
- Added screenshot function `/screenshot.jpg?pwd=<admin>`, works only for unlocked rooms.
### Misc
- Server: Split `remote` to `desktop` and `capture`.

View File

@ -3,8 +3,10 @@ package http
import (
"context"
"encoding/json"
"image/jpeg"
"net/http"
"os"
"strconv"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
@ -22,7 +24,7 @@ type Server struct {
conf *config.Server
}
func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
func New(conf *config.Server, webSocketHandler types.WebSocketHandler, desktop types.DesktopManager) *Server {
logger := log.With().Str("module", "http").Logger()
router := chi.NewRouter()
@ -64,6 +66,39 @@ func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
}
})
router.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) {
password := r.URL.Query().Get("pwd")
isAdmin, err := webSocketHandler.IsAdmin(password)
if err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return
}
if !isAdmin {
http.Error(w, "bad authorization", http.StatusUnauthorized)
return
}
if webSocketHandler.IsLocked("login") {
http.Error(w, "room is locked", http.StatusLocked)
return
}
quality, err := strconv.Atoi(r.URL.Query().Get("quality"))
if err != nil {
quality = 90
}
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Content-Type", "image/jpeg")
img := desktop.GetScreenshotImage()
if err := jpeg.Encode(w, img, &jpeg.Options{Quality: quality}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
router.Get("/health", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("true"))
})

View File

@ -32,5 +32,6 @@ type WebSocketHandler interface {
Shutdown() error
Upgrade(w http.ResponseWriter, r *http.Request) error
Stats() Stats
IsLocked(resource string) bool
IsAdmin(password string) (bool, error)
}

View File

@ -298,6 +298,10 @@ func (ws *WebSocketHandler) Stats() types.Stats {
}
}
func (ws *WebSocketHandler) IsLocked(resource string) bool {
return ws.state.IsLocked(resource)
}
func (ws *WebSocketHandler) IsAdmin(password string) (bool, error) {
if password == ws.conf.AdminPassword {
return true, nil

View File

@ -134,7 +134,7 @@ func (neko *Neko) Start() {
webSocketHandler := websocket.New(sessionManager, desktopManager, captureManager, webRTCManager, neko.WebSocket)
webSocketHandler.Start()
server := http.New(neko.Server, webSocketHandler)
server := http.New(neko.Server, webSocketHandler, desktopManager)
server.Start()
neko.sessionManager = sessionManager