package api import ( "archive/zip" "bytes" "io" "net/http/httptest" "testing" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/compress" ) // buildTinyXLSX returns a minimal but structurally valid .xlsx (ZIP) payload. func buildTinyXLSX(t *testing.T) []byte { t.Helper() var buf bytes.Buffer zw := zip.NewWriter(&buf) entries := map[string]string{ "[Content_Types].xml": ``, "_rels/.rels": ``, "xl/workbook.xml": ``, } for name, content := range entries { w, err := zw.Create(name) if err != nil { t.Fatalf("zip create %s: %v", name, err) } if _, err := io.WriteString(w, content); err != nil { t.Fatalf("zip write %s: %v", name, err) } } if err := zw.Close(); err != nil { t.Fatalf("zip close: %v", err) } return buf.Bytes() } func assertValidZip(t *testing.T, b []byte) { t.Helper() if _, err := zip.NewReader(bytes.NewReader(b), int64(len(b))); err != nil { t.Fatalf("payload is not a valid zip: %v", err) } } func TestIsWOPIRequest(t *testing.T) { app := fiber.New() cases := []struct { path string want bool }{ {"/wopi/files/123/contents", true}, {"/wopi/files/123", true}, {"/api/file-manager/files", false}, {"/wopimirror/x", false}, {"/", false}, } for _, tc := range cases { app.Get(tc.path, func(c *fiber.Ctx) error { if got := isWOPIRequest(c); got != tc.want { t.Errorf("isWOPIRequest(%q) = %v, want %v", tc.path, got, tc.want) } return c.SendStatus(fiber.StatusOK) }) resp, err := app.Test(httptest.NewRequest("GET", tc.path, nil), -1) if err != nil { t.Fatalf("app.Test(%q): %v", tc.path, err) } _ = resp.Body.Close() } } // Regression for the "template .xlsx always corrupt via WOPI" bug: the global // gzip compress middleware must NOT compress WOPI file-content responses. // Collabora saves the response body verbatim as the document, so a gzip stream // there is a guaranteed-corrupt file. func TestCompressMiddleware_SkipsWOPIContents(t *testing.T) { src := buildTinyXLSX(t) assertValidZip(t, src) app := fiber.New() // Mirror the production compress wiring (UseDefaultMiddlewares). app.Use(compress.New(compress.Config{ Level: compress.LevelBestSpeed, Next: func(c *fiber.Ctx) bool { return isEventStreamRequest(c) || isWOPIRequest(c) }, })) streamXLSX := func(c *fiber.Ctx) error { c.Set(fiber.HeaderContentType, "application/octet-stream") c.Status(fiber.StatusOK) c.Context().Response.SetBodyStream(io.NopCloser(bytes.NewReader(src)), len(src)) return nil } app.Get("/wopi/files/:id/contents", streamXLSX) // Negative control: a non-WOPI route with a compressible body must still gzip. app.Get("/api/echo", func(c *fiber.Ctx) error { c.Set(fiber.HeaderContentType, "application/octet-stream") return c.Send(bytes.Repeat([]byte("A"), 4096)) }) // WOPI content download with gzip offered must come back raw + valid. req := httptest.NewRequest("GET", "/wopi/files/abc/contents", nil) req.Header.Set("Accept-Encoding", "gzip") resp, err := app.Test(req, -1) if err != nil { t.Fatalf("app.Test wopi: %v", err) } if enc := resp.Header.Get("Content-Encoding"); enc != "" { t.Fatalf("WOPI content unexpectedly encoded: Content-Encoding=%q", enc) } got, _ := io.ReadAll(resp.Body) _ = resp.Body.Close() assertValidZip(t, got) if !bytes.Equal(got, src) { t.Fatalf("WOPI content body mutated: got %d bytes, want %d", len(got), len(src)) } // Sanity: prove compression is actually active for non-excluded routes. req2 := httptest.NewRequest("GET", "/api/echo", nil) req2.Header.Set("Accept-Encoding", "gzip") resp2, err := app.Test(req2, -1) if err != nil { t.Fatalf("app.Test echo: %v", err) } if enc := resp2.Header.Get("Content-Encoding"); enc != "gzip" { t.Fatalf("expected gzip on non-WOPI route, got Content-Encoding=%q (compress not active - test invalid)", enc) } _ = resp2.Body.Close() }