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 }