]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix relURL with leading slash when baseURL includes a subdirectory
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 13 Jun 2022 07:52:02 +0000 (09:52 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 13 Jun 2022 09:40:25 +0000 (11:40 +0200)
Fixes #9994

helpers/pathspec_test.go
helpers/url.go
helpers/url_test.go
hugolib/paths/paths.go

index c112995167194a2cbba0feb28c025f45bca118c6..84448050d5e317af61cd7a5e95172a16dc6dedcd 100644 (file)
@@ -32,7 +32,7 @@ func TestNewPathSpecFromConfig(t *testing.T) {
        v.Set("uglyURLs", true)
        v.Set("canonifyURLs", true)
        v.Set("paginatePath", "side")
-       v.Set("baseURL", "http://base.com")
+       v.Set("baseURL", "http://base.com/foo")
        v.Set("themesDir", "thethemes")
        v.Set("layoutDir", "thelayouts")
        v.Set("workingDir", "thework")
@@ -53,7 +53,10 @@ func TestNewPathSpecFromConfig(t *testing.T) {
        c.Assert(p.Language.Lang, qt.Equals, "no")
        c.Assert(p.PaginatePath, qt.Equals, "side")
 
-       c.Assert(p.BaseURL.String(), qt.Equals, "http://base.com")
+       c.Assert(p.BaseURL.String(), qt.Equals, "http://base.com/foo")
+       c.Assert(p.BaseURLString, qt.Equals, "http://base.com/foo")
+       c.Assert(p.BaseURLNoPathString, qt.Equals, "http://base.com")
+
        c.Assert(p.ThemesDir, qt.Equals, "thethemes")
        c.Assert(p.WorkingDir, qt.Equals, "thework")
 }
index 193dd3c864156c7ae332f62df5ef03490afb86ee..7cb998ca25b85367a5a22f64f110582cfb74d876 100644 (file)
@@ -103,17 +103,11 @@ func (p *PathSpec) AbsURL(in string, addLanguage bool) string {
        }
 
        if url.IsAbs() || strings.HasPrefix(in, "//") {
+               // It  is already  absolute, return it as is.
                return in
        }
 
-       var baseURL string
-       if strings.HasPrefix(in, "/") {
-               u := p.BaseURL.URL()
-               u.Path = ""
-               baseURL = u.String()
-       } else {
-               baseURL = p.BaseURL.String()
-       }
+       baseURL := p.getBaseURLRoot(in)
 
        if addLanguage {
                prefix := p.GetLanguagePrefix()
@@ -140,13 +134,22 @@ func (p *PathSpec) AbsURL(in string, addLanguage bool) string {
                        }
                }
        }
+
        return paths.MakePermalink(baseURL, in).String()
 }
 
-// RelURL creates a URL relative to the BaseURL root.
-// Note: The result URL will not include the context root if canonifyURLs is enabled.
+func (p *PathSpec) getBaseURLRoot(path string) string {
+       if strings.HasPrefix(path, "/") {
+               // Treat it as relative to the server root.
+               return p.BaseURLNoPathString
+       } else {
+               // Treat it as relative to the baseURL.
+               return p.BaseURLString
+       }
+}
+
 func (p *PathSpec) RelURL(in string, addLanguage bool) string {
-       baseURL := p.BaseURL.String()
+       baseURL := p.getBaseURLRoot(in)
        canonifyURLs := p.CanonifyURLs
        if (!strings.HasPrefix(in, baseURL) && strings.HasPrefix(in, "http")) || strings.HasPrefix(in, "//") {
                return in
index f899e1cdbb9c2213991f3d396bc027a55d0dac23..e248036aee9d56ad23e0364f250fda0bf542516e 100644 (file)
@@ -17,6 +17,7 @@ import (
        "strings"
        "testing"
 
+       qt "github.com/frankban/quicktest"
        "github.com/gohugoio/hugo/hugofs"
        "github.com/gohugoio/hugo/langs"
 )
@@ -59,6 +60,7 @@ func TestAbsURL(t *testing.T) {
 }
 
 func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
+       c := qt.New(t)
        v := newTestCfg()
        v.Set("multilingual", multilingual)
        v.Set("defaultContentLanguage", "en")
@@ -69,6 +71,10 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
                baseURL  string
                expected string
        }{
+               // Issue 9994
+               {"foo/bar", "https://example.org/foo/", "https://example.org/foo/MULTIfoo/bar"},
+               {"/foo/bar", "https://example.org/foo/", "https://example.org/MULTIfoo/bar"},
+
                {"/test/foo", "http://base/", "http://base/MULTItest/foo"},
                {"/" + lang + "/test/foo", "http://base/", "http://base/" + lang + "/test/foo"},
                {"", "http://base/ace/", "http://base/ace/MULTI"},
@@ -113,9 +119,8 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
                } else {
                        expected = strings.Replace(expected, "MULTI", "", 1)
                }
-               if output != expected {
-                       t.Fatalf("Expected %#v, got %#v\n", expected, output)
-               }
+
+               c.Assert(output, qt.Equals, expected)
        }
 }
 
