Skip to content

Commit

Permalink
Ignore ports for custom domain
Browse files Browse the repository at this point in the history
  • Loading branch information
kiootic committed Nov 30, 2023
1 parent 2f795e3 commit 67b04c9
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 8 deletions.
2 changes: 1 addition & 1 deletion internal/config/app_domain.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package config

type AppDomainConfig struct {
Domain string `json:"domain" pageship:"required,max=200,hostname_port,lowercase"`
Domain string `json:"domain" pageship:"required,max=200,hostname_rfc1123,lowercase"`
Site string `json:"site" pageship:"required,dnsLabel"`
}
27 changes: 20 additions & 7 deletions internal/handler/site/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func NewHandler(ctx context.Context, logger *zap.Logger, domainResolver domain.R
middlewares: conf.Middlewares,
}

cache, err := cache.NewCache(cacheSize, cacheTTL, h.doResolve)
cache, err := cache.NewCache(cacheSize, cacheTTL, h.doResolveHandler)
if err != nil {
return nil, fmt.Errorf("setup cache: %w", err)
}
Expand All @@ -57,13 +57,17 @@ func NewHandler(ctx context.Context, logger *zap.Logger, domainResolver domain.R
return h, nil
}

func (h *Handler) resolveSite(hostname string) (*SiteHandler, error) {
return h.cache.Load(hostname)
func (h *Handler) resolveHandler(host string) (*SiteHandler, error) {
return h.cache.Load(host)
}

func (h *Handler) doResolve(hostname string) (*SiteHandler, error) {
matchedID, ok := h.hostPattern.MatchString(hostname)
func (h *Handler) ResolveSite(host string) (*site.Descriptor, error) {
matchedID, ok := h.hostPattern.MatchString(host)
if !ok {
hostname, _, err := net.SplitHostPort(host)
if err != nil {
hostname = host
}
id, err := h.domainResolver.Resolve(h.ctx, hostname)
if errors.Is(err, domain.ErrDomainNotFound) {
return nil, site.ErrSiteNotFound
Expand All @@ -78,6 +82,15 @@ func (h *Handler) doResolve(hostname string) (*SiteHandler, error) {
return nil, err
}

return desc, nil
}

func (h *Handler) doResolveHandler(host string) (*SiteHandler, error) {
desc, err := h.ResolveSite(host)
if err != nil {
return nil, err
}

return NewSiteHandler(desc, h.middlewares), nil
}

Expand All @@ -89,7 +102,7 @@ func (h *Handler) CheckValidDomain(hostname string) error {
if h.siteResolver.IsWildcard() {
return nil
}
_, err := h.resolveSite(hostname)
_, err := h.ResolveSite(hostname)
return err
}

Expand All @@ -112,7 +125,7 @@ func (h *Handler) checkAuthz(r *http.Request, handler *SiteHandler) error {
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
handler, err := h.resolveSite(r.Host)
handler, err := h.resolveHandler(r.Host)
if errors.Is(err, site.ErrSiteNotFound) {
http.NotFound(w, r)
return
Expand Down
86 changes: 86 additions & 0 deletions internal/handler/site/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package site_test

import (
"context"
"errors"
"testing"

"github.com/oursky/pageship/internal/domain"
sitehandler "github.com/oursky/pageship/internal/handler/site"
"github.com/oursky/pageship/internal/site"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
)

type mockDomainResolver struct {
domains map[string]string
}

func (*mockDomainResolver) Kind() string { return "mock" }

func (r *mockDomainResolver) Resolve(ctx context.Context, hostname string) (string, error) {
if id, ok := r.domains[hostname]; ok {
return id, nil
}
return "", domain.ErrDomainNotFound
}

type mockSiteResolver struct {
wildcard bool
sites map[string]string
}

func (r *mockSiteResolver) IsWildcard() bool { return r.wildcard }

func (*mockSiteResolver) Kind() string { return "mock" }

func (r *mockSiteResolver) Resolve(ctx context.Context, matchedID string) (*site.Descriptor, error) {
if id, ok := r.sites[matchedID]; ok {
return &site.Descriptor{ID: id}, nil
}
return nil, site.ErrSiteNotFound
}

func TestHandleResolution(t *testing.T) {
hostPattern := "http://*.pageship.local"
domainResolver := &mockDomainResolver{
domains: map[string]string{
"example.com": "example",
"dev.example.com": "dev.example",
},
}
siteResolver := &mockSiteResolver{
sites: map[string]string{
"example": "example/main",
"dev.example": "example/dev",
"test": "test/main",
"dev.test": "test/dev",
},
}

handler, err := sitehandler.NewHandler(context.Background(), zap.NewNop(),
domainResolver, siteResolver, sitehandler.HandlerConfig{HostPattern: hostPattern})
assert.NoError(t, err)

resolve := func(host string) any {
desc, err := handler.ResolveSite(host)
if errors.Is(err, site.ErrSiteNotFound) {
return nil
} else if err != nil {
panic(err)
}
return desc
}

assert.Equal(t, resolve("example.com"), &site.Descriptor{ID: "example/main"})
assert.Equal(t, resolve("example.com:8001"), &site.Descriptor{ID: "example/main"})
assert.Equal(t, resolve("dev.example.com"), &site.Descriptor{ID: "example/dev"})
assert.Equal(t, resolve("example.local"), nil)

assert.Equal(t, resolve("test.pageship.local"), &site.Descriptor{ID: "test/main"})
assert.Equal(t, resolve("dev.test.pageship.local"), &site.Descriptor{ID: "test/dev"})
assert.Equal(t, resolve("dev.test.pageship.local:8001"), &site.Descriptor{ID: "test/dev"})
assert.Equal(t, resolve("staging.test.pageship.local"), nil)
assert.Equal(t, resolve("pageship.local"), nil)
assert.Equal(t, resolve("main.pageship.local"), nil)
}

0 comments on commit 67b04c9

Please sign in to comment.