From fdff1a54ee67977b755a8c6fcfa33befad6e41b4 Mon Sep 17 00:00:00 2001 From: Oleg Kunitsyn <114359669+hiddenmarten@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:40:00 +0100 Subject: [PATCH] http: fix incorrect URLs with initial slash * http: trim initial slash building url * Add a test for http object with leading slash Fixes #8261 --- backend/http/http.go | 5 +++-- backend/http/http_internal_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/backend/http/http.go b/backend/http/http.go index ce03bb9bd..60c6cb99c 100644 --- a/backend/http/http.go +++ b/backend/http/http.go @@ -331,12 +331,13 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { // Join's the remote onto the base URL func (f *Fs) url(remote string) string { + trimmedRemote := strings.TrimLeft(remote, "/") // remove leading "/" since we always have it in f.endpointURL if f.opt.NoEscape { // Directly concatenate without escaping, no_escape behavior - return f.endpointURL + remote + return f.endpointURL + trimmedRemote } // Default behavior - return f.endpointURL + rest.URLPathEscape(remote) + return f.endpointURL + rest.URLPathEscape(trimmedRemote) } // Errors returned by parseName diff --git a/backend/http/http_internal_test.go b/backend/http/http_internal_test.go index 307bbc559..90a2bae78 100644 --- a/backend/http/http_internal_test.go +++ b/backend/http/http_internal_test.go @@ -191,6 +191,33 @@ func TestNewObject(t *testing.T) { assert.Equal(t, fs.ErrorObjectNotFound, err) } +func TestNewObjectWithLeadingSlash(t *testing.T) { + f := prepare(t) + + o, err := f.NewObject(context.Background(), "/four/under four.txt") + require.NoError(t, err) + + assert.Equal(t, "/four/under four.txt", o.Remote()) + assert.Equal(t, int64(8+lineEndSize), o.Size()) + _, ok := o.(*Object) + assert.True(t, ok) + + // Test the time is correct on the object + + tObj := o.ModTime(context.Background()) + + fi, err := os.Stat(filepath.Join(filesPath, "four", "under four.txt")) + require.NoError(t, err) + tFile := fi.ModTime() + + fstest.AssertTimeEqualWithPrecision(t, o.Remote(), tFile, tObj, time.Second) + + // check object not found + o, err = f.NewObject(context.Background(), "/not found.txt") + assert.Nil(t, o) + assert.Equal(t, fs.ErrorObjectNotFound, err) +} + func TestOpen(t *testing.T) { m := prepareServer(t)