@@ -132,6 +137,7 @@ func TestRelURL(t *testing.T) {
 }
 
 func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
+       c := qt.New(t)
        v := newTestCfg()
        v.Set("multilingual", multilingual)
        v.Set("defaultContentLanguage", "en")
@@ -143,13 +149,18 @@ func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
                canonify bool
                expected string
        }{
+
+               // Issue 9994
+               {"/foo/bar", "https://example.org/foo/", false, "MULTI/foo/bar"},
+               {"foo/bar", "https://example.org/foo/", false, "/fooMULTI/foo/bar"},
+
                {"/test/foo", "http://base/", false, "MULTI/test/foo"},
                {"/" + lang + "/test/foo", "http://base/", false, "/" + lang + "/test/foo"},
                {lang + "/test/foo", "http://base/", false, "/" + lang + "/test/foo"},
                {"test.css", "http://base/sub", false, "/subMULTI/test.css"},
                {"test.css", "http://base/sub", true, "MULTI/test.css"},
                {"/test/", "http://base/", false, "MULTI/test/"},
-               {"/test/", "http://base/sub/", false, "/subMULTI/test/"},
+               {"test/", "http://base/sub/", false, "/subMULTI/test/"},
                {"/test/", "http://base/sub/", true, "MULTI/test/"},
                {"", "http://base/ace/", false, "/aceMULTI/"},
                {"", "http://base/ace", false, "/aceMULTI"},
@@ -189,9 +200,8 @@ func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
                        expected = strings.Replace(expected, "MULTI", "", 1)
                }
 
-               if output != expected {
-                       t.Errorf("[%d][%t] Expected %#v, got %#v\n", i, test.canonify, expected, output)
-               }
+               c.Assert(output, qt.Equals, expected, qt.Commentf("[%d] %s", i, test.input))
+
        }
 }
 
index 501665676c2e46bf5aaa1c23532084445096590c..e80215b92a0d5e74f43fdb1d695a392a4c413fa1 100644 (file)
@@ -34,6 +34,8 @@ type Paths struct {
        Cfg config.Provider
 
        BaseURL
+       BaseURLString       string
+       BaseURLNoPathString string
 
        // If the baseURL contains a base path, e.g. https://example.com/docs, then "/docs" will be the BasePath.
        BasePath string
@@ -145,10 +147,17 @@ func New(fs *hugofs.Fs, cfg config.Provider) (*Paths, error) {
                }
        }
 
+       var baseURLString = baseURL.String()
+       var baseURLNoPath = baseURL.URL()
+       baseURLNoPath.Path = ""
+       var baseURLNoPathString = baseURLNoPath.String()
+
        p := &Paths{
-               Fs:      fs,
-               Cfg:     cfg,
-               BaseURL: baseURL,
+               Fs:                  fs,
+               Cfg:                 cfg,
+               BaseURL:             baseURL,
+               BaseURLString:       baseURLString,
+               BaseURLNoPathString: baseURLNoPathString,
 
                DisablePathToLower: cfg.GetBool("disablePathToLower"),
                RemovePathAccents:  cfg.GetBool("removePathAccents"),