mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-16 02:58:35 +02:00
* fix(admin): switch file browser upload/download to filer gRPC + volume HTTP The admin file browser proxied uploads and downloads through the filer's HTTP listener, so the whole feature 404'd against filers started with -disableHttp=true even though S3 still worked on its own port. Re-route through the filer gRPC service: LookupDirectoryEntry + StreamContent for reads (chunks flow straight from the volume servers), AssignVolume + volume HTTP POST + CreateEntry for writes. Volume read tokens come from jwt.signing.read.key when configured; the old jwt.filer_signing tokens no longer apply since the filer HTTP surface is bypassed. * admin file browser: propagate request context + track response writes Pass r.Context() into uploadFileToFiler so a client disconnect cancels the in-flight chunked upload instead of letting it run to completion against the volume servers. For DownloadFile, replace the Content-Type probe with a small response-writer wrapper that records whether headers or bytes have actually been sent, so the error path can't silently convert a pre-stream failure into a partial response if future code moves the header-setting around.
45 lines
1.3 KiB
Go
45 lines
1.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestValidateAndCleanFilePath_AllowsControlChars(t *testing.T) {
|
|
h := &FileBrowserHandlers{}
|
|
|
|
// S3 object keys may legally contain any UTF-8 bytes, including control
|
|
// characters like \n, \r, and \x00. The admin UI must be able to browse
|
|
// and manage such entries rather than silently stripping or rejecting them.
|
|
cases := []struct {
|
|
in string
|
|
want string
|
|
}{
|
|
{"/buckets/profilebuilder/3testGB.zip\n ", "/buckets/profilebuilder/3testGB.zip\n "},
|
|
{"/foo\rbar", "/foo\rbar"},
|
|
{"/foo\x00bar", "/foo\x00bar"},
|
|
{"/normal/path.txt", "/normal/path.txt"},
|
|
// Missing leading slash should be added back.
|
|
{"relative/path.txt", "/relative/path.txt"},
|
|
// Duplicate slashes should be collapsed by path.Clean.
|
|
{"/a//b", "/a/b"},
|
|
}
|
|
for _, tc := range cases {
|
|
got, err := h.validateAndCleanFilePath(tc.in)
|
|
if err != nil {
|
|
t.Errorf("validateAndCleanFilePath(%q) unexpected error: %v", tc.in, err)
|
|
continue
|
|
}
|
|
if got != tc.want {
|
|
t.Errorf("validateAndCleanFilePath(%q) = %q, want %q", tc.in, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateAndCleanFilePath_RejectsEmpty(t *testing.T) {
|
|
h := &FileBrowserHandlers{}
|
|
if _, err := h.validateAndCleanFilePath(""); err == nil {
|
|
t.Errorf("expected empty path rejection")
|
|
}
|
|
}
|
|
|