shithub: hugo

Download patch

ref: 0ad378b09cea90a2a70d7ff06af668abe22475a1
parent: aebfe156fb2f27057e61b2e50c7576e6b06dab58
author: sth <sth.dev@tejp.de>
date: Wed Dec 2 07:52:26 EST 2020

Use --baseURL path for live-reload URL

Fixes #6595

--- a/commands/server.go
+++ b/commands/server.go
@@ -357,7 +357,9 @@
 					if !f.c.paused {
 						port = f.c.Cfg.GetInt("liveReloadPort")
 					}
-					fmt.Fprint(w, injectLiveReloadScript(r, port))
+					lr := *u
+					lr.Host = fmt.Sprintf("%s:%d", lr.Hostname(), port)
+					fmt.Fprint(w, injectLiveReloadScript(r, lr))
 
 					return
 				}
@@ -501,8 +503,13 @@
 		mu, serverURL, endpoint, err := srv.createEndpoint(i)
 
 		if doLiveReload {
-			mu.HandleFunc("/livereload.js", livereload.ServeJS)
-			mu.HandleFunc("/livereload", livereload.Handler)
+			u, err := url.Parse(helpers.SanitizeURL(baseURLs[i]))
+			if err != nil {
+				return err
+			}
+
+			mu.HandleFunc(u.Path+"/livereload.js", livereload.ServeJS)
+			mu.HandleFunc(u.Path+"/livereload", livereload.Handler)
 		}
 		jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, s.serverInterface)
 		go func() {
--- a/commands/server_errors.go
+++ b/commands/server_errors.go
@@ -16,6 +16,7 @@
 import (
 	"bytes"
 	"io"
+	"net/url"
 
 	"github.com/gohugoio/hugo/transform"
 	"github.com/gohugoio/hugo/transform/livereloadinject"
@@ -82,9 +83,9 @@
 </html>
 `
 
-func injectLiveReloadScript(src io.Reader, port int) string {
+func injectLiveReloadScript(src io.Reader, baseURL url.URL) string {
 	var b bytes.Buffer
-	chain := transform.Chain{livereloadinject.New(port)}
+	chain := transform.Chain{livereloadinject.New(baseURL)}
 	chain.Apply(&b, src)
 
 	return b.String()
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1716,7 +1716,10 @@
 		}
 
 		if s.running() && s.Cfg.GetBool("watch") && !s.Cfg.GetBool("disableLiveReload") {
-			pd.LiveReloadPort = s.Cfg.GetInt("liveReloadPort")
+			pd.LiveReloadBaseURL = s.PathSpec.BaseURL.URL()
+			if s.Cfg.GetInt("liveReloadPort") != -1 {
+				pd.LiveReloadBaseURL.Host = fmt.Sprintf("%s:%d", pd.LiveReloadBaseURL.Hostname(), s.Cfg.GetInt("liveReloadPort"))
+			}
 		}
 
 		// For performance reasons we only inject the Hugo generator tag on the home page.
--- a/publisher/publisher.go
+++ b/publisher/publisher.go
@@ -16,6 +16,7 @@
 import (
 	"errors"
 	"io"
+	"net/url"
 	"sync/atomic"
 
 	"github.com/gohugoio/hugo/resources"
@@ -51,8 +52,8 @@
 	StatCounter *uint64
 
 	// Configuration that trigger pre-processing.
-	// LiveReload script will be injected if this is > 0
-	LiveReloadPort int
+	// LiveReload script will be injected if this is != nil
+	LiveReloadBaseURL *url.URL
 
 	// Enable to inject the Hugo generated tag in the header. Is currently only
 	// injected on the home page for HTML type of output formats.
@@ -166,8 +167,8 @@
 	}
 
 	if isHTML {
-		if f.LiveReloadPort > 0 {
-			transformers = append(transformers, livereloadinject.New(f.LiveReloadPort))
+		if f.LiveReloadBaseURL != nil {
+			transformers = append(transformers, livereloadinject.New(*f.LiveReloadBaseURL))
 		}
 
 		// This is only injected on the home page.
--- a/transform/livereloadinject/livereloadinject.go
+++ b/transform/livereloadinject/livereloadinject.go
@@ -16,6 +16,9 @@
 import (
 	"bytes"
 	"fmt"
+	"html"
+	"net/url"
+	"strings"
 
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/gohugoio/hugo/transform"
@@ -35,7 +38,8 @@
 
 // New creates a function that can be used
 // to inject a script tag for the livereload JavaScript in a HTML document.
-func New(port int) transform.Transformer {
+func New(baseURL url.URL) transform.Transformer {
+
 	return func(ft transform.FromTo) error {
 		b := ft.From().Bytes()
 		var idx = -1
@@ -51,6 +55,12 @@
 			}
 		}
 
+		path := strings.TrimSuffix(baseURL.Path, "/")
+
+		src := path + "/livereload.js?mindelay=10&v=2"
+		src += "&port=" + baseURL.Port()
+		src += "&path=" + strings.TrimPrefix(path+"/livereload", "/")
+
 		c := make([]byte, len(b))
 		copy(c, b)
 
@@ -59,7 +69,7 @@
 			return err
 		}
 
-		script := []byte(fmt.Sprintf(`<script src="/livereload.js?port=%d&amp;mindelay=10&amp;v=2" data-no-instant defer></script>`, port))
+		script := []byte(fmt.Sprintf(`<script src="%s" data-no-instant defer></script>`, html.EscapeString(src)))
 
 		i := idx
 		if match.appendScript {
--- a/transform/livereloadinject/livereloadinject_test.go
+++ b/transform/livereloadinject/livereloadinject_test.go
@@ -15,6 +15,7 @@
 
 import (
 	"bytes"
+	"net/url"
 	"strings"
 	"testing"
 
@@ -25,12 +26,17 @@
 func TestLiveReloadInject(t *testing.T) {
 	c := qt.New(t)
 
-	expectBase := `<script src="/livereload.js?port=1313&amp;mindelay=10&amp;v=2" data-no-instant defer></script>`
+	lrurl, err := url.Parse("http://localhost:1234/subpath")
+	if err != nil {
+		t.Errorf("Parsing test URL failed")
+		return
+	}
+	expectBase := `<script src="/subpath/livereload.js?mindelay=10&amp;v=2&amp;port=1234&amp;path=subpath/livereload" data-no-instant defer></script>`
 	apply := func(s string) string {
 		out := new(bytes.Buffer)
 		in := strings.NewReader(s)
 
-		tr := transform.New(New(1313))
+		tr := transform.New(New(*lrurl))
 		tr.Apply(out, in)
 
 		return out.String()