mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
353 lines
9.4 KiB
Go
353 lines
9.4 KiB
Go
package statigz_test
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"embed"
|
|
"io"
|
|
"io/fs"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
brotli2 "github.com/andybalholm/brotli"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/vearutop/statigz"
|
|
"github.com/vearutop/statigz/brotli"
|
|
)
|
|
|
|
//go:embed _testdata/*
|
|
var v embed.FS
|
|
|
|
func TestServer_ServeHTTP_std(t *testing.T) {
|
|
s := http.FileServer(http.FS(v))
|
|
|
|
for u, found := range map[string]bool{
|
|
"/_testdata/favicon.png": true,
|
|
"/_testdata/nonexistent": false,
|
|
"/_testdata/swagger.json": true,
|
|
"/_testdata/deeper/swagger.json": false,
|
|
"/_testdata/deeper/openapi.json": false,
|
|
"/_testdata/": true,
|
|
"/_testdata/?abc": true,
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
if found {
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, http.StatusOK, rw.Code, u)
|
|
} else {
|
|
assert.Equal(t, http.StatusNotFound, rw.Code, u)
|
|
}
|
|
}
|
|
|
|
for u, l := range map[string]string{
|
|
"/_testdata/index.html": "./",
|
|
"/_testdata": "_testdata/",
|
|
"/_testdata?abc": "_testdata/?abc",
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusMovedPermanently, rw.Code, u)
|
|
assert.Equal(t, l, rw.Header().Get("Location"))
|
|
}
|
|
}
|
|
|
|
func TestServer_ServeHTTP_found(t *testing.T) {
|
|
s := statigz.FileServer(v, brotli.AddEncoding, statigz.EncodeOnInit)
|
|
|
|
for u, found := range map[string]bool{
|
|
"/_testdata/favicon.png": true,
|
|
"/_testdata/nonexistent": false,
|
|
"/_testdata/swagger.json": true,
|
|
"/_testdata/deeper/swagger.json": true,
|
|
"/_testdata/deeper/openapi.json": true,
|
|
"/_testdata/": true,
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
if found {
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, http.StatusOK, rw.Code, u)
|
|
} else {
|
|
assert.Equal(t, http.StatusNotFound, rw.Code, u)
|
|
}
|
|
}
|
|
|
|
for u, l := range map[string]string{
|
|
"/_testdata/index.html": "./",
|
|
"/_testdata": "_testdata/",
|
|
"/_testdata?abc": "_testdata/?abc",
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusMovedPermanently, rw.Code, u)
|
|
assert.Equal(t, l, rw.Header().Get("Location"))
|
|
}
|
|
}
|
|
|
|
func TestServer_ServeHTTP_error(t *testing.T) {
|
|
s := statigz.FileServer(v, brotli.AddEncoding)
|
|
|
|
req, err := http.NewRequest(http.MethodDelete, "/", nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusMethodNotAllowed, rw.Code)
|
|
assert.Equal(t, "Method Not Allowed\n\nmethod should be GET or HEAD\n", rw.Body.String())
|
|
}
|
|
|
|
func TestServer_ServeHTTP_acceptEncoding(t *testing.T) {
|
|
s := statigz.FileServer(v, brotli.AddEncoding, statigz.EncodeOnInit)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/deeper/swagger.json", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "br", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "3b88egjdndqox", rw.Header().Get("Etag"))
|
|
assert.Len(t, rw.Body.Bytes(), 2548)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip")
|
|
|
|
rw = httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "3b88egjdndqoxU", rw.Header().Get("Etag"))
|
|
assert.Len(t, rw.Body.Bytes(), 24919)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
req.Header.Set("If-None-Match", "3b88egjdndqox")
|
|
|
|
rw = httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusNotModified, rw.Code)
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "", rw.Header().Get("Etag"))
|
|
assert.Len(t, rw.Body.Bytes(), 0)
|
|
}
|
|
|
|
func TestServer_ServeHTTP_badFile(t *testing.T) {
|
|
s := statigz.FileServer(v, brotli.AddEncoding,
|
|
statigz.OnError(func(rw http.ResponseWriter, r *http.Request, err error) {
|
|
assert.EqualError(t, err, "gzip: invalid header")
|
|
|
|
_, err = rw.Write([]byte("failed"))
|
|
assert.NoError(t, err)
|
|
}))
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/bad.png", nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "", rw.Header().Get("Etag"))
|
|
assert.Equal(t, "failed", rw.Body.String())
|
|
}
|
|
|
|
func TestServer_ServeHTTP_head(t *testing.T) {
|
|
s := statigz.FileServer(v, brotli.AddEncoding, statigz.EncodeOnInit)
|
|
|
|
req, err := http.NewRequest(http.MethodHead, "/_testdata/swagger.json", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "br", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "1bp69hxb9nd93.br", rw.Header().Get("Etag"))
|
|
assert.Len(t, rw.Body.String(), 0)
|
|
}
|
|
|
|
func TestServer_ServeHTTP_head_gz(t *testing.T) {
|
|
s := statigz.FileServer(v, statigz.EncodeOnInit)
|
|
|
|
req, err := http.NewRequest(http.MethodHead, "/_testdata/swagger.json", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "gzip", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "1bp69hxb9nd93.gz", rw.Header().Get("Etag"))
|
|
assert.Len(t, rw.Body.String(), 0)
|
|
}
|
|
|
|
func BenchmarkServer_ServeHTTP(b *testing.B) {
|
|
s := statigz.FileServer(v, statigz.EncodeOnInit)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/swagger.json", nil)
|
|
require.NoError(b, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
}
|
|
}
|
|
|
|
func TestServer_ServeHTTP_get_gz(t *testing.T) {
|
|
s := statigz.FileServer(v, statigz.EncodeOnInit)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/swagger.json", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "gzip", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "1bp69hxb9nd93.gz", rw.Header().Get("Etag"))
|
|
assert.Equal(t, "Accept-Encoding", rw.Header().Get("Vary"))
|
|
assert.NotEmpty(t, rw.Body.String())
|
|
|
|
r, err := gzip.NewReader(rw.Body)
|
|
assert.NoError(t, err)
|
|
|
|
decoded, err := io.ReadAll(r)
|
|
assert.NoError(t, err)
|
|
|
|
raw, err := ioutil.ReadFile("_testdata/swagger.json")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, raw, decoded)
|
|
}
|
|
|
|
func TestServer_ServeHTTP_get_br(t *testing.T) {
|
|
s := statigz.FileServer(v, statigz.EncodeOnInit, brotli.AddEncoding)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/swagger.json", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "br", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "1bp69hxb9nd93.br", rw.Header().Get("Etag"))
|
|
assert.NotEmpty(t, rw.Body.String())
|
|
|
|
r := brotli2.NewReader(rw.Body)
|
|
|
|
decoded, err := io.ReadAll(r)
|
|
assert.NoError(t, err)
|
|
|
|
raw, err := ioutil.ReadFile("_testdata/swagger.json")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, raw, decoded)
|
|
}
|
|
|
|
func TestServer_ServeHTTP_indexCompressed(t *testing.T) {
|
|
s := statigz.FileServer(v)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, "/_testdata/", nil)
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip, br")
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code)
|
|
assert.Equal(t, "gzip", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, "45pls0g4wm91", rw.Header().Get("Etag"))
|
|
assert.NotEmpty(t, rw.Body.String())
|
|
|
|
r, err := gzip.NewReader(rw.Body)
|
|
assert.NoError(t, err)
|
|
|
|
decoded, err := io.ReadAll(r)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "Hello!", string(decoded))
|
|
}
|
|
|
|
func TestServer_ServeHTTP_sub(t *testing.T) {
|
|
vs, err := fs.Sub(v, "_testdata")
|
|
require.NoError(t, err)
|
|
|
|
s := statigz.FileServer(vs.(fs.ReadDirFS), brotli.AddEncoding, statigz.EncodeOnInit)
|
|
|
|
for u, found := range map[string]bool{
|
|
"/favicon.png": true,
|
|
"/nonexistent": false,
|
|
"/swagger.json": true,
|
|
"/deeper/swagger.json": true,
|
|
"/deeper/openapi.json": true,
|
|
"/": true,
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
if found {
|
|
assert.Equal(t, "", rw.Header().Get("Content-Encoding"))
|
|
assert.Equal(t, http.StatusOK, rw.Code, u)
|
|
} else {
|
|
assert.Equal(t, http.StatusNotFound, rw.Code, u)
|
|
}
|
|
}
|
|
|
|
for u, l := range map[string]string{
|
|
"/index.html": "./",
|
|
"/deeper": "deeper/",
|
|
"/deeper?abc": "deeper/?abc",
|
|
} {
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
require.NoError(t, err)
|
|
|
|
rw := httptest.NewRecorder()
|
|
s.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, http.StatusMovedPermanently, rw.Code, u)
|
|
assert.Equal(t, l, rw.Header().Get("Location"))
|
|
}
|
|
}
|