mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
Fix relURL with leading slash when baseURL includes a subdirectory
Fixes #9994
This commit is contained in:
parent
617e094482
commit
a5a4422aae
4 changed files with 48 additions and 23 deletions
|
@ -32,7 +32,7 @@ func TestNewPathSpecFromConfig(t *testing.T) {
|
||||||
v.Set("uglyURLs", true)
|
v.Set("uglyURLs", true)
|
||||||
v.Set("canonifyURLs", true)
|
v.Set("canonifyURLs", true)
|
||||||
v.Set("paginatePath", "side")
|
v.Set("paginatePath", "side")
|
||||||
v.Set("baseURL", "http://base.com")
|
v.Set("baseURL", "http://base.com/foo")
|
||||||
v.Set("themesDir", "thethemes")
|
v.Set("themesDir", "thethemes")
|
||||||
v.Set("layoutDir", "thelayouts")
|
v.Set("layoutDir", "thelayouts")
|
||||||
v.Set("workingDir", "thework")
|
v.Set("workingDir", "thework")
|
||||||
|
@ -53,7 +53,10 @@ func TestNewPathSpecFromConfig(t *testing.T) {
|
||||||
c.Assert(p.Language.Lang, qt.Equals, "no")
|
c.Assert(p.Language.Lang, qt.Equals, "no")
|
||||||
c.Assert(p.PaginatePath, qt.Equals, "side")
|
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.ThemesDir, qt.Equals, "thethemes")
|
||||||
c.Assert(p.WorkingDir, qt.Equals, "thework")
|
c.Assert(p.WorkingDir, qt.Equals, "thework")
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,17 +103,11 @@ func (p *PathSpec) AbsURL(in string, addLanguage bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if url.IsAbs() || strings.HasPrefix(in, "//") {
|
if url.IsAbs() || strings.HasPrefix(in, "//") {
|
||||||
|
// It is already absolute, return it as is.
|
||||||
return in
|
return in
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseURL string
|
baseURL := p.getBaseURLRoot(in)
|
||||||
if strings.HasPrefix(in, "/") {
|
|
||||||
u := p.BaseURL.URL()
|
|
||||||
u.Path = ""
|
|
||||||
baseURL = u.String()
|
|
||||||
} else {
|
|
||||||
baseURL = p.BaseURL.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if addLanguage {
|
if addLanguage {
|
||||||
prefix := p.GetLanguagePrefix()
|
prefix := p.GetLanguagePrefix()
|
||||||
|
@ -140,13 +134,22 @@ func (p *PathSpec) AbsURL(in string, addLanguage bool) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths.MakePermalink(baseURL, in).String()
|
return paths.MakePermalink(baseURL, in).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelURL creates a URL relative to the BaseURL root.
|
func (p *PathSpec) getBaseURLRoot(path string) string {
|
||||||
// Note: The result URL will not include the context root if canonifyURLs is enabled.
|
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 {
|
func (p *PathSpec) RelURL(in string, addLanguage bool) string {
|
||||||
baseURL := p.BaseURL.String()
|
baseURL := p.getBaseURLRoot(in)
|
||||||
canonifyURLs := p.CanonifyURLs
|
canonifyURLs := p.CanonifyURLs
|
||||||
if (!strings.HasPrefix(in, baseURL) && strings.HasPrefix(in, "http")) || strings.HasPrefix(in, "//") {
|
if (!strings.HasPrefix(in, baseURL) && strings.HasPrefix(in, "http")) || strings.HasPrefix(in, "//") {
|
||||||
return in
|
return in
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
qt "github.com/frankban/quicktest"
|
||||||
"github.com/gohugoio/hugo/hugofs"
|
"github.com/gohugoio/hugo/hugofs"
|
||||||
"github.com/gohugoio/hugo/langs"
|
"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) {
|
func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
|
||||||
|
c := qt.New(t)
|
||||||
v := newTestCfg()
|
v := newTestCfg()
|
||||||
v.Set("multilingual", multilingual)
|
v.Set("multilingual", multilingual)
|
||||||
v.Set("defaultContentLanguage", "en")
|
v.Set("defaultContentLanguage", "en")
|
||||||
|
@ -69,6 +71,10 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
baseURL string
|
baseURL string
|
||||||
expected 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"},
|
{"/test/foo", "http://base/", "http://base/MULTItest/foo"},
|
||||||
{"/" + lang + "/test/foo", "http://base/", "http://base/" + lang + "/test/foo"},
|
{"/" + lang + "/test/foo", "http://base/", "http://base/" + lang + "/test/foo"},
|
||||||
{"", "http://base/ace/", "http://base/ace/MULTI"},
|
{"", "http://base/ace/", "http://base/ace/MULTI"},
|
||||||
|
@ -113,9 +119,8 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
} else {
|
} else {
|
||||||
expected = strings.Replace(expected, "MULTI", "", 1)
|
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) {
|
func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
|
||||||
|
c := qt.New(t)
|
||||||
v := newTestCfg()
|
v := newTestCfg()
|
||||||
v.Set("multilingual", multilingual)
|
v.Set("multilingual", multilingual)
|
||||||
v.Set("defaultContentLanguage", "en")
|
v.Set("defaultContentLanguage", "en")
|
||||||
|
@ -143,13 +149,18 @@ func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
canonify bool
|
canonify bool
|
||||||
expected string
|
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"},
|
{"/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"},
|
||||||
{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", false, "/subMULTI/test.css"},
|
||||||
{"test.css", "http://base/sub", true, "MULTI/test.css"},
|
{"test.css", "http://base/sub", true, "MULTI/test.css"},
|
||||||
{"/test/", "http://base/", false, "MULTI/test/"},
|
{"/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/"},
|
{"/test/", "http://base/sub/", true, "MULTI/test/"},
|
||||||
{"", "http://base/ace/", false, "/aceMULTI/"},
|
{"", "http://base/ace/", false, "/aceMULTI/"},
|
||||||
{"", "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)
|
expected = strings.Replace(expected, "MULTI", "", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if output != expected {
|
c.Assert(output, qt.Equals, expected, qt.Commentf("[%d] %s", i, test.input))
|
||||||
t.Errorf("[%d][%t] Expected %#v, got %#v\n", i, test.canonify, expected, output)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ type Paths struct {
|
||||||
Cfg config.Provider
|
Cfg config.Provider
|
||||||
|
|
||||||
BaseURL
|
BaseURL
|
||||||
|
BaseURLString string
|
||||||
|
BaseURLNoPathString string
|
||||||
|
|
||||||
// If the baseURL contains a base path, e.g. https://example.com/docs, then "/docs" will be the BasePath.
|
// If the baseURL contains a base path, e.g. https://example.com/docs, then "/docs" will be the BasePath.
|
||||||
BasePath string
|
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{
|
p := &Paths{
|
||||||
Fs: fs,
|
Fs: fs,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
BaseURL: baseURL,
|
BaseURL: baseURL,
|
||||||
|
BaseURLString: baseURLString,
|
||||||
|
BaseURLNoPathString: baseURLNoPathString,
|
||||||
|
|
||||||
DisablePathToLower: cfg.GetBool("disablePathToLower"),
|
DisablePathToLower: cfg.GetBool("disablePathToLower"),
|
||||||
RemovePathAccents: cfg.GetBool("removePathAccents"),
|
RemovePathAccents: cfg.GetBool("removePathAccents"),
|
||||||
|
|
Loading…
Reference in a new issue