Skip to content

Commit

Permalink
feat: add new option for setting a custom hostname
Browse files Browse the repository at this point in the history
By default hostname is parsed from HTTP request.
  • Loading branch information
kare committed Oct 19, 2023
1 parent 606f2d2 commit e41d57b
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 2 deletions.
19 changes: 17 additions & 2 deletions vanity.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type (
log Logger
vcs string
vcsURL string
host string
moduleServerURL string
static *staticDir
indexPageHandler http.Handler
Expand Down Expand Up @@ -71,6 +72,10 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

host := r.Host
if h.host != "" {
host = h.host
}
// Respond to Go tool with vcs info meta tag
if r.FormValue("go-get") == "1" {
path := r.URL.Path
Expand All @@ -84,7 +89,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vcsroot = h.vcsURL + shortPath[0]
}

importRoot := strings.TrimSuffix(r.Host+r.URL.Path, "/")
importRoot := strings.TrimSuffix(host+r.URL.Path, "/")
metaTag := fmt.Sprintf(`<meta name="go-import" content="%v %v %v">`, importRoot, h.vcs, vcsroot)
if _, err := w.Write([]byte(metaTag)); err != nil {
h.log.Printf("vanity: i/o error writing go tool http response: %v", err)
Expand All @@ -93,7 +98,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

// Redirect browsers to Go module site.
url := h.browserURL(r.Host, r.URL.Path)
url := h.browserURL(host, r.URL.Path)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

Expand Down Expand Up @@ -175,6 +180,16 @@ func VCSURL(vcsURL string) Option {
}
}

// Host sets the hostname of the vanity server. Host defaults to HTTP request
// hostname.
func Host(host string) Option {
return func(h http.Handler) error {
v := h.(*handler)
v.host = host
return nil
}
}

// Log sets the logger used by vanity package's error logger.
func Log(l Logger) Option {
return func(h http.Handler) error {
Expand Down
88 changes: 88 additions & 0 deletions vanity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,93 @@ func TestHTTPMethodsSupport(t *testing.T) {
}
}

func TestHostOptionGoTool(t *testing.T) {
tests := []struct {
name string
url string
result string
}{
{
name: "host go.kkn.fi/vanity redirects to kkn.fi/vanity",
url: "https://go.kkn.fi/vanity?go-get=1",
result: "kkn.fi/vanity git https://github.com/kare/vanity",
},
{
name: "hostname go.kkn.fi/infra redirects to kkn.fi/infra",
url: "https://go.kkn.fi/infra?go-get=1",
result: "kkn.fi/infra git https://github.com/kare/infra",
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, test.url, nil)
srv, err := vanity.NewHandlerWithOptions(
vanity.VCSURL("https://github.com/kare"),
vanity.Host("kkn.fi"),
)
if err != nil {
t.Error(err)
}
srv.ServeHTTP(rec, req)
res := rec.Result()
if res.StatusCode != http.StatusOK {
t.Errorf("expected response status %v, but got %v", http.StatusOK, res.StatusCode)
}
body, _ := io.ReadAll(res.Body)
if !strings.Contains(string(body), test.result) {
t.Errorf("expecting\n%v be contained in\n%v", test.result, string(body))
}
})
}
}
func TestHostOptionBrowserGoDoc(t *testing.T) {
tests := []struct {
name string
url string
result string
}{
{
name: "host go.kkn.fi/vanity redirects to kkn.fi/vanity",
url: "https://go.kkn.fi/vanity",
result: `<a href="https://pkg.go.dev/kkn.fi/vanity">Temporary Redirect</a>.`,
},
{
name: "hostname go.kkn.fi/infra redirects to kkn.fi/infra",
url: "https://go.kkn.fi/infra",
result: `<a href="https://pkg.go.dev/kkn.fi/infra">Temporary Redirect</a>.`,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, test.url, nil)
srv, err := vanity.NewHandlerWithOptions(
vanity.VCSURL("https://github.com/kare"),
vanity.Host("kkn.fi"),
)
if err != nil {
t.Error(err)
}
srv.ServeHTTP(rec, req)
res := rec.Result()
if res.StatusCode != http.StatusTemporaryRedirect {
t.Errorf("expected response status %v, but got %v", http.StatusTemporaryRedirect, res.StatusCode)
}
body, _ := io.ReadAll(res.Body)
if !strings.Contains(string(body), test.result) {
t.Errorf("expecting\n%v be contained in\n%v", test.result, string(body))
}
})
}
}

func TestIndexPageNotFound(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -357,6 +444,7 @@ func ExampleHandler() {
vanity.ModuleServerURL("https://pkg.go.dev"),
vanity.VCSURL("https://github.com/kare"),
vanity.VCS("git"),
vanity.Host("go.kkn.fi"),
vanity.Log(errorLog),
vanity.StaticDir("testdata", "/.static/"),
vanity.IndexPageHandler(vanity.DefaultIndexPageHandler("testdata/index.html")),
Expand Down

0 comments on commit e41d57b

Please sign in to comment.