You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
3.4 KiB
88 lines
3.4 KiB
package web
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestDownloadServesByteIdenticalFileAsAttachment(t *testing.T) {
|
|
rootPath, handler := newBrowsingApplication(t)
|
|
contents := []byte("the exact source bytes\x00\xff")
|
|
if err := os.WriteFile(filepath.Join(rootPath, "report.txt"), contents, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cookie := completeSeedPasswordChange(t, handler)
|
|
|
|
response := getWithCookie(handler, "/download?root=Media&path=report.txt", cookie)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("GET /download status = %d, want %d", response.Code, http.StatusOK)
|
|
}
|
|
if !bytes.Equal(response.Body.Bytes(), contents) {
|
|
t.Errorf("GET /download bytes = %q, want %q", response.Body.Bytes(), contents)
|
|
}
|
|
if contentType := response.Header().Get("Content-Type"); !strings.HasPrefix(contentType, "text/plain") {
|
|
t.Errorf("GET /download Content-Type = %q, want text/plain", contentType)
|
|
}
|
|
if disposition := response.Header().Get("Content-Disposition"); !strings.HasPrefix(disposition, "attachment;") || !strings.Contains(disposition, "report.txt") {
|
|
t.Errorf("GET /download Content-Disposition = %q, want attachment filename", disposition)
|
|
}
|
|
}
|
|
|
|
func TestStreamHonorsVideoRangeRequests(t *testing.T) {
|
|
rootPath, handler := newBrowsingApplication(t)
|
|
contents := []byte("0123456789")
|
|
if err := os.WriteFile(filepath.Join(rootPath, "clip.mp4"), contents, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cookie := completeSeedPasswordChange(t, handler)
|
|
|
|
request := getRequestWithCookie("/stream?root=Media&path=clip.mp4", cookie)
|
|
request.Header.Set("Range", "bytes=2-5")
|
|
response := serveRequest(handler, request)
|
|
if response.Code != http.StatusPartialContent {
|
|
t.Fatalf("GET /stream Range status = %d, want %d", response.Code, http.StatusPartialContent)
|
|
}
|
|
if body := response.Body.String(); body != "2345" {
|
|
t.Errorf("GET /stream Range bytes = %q, want %q", body, "2345")
|
|
}
|
|
if contentRange := response.Header().Get("Content-Range"); contentRange != "bytes 2-5/10" {
|
|
t.Errorf("GET /stream Content-Range = %q, want %q", contentRange, "bytes 2-5/10")
|
|
}
|
|
if acceptRanges := response.Header().Get("Accept-Ranges"); acceptRanges != "bytes" {
|
|
t.Errorf("GET /stream Accept-Ranges = %q, want %q", acceptRanges, "bytes")
|
|
}
|
|
if contentType := response.Header().Get("Content-Type"); !strings.HasPrefix(contentType, "video/mp4") {
|
|
t.Errorf("GET /stream Content-Type = %q, want video/mp4", contentType)
|
|
}
|
|
}
|
|
|
|
func TestFileDeliveryRoutesRequireAuthentication(t *testing.T) {
|
|
_, handler := newBrowsingApplication(t)
|
|
for _, target := range []string{"/download?root=Media&path=report.txt", "/stream?root=Media&path=clip.mp4"} {
|
|
t.Run(target, func(t *testing.T) {
|
|
response := serveRequest(handler, getRequestWithCookie(target, nil))
|
|
if response.Code != http.StatusSeeOther || response.Header().Get("Location") != loginPath {
|
|
t.Errorf("GET %s status/location = (%d, %q), want (%d, %q)", target, response.Code, response.Header().Get("Location"), http.StatusSeeOther, loginPath)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func getRequestWithCookie(target string, cookie *http.Cookie) *http.Request {
|
|
request := httptest.NewRequest(http.MethodGet, target, nil)
|
|
if cookie != nil {
|
|
request.AddCookie(cookie)
|
|
}
|
|
return request
|
|
}
|
|
|
|
func serveRequest(handler http.Handler, request *http.Request) *httptest.ResponseRecorder {
|
|
response := httptest.NewRecorder()
|
|
handler.ServeHTTP(response, request)
|
|
return response
|
|
}
|
|
|