From 47153d31a1a60f81396b54d0224c229c71a70458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Fri, 6 Sep 2024 20:59:07 +0200 Subject: [PATCH] legacy: implement screenshot function. --- server/internal/http/legacy/handler.go | 56 ++++++++++++++------------ server/internal/http/legacy/session.go | 31 +++++++++----- server/openapi.yaml | 7 ++++ 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/server/internal/http/legacy/handler.go b/server/internal/http/legacy/handler.go index c450d2e29..89ee0d9f8 100644 --- a/server/internal/http/legacy/handler.go +++ b/server/internal/http/legacy/handler.go @@ -4,7 +4,9 @@ import ( "encoding/json" "errors" "fmt" + "io" "net/http" + "strconv" "time" "m1k1o/neko/internal/api" @@ -264,38 +266,42 @@ func (h *LegacyHandler) Route(r types.Router) { return json.NewEncoder(w).Encode(stats) }) - /* - r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error { - password := r.URL.Query().Get("pwd") - isAdmin, err := webSocketHandler.IsAdmin(password) - if err != nil { - return utils.HttpForbidden(err) - } + r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error { + s := newSession(h.logger, h.serverAddr) - if !isAdmin { - return utils.HttpUnauthorized().Msg("bad authorization") - } + // create a new session + username := r.URL.Query().Get("usr") + password := r.URL.Query().Get("pwd") + err := s.create(username, password) + if err != nil { + return utils.HttpForbidden(err.Error()) + } + defer s.destroy() - if webSocketHandler.IsLocked("login") { - return utils.HttpError(http.StatusLocked).Msg("room is locked") - } + if !s.isAdmin { + return utils.HttpUnauthorized().Msg("bad authorization") + } - quality, err := strconv.Atoi(r.URL.Query().Get("quality")) - if err != nil { - quality = 90 - } + 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") + 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 { - return utils.HttpInternalServerError().WithInternalErr(err) - } + // get the screenshot + body, err := s.req(http.MethodGet, "/api/room/screen/shot.jpg?quality="+strconv.Itoa(quality), nil) + if err != nil { + return utils.HttpInternalServerError().WithInternalErr(err) + } - return nil - }) + // copy the body to the response writer + _, err = io.Copy(w, body) + return err + }) + /* // allow downloading and uploading files if webSocketHandler.FileTransferEnabled() { r.Get("/file", func(w http.ResponseWriter, r *http.Request) error { diff --git a/server/internal/http/legacy/session.go b/server/internal/http/legacy/session.go index feaa36fc4..191523bea 100644 --- a/server/internal/http/legacy/session.go +++ b/server/internal/http/legacy/session.go @@ -57,15 +57,15 @@ func newSession(logger zerolog.Logger, serverAddr string) *session { } } -func (s *session) apiReq(method, path string, request, response any) error { +func (s *session) req(method, path string, request any) (io.ReadCloser, error) { body, err := json.Marshal(request) if err != nil { - return err + return nil, err } req, err := http.NewRequest(method, "http://"+s.serverAddr+path, bytes.NewReader(body)) if err != nil { - return err + return nil, err } req.Header.Set("Content-Type", "application/json") @@ -76,33 +76,44 @@ func (s *session) apiReq(method, path string, request, response any) error { res, err := s.client.Do(req) if err != nil { - return err + return nil, err } - defer res.Body.Close() if res.StatusCode < 200 || res.StatusCode >= 300 { + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) // try to unmarsal as json error message var apiErr struct { Message string `json:"message"` } if err := json.Unmarshal(body, &apiErr); err == nil { - return fmt.Errorf("%w: %s", ErrBackendRespone, apiErr.Message) + return nil, fmt.Errorf("%w: %s", ErrBackendRespone, apiErr.Message) } // return raw body if failed to unmarshal - return fmt.Errorf("unexpected status code: %d, body: %s", res.StatusCode, strings.TrimSpace(string(body))) + return nil, fmt.Errorf("unexpected status code: %d, body: %s", res.StatusCode, strings.TrimSpace(string(body))) + } + + return res.Body, nil +} + +func (s *session) apiReq(method, path string, request, response any) error { + body, err := s.req(method, path, request) + if err != nil { + return err } + defer body.Close() - if res.Body == nil { + if body == nil { return nil } if response == nil { - io.Copy(io.Discard, res.Body) + io.Copy(io.Discard, body) return nil } - return json.NewDecoder(res.Body).Decode(response) + return json.NewDecoder(body).Decode(response) } // send message to client (in old format) diff --git a/server/openapi.yaml b/server/openapi.yaml index 974b27601..bf5e18c8f 100644 --- a/server/openapi.yaml +++ b/server/openapi.yaml @@ -703,6 +703,13 @@ paths: - room summary: get screenshot image operationId: screenShotImage + parameters: + - in: query + name: quality + description: image quality (0-100) + required: false + schema: + type: integer responses: '200': description: OK