Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2019-10-01 12:53:16 +0300
committerKamil Trzciński <ayufan@ayufan.eu>2019-10-01 12:53:16 +0300
commitb37ed1c0ff9880fb73ed2ed771c100333d79f3c5 (patch)
treee7e60fab0101acbda400e9cd98cf843cecc49236
parent9660a822ed42dd28fa1d7e878a1a7f05c2b351b5 (diff)
Refactor the code to use `Serving/LookupPath`
This moves the code from the concept of `Project` to use a concept of `LookupPath`. This makes the `LookupPath` to define a `Path` on disk that the data is being served from. This makes the `ACME` to not have special handling, but rather try to serve the file if succeeds, skip GitLab passthrough for ACME.
-rw-r--r--internal/acme/acme.go4
-rw-r--r--internal/acme/acme_test.go8
-rw-r--r--internal/domain/domain.go41
-rw-r--r--internal/domain/domain_test.go38
-rw-r--r--internal/domain/handler.go42
-rw-r--r--internal/domain/resolver.go8
-rw-r--r--internal/serving/disk.go19
-rw-r--r--internal/serving/disk/handler.go11
-rw-r--r--internal/serving/disk/reader.go27
-rw-r--r--internal/serving/disk/serving.go28
-rw-r--r--internal/serving/handler.go20
-rw-r--r--internal/serving/lookup_path.go (renamed from internal/domain/project.go)7
-rw-r--r--internal/serving/serving.go16
-rw-r--r--internal/source/disk/custom.go11
-rw-r--r--internal/source/disk/domain_test.go36
-rw-r--r--internal/source/disk/group.go21
-rw-r--r--internal/source/disk/map.go22
17 files changed, 126 insertions, 233 deletions
diff --git a/internal/acme/acme.go b/internal/acme/acme.go
index a6be01de..3bfa8f2e 100644
--- a/internal/acme/acme.go
+++ b/internal/acme/acme.go
@@ -18,7 +18,7 @@ type Middleware struct {
// Domain interface represent D from domain package
type Domain interface {
- HasAcmeChallenge(*http.Request, string) bool
+ ServeFileHTTP(w http.ResponseWriter, r *http.Request) bool
}
// ServeAcmeChallenges identifies if request is acme-challenge and redirects to GitLab in that case
@@ -31,7 +31,7 @@ func (m *Middleware) ServeAcmeChallenges(w http.ResponseWriter, r *http.Request,
return false
}
- if domain.HasAcmeChallenge(r, filepath.Base(r.URL.Path)) {
+ if domain.ServeFileHTTP(w, r) {
return false
}
diff --git a/internal/acme/acme_test.go b/internal/acme/acme_test.go
index 00932d3e..ab191694 100644
--- a/internal/acme/acme_test.go
+++ b/internal/acme/acme_test.go
@@ -11,8 +11,12 @@ type domainStub struct {
hasAcmeChallenge bool
}
-func (d *domainStub) HasAcmeChallenge(_ *http.Request, _ string) bool {
- return d.hasAcmeChallenge
+func (d *domainStub) ServeFileHTTP(w http.ResponseWriter, r *http.Request) bool {
+ if r.URL.Path == "/.well-known/acme-challenge/token" {
+ return d.hasAcmeChallenge
+ }
+
+ return false
}
func serveAcmeOrNotFound(m *Middleware, domain Domain) http.HandlerFunc {
diff --git a/internal/domain/domain.go b/internal/domain/domain.go
index df484dd2..2941d174 100644
--- a/internal/domain/domain.go
+++ b/internal/domain/domain.go
@@ -8,19 +8,18 @@ import (
"gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
"gitlab.com/gitlab-org/gitlab-pages/internal/serving"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving/disk"
)
// Domain is a domain that gitlab-pages can serve.
type Domain struct {
Name string
- Location string
CertificateCert string
CertificateKey string
Resolver Resolver
- lookupPaths map[string]*Project
- serving serving.Serving
+ serving serving.Serving
certificate *tls.Certificate
certificateError error
@@ -40,7 +39,7 @@ func (d *Domain) isUnconfigured() bool {
return d.Resolver == nil
}
-func (d *Domain) resolve(r *http.Request) (*Project, string) {
+func (d *Domain) resolve(r *http.Request) (*serving.LookupPath, string) {
// TODO use lookupPaths to cache information about projects better, to
// improve performance and resilience
@@ -55,7 +54,7 @@ func (d *Domain) resolve(r *http.Request) (*Project, string) {
}
// GetProject returns a project details based on the request
-func (d *Domain) GetProject(r *http.Request) *Project {
+func (d *Domain) GetProject(r *http.Request) *serving.LookupPath {
project, _ := d.resolve(r)
return project
@@ -64,20 +63,20 @@ func (d *Domain) GetProject(r *http.Request) *Project {
// Serving returns domain serving driver
func (d *Domain) Serving() serving.Serving {
if d.serving == nil {
- d.serving = serving.NewDiskServing(d.Name, d.Location)
+ d.serving = disk.New()
}
return d.serving
}
-func (d *Domain) toHandler(w http.ResponseWriter, r *http.Request) *handler {
+func (d *Domain) toHandler(w http.ResponseWriter, r *http.Request) serving.Handler {
project, subpath := d.resolve(r)
- return &handler{
- writer: w,
- request: r,
- project: project,
- subpath: subpath,
+ return serving.Handler{
+ Writer: w,
+ Request: r,
+ LookupPath: project,
+ SubPath: subpath,
}
}
@@ -108,20 +107,6 @@ func (d *Domain) IsAccessControlEnabled(r *http.Request) bool {
return false
}
-// HasAcmeChallenge checks domain directory contains particular acme challenge
-func (d *Domain) HasAcmeChallenge(r *http.Request, token string) bool {
- // TODO is that safe to redirect to acme challenge in GitLab if it is a grup domain?
- if d.isUnconfigured() || !d.HasProject(r) {
- return false
- }
-
- // TODO we should improve that, we need different type of information to
- // check if the ACME challenge is present in the serving. We should devise a
- // better interface here or we should to extract this responsibility
- // somewhere else.
- return d.Serving().HasAcmeChallenge(d.toHandler(nil, r), token)
-}
-
// IsNamespaceProject figures out if the request is to a namespace project
func (d *Domain) IsNamespaceProject(r *http.Request) bool {
if d.isUnconfigured() {
@@ -180,6 +165,10 @@ func (d *Domain) EnsureCertificate() (*tls.Certificate, error) {
// ServeFileHTTP returns true if something was served, false if not.
func (d *Domain) ServeFileHTTP(w http.ResponseWriter, r *http.Request) bool {
if d.isUnconfigured() || !d.HasProject(r) {
+ // TODO: this seems to be wrong:
+ // as we should rather return false,
+ // and fallback to `ServeNotFoundHTTP`
+ // to handle this case
httperrors.Serve404(w)
return true
}
diff --git a/internal/domain/domain_test.go b/internal/domain/domain_test.go
index 8b369075..a43d3c9a 100644
--- a/internal/domain/domain_test.go
+++ b/internal/domain/domain_test.go
@@ -11,16 +11,17 @@ import (
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
"gitlab.com/gitlab-org/gitlab-pages/internal/testhelpers"
)
type stubbedResolver struct {
- project *Project
+ project *serving.LookupPath
subpath string
err error
}
-func (resolver *stubbedResolver) Resolve(*http.Request) (*Project, string, error) {
+func (resolver *stubbedResolver) Resolve(*http.Request) (*serving.LookupPath, string, error) {
return resolver.project, resolver.subpath, resolver.err
}
@@ -42,8 +43,12 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Custom domain with HTTPS-only enabled",
domain: &Domain{
- Location: "group/project",
- Resolver: &stubbedResolver{project: &Project{IsHTTPSOnly: true}},
+ Resolver: &stubbedResolver{
+ project: &serving.LookupPath{
+ Path: "group/project/public",
+ IsHTTPSOnly: true,
+ },
+ },
},
url: "http://custom-domain",
expected: true,
@@ -51,17 +56,19 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Custom domain with HTTPS-only disabled",
domain: &Domain{
- Location: "group/project",
- Resolver: &stubbedResolver{project: &Project{IsHTTPSOnly: false}},
+ Resolver: &stubbedResolver{
+ project: &serving.LookupPath{
+ Path: "group/project/public",
+ IsHTTPSOnly: false,
+ },
+ },
},
url: "http://custom-domain",
expected: false,
},
{
- name: "Unknown project",
- domain: &Domain{
- Location: "group/project",
- },
+ name: "Unknown project",
+ domain: &Domain{},
url: "http://test-domain/project",
expected: false,
},
@@ -106,17 +113,13 @@ func TestPredefined404ServeHTTP(t *testing.T) {
cleanup := setUpTests(t)
defer cleanup()
- testDomain := &Domain{
- Location: "group",
- }
+ testDomain := &Domain{}
testhelpers.AssertHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.test.io/not-existing-file", nil, "The page you're looking for could not be found")
}
func TestGroupCertificate(t *testing.T) {
- testGroup := &Domain{
- Location: "group",
- }
+ testGroup := &Domain{}
tls, err := testGroup.EnsureCertificate()
require.Nil(t, tls)
@@ -125,8 +128,7 @@ func TestGroupCertificate(t *testing.T) {
func TestDomainNoCertificate(t *testing.T) {
testDomain := &Domain{
- Name: "test.domain.com",
- Location: "group/project2",
+ Name: "test.domain.com",
}
tls, err := testDomain.EnsureCertificate()
diff --git a/internal/domain/handler.go b/internal/domain/handler.go
deleted file mode 100644
index 55697700..00000000
--- a/internal/domain/handler.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package domain
-
-import "net/http"
-
-type handler struct {
- writer http.ResponseWriter
- request *http.Request
- project *Project
- subpath string
-}
-
-func (h *handler) Writer() http.ResponseWriter {
- return h.writer
-}
-
-func (h *handler) Request() *http.Request {
- return h.request
-}
-
-func (h *handler) LookupPath() string {
- return h.project.LookupPath
-}
-
-func (h *handler) Subpath() string {
- return h.subpath
-}
-
-func (h *handler) IsNamespaceProject() bool {
- return h.project.IsNamespaceProject
-}
-
-func (h *handler) IsHTTPSOnly() bool {
- return h.project.IsHTTPSOnly
-}
-
-func (h *handler) HasAccessControl() bool {
- return h.project.HasAccessControl
-}
-
-func (h *handler) ProjectID() uint64 {
- return h.project.ID
-}
diff --git a/internal/domain/resolver.go b/internal/domain/resolver.go
index 5bde31ec..0de66ad5 100644
--- a/internal/domain/resolver.go
+++ b/internal/domain/resolver.go
@@ -1,10 +1,14 @@
package domain
-import "net/http"
+import (
+ "net/http"
+
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
+)
// Resolver represents an interface responsible for resolving a project
// per-request
type Resolver interface {
// Resolve returns a project with a file path and an error if it occured
- Resolve(*http.Request) (*Project, string, error)
+ Resolve(*http.Request) (*serving.LookupPath, string, error)
}
diff --git a/internal/serving/disk.go b/internal/serving/disk.go
deleted file mode 100644
index b569986f..00000000
--- a/internal/serving/disk.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package serving
-
-import "gitlab.com/gitlab-org/gitlab-pages/internal/serving/disk"
-
-type diskServing struct {
- disk *disk.Serving
-}
-
-func (d *diskServing) ServeFileHTTP(h Handler) bool {
- return d.disk.ServeFileHTTP(h)
-}
-
-func (d *diskServing) ServeNotFoundHTTP(h Handler) {
- d.disk.ServeNotFoundHTTP(h)
-}
-
-func (d *diskServing) HasAcmeChallenge(h Handler, token string) bool {
- return d.disk.HasAcmeChallenge(h, token)
-}
diff --git a/internal/serving/disk/handler.go b/internal/serving/disk/handler.go
deleted file mode 100644
index fbbf9ce3..00000000
--- a/internal/serving/disk/handler.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package disk
-
-import "net/http"
-
-type handler interface {
- Writer() http.ResponseWriter
- Request() *http.Request
- LookupPath() string
- Subpath() string
- HasAccessControl() bool
-}
diff --git a/internal/serving/disk/reader.go b/internal/serving/disk/reader.go
index 1fc30da7..b52b5cff 100644
--- a/internal/serving/disk/reader.go
+++ b/internal/serving/disk/reader.go
@@ -9,23 +9,24 @@ import (
"strconv"
"strings"
"time"
+
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
)
// Reader is a disk access driver
type Reader struct {
- Location string
}
-func (reader *Reader) tryFile(h handler) error {
- fullPath, err := reader.resolvePath(h.LookupPath(), h.Subpath())
+func (reader *Reader) tryFile(h serving.Handler) error {
+ fullPath, err := reader.resolvePath(h.LookupPath.Path, h.SubPath)
- request := h.Request()
+ request := h.Request
host := request.Host
urlPath := request.URL.Path
if locationError, _ := err.(*locationDirectoryError); locationError != nil {
if endsWithSlash(urlPath) {
- fullPath, err = reader.resolvePath(h.LookupPath(), h.Subpath(), "index.html")
+ fullPath, err = reader.resolvePath(h.LookupPath.Path, h.SubPath, "index.html")
} else {
// Concat Host with URL.Path
redirectPath := "//" + host + "/"
@@ -33,29 +34,29 @@ func (reader *Reader) tryFile(h handler) error {
// Ensure that there's always "/" at end
redirectPath = strings.TrimSuffix(redirectPath, "/") + "/"
- http.Redirect(h.Writer(), h.Request(), redirectPath, 302)
+ http.Redirect(h.Writer, h.Request, redirectPath, 302)
return nil
}
}
if locationError, _ := err.(*locationFileNoExtensionError); locationError != nil {
- fullPath, err = reader.resolvePath(h.LookupPath(), strings.TrimSuffix(h.Subpath(), "/")+".html")
+ fullPath, err = reader.resolvePath(h.LookupPath.Path, strings.TrimSuffix(h.SubPath, "/")+".html")
}
if err != nil {
return err
}
- return reader.serveFile(h.Writer(), h.Request(), fullPath, h.HasAccessControl())
+ return reader.serveFile(h.Writer, h.Request, fullPath, h.LookupPath.HasAccessControl)
}
-func (reader *Reader) tryNotFound(h handler) error {
- page404, err := reader.resolvePath(h.LookupPath(), "404.html")
+func (reader *Reader) tryNotFound(h serving.Handler) error {
+ page404, err := reader.resolvePath(h.LookupPath.Path, "404.html")
if err != nil {
return err
}
- err = reader.serveCustomFile(h.Writer(), h.Request(), http.StatusNotFound, page404)
+ err = reader.serveCustomFile(h.Writer, h.Request, http.StatusNotFound, page404)
if err != nil {
return err
}
@@ -64,9 +65,7 @@ func (reader *Reader) tryNotFound(h handler) error {
// Resolve the HTTP request to a path on disk, converting requests for
// directories to requests for index.html inside the directory if appropriate.
-func (reader *Reader) resolvePath(lookupPath string, subPath ...string) (string, error) {
- publicPath := filepath.Join(reader.Location, lookupPath, "public")
-
+func (reader *Reader) resolvePath(publicPath string, subPath ...string) (string, error) {
// Don't use filepath.Join as cleans the path,
// where we want to traverse full path as supplied by user
// (including ..)
diff --git a/internal/serving/disk/serving.go b/internal/serving/disk/serving.go
index 78b1b572..db184d3c 100644
--- a/internal/serving/disk/serving.go
+++ b/internal/serving/disk/serving.go
@@ -2,17 +2,17 @@ package disk
import (
"gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
)
// Serving describes a disk access serving
type Serving struct {
- Domain string // TODO it is not used but might be handy
- *Reader
+ Reader
}
// ServeFileHTTP serves a file from disk and returns true. It returns false
// when a file could not been found.
-func (s *Serving) ServeFileHTTP(h handler) bool {
+func (s *Serving) ServeFileHTTP(h serving.Handler) bool {
if s.tryFile(h) == nil {
return true
}
@@ -21,27 +21,17 @@ func (s *Serving) ServeFileHTTP(h handler) bool {
}
// ServeNotFoundHTTP tries to read a custom 404 page
-func (s *Serving) ServeNotFoundHTTP(h handler) {
+func (s *Serving) ServeNotFoundHTTP(h serving.Handler) {
if s.tryNotFound(h) == nil {
return
}
// Generic 404
- httperrors.Serve404(h.Writer())
+ httperrors.Serve404(h.Writer)
}
-// HasAcmeChallenge checks if the ACME challenge is present on the disk
-func (s *Serving) HasAcmeChallenge(h handler, token string) bool {
- _, err := s.resolvePath(h.LookupPath(), ".well-known/acme-challenge", token)
- // there is an acme challenge on disk
- if err == nil {
- return true
- }
-
- _, err = s.resolvePath(h.LookupPath(), ".well-known/acme-challenge", token, "index.html")
- if err == nil {
- return true
- }
-
- return false
+// New returns a serving instance that is capable of reading files
+// from the disk
+func New() serving.Serving {
+ return &Serving{}
}
diff --git a/internal/serving/handler.go b/internal/serving/handler.go
index 2a9969b7..446c9843 100644
--- a/internal/serving/handler.go
+++ b/internal/serving/handler.go
@@ -2,15 +2,13 @@ package serving
import "net/http"
-// Handler interface represent an interface that is needed to fullfil the
-// serving request
-type Handler interface {
- Writer() http.ResponseWriter
- Request() *http.Request
- LookupPath() string
- Subpath() string
- IsNamespaceProject() bool
- IsHTTPSOnly() bool
- HasAccessControl() bool
- ProjectID() uint64
+type Handler struct {
+ Writer http.ResponseWriter
+ Request *http.Request
+
+ LookupPath *LookupPath
+
+ // parsed representation of Request.URI
+ // that is part of LookupPath.Prefix
+ SubPath string
}
diff --git a/internal/domain/project.go b/internal/serving/lookup_path.go
index 9ea7306f..77ac45e8 100644
--- a/internal/domain/project.go
+++ b/internal/serving/lookup_path.go
@@ -1,8 +1,9 @@
-package domain
+package serving
// Project holds a domain / project configuration
-type Project struct {
- LookupPath string
+type LookupPath struct {
+ Location string
+ Path string
IsNamespaceProject bool
IsHTTPSOnly bool
HasAccessControl bool
diff --git a/internal/serving/serving.go b/internal/serving/serving.go
index c6a39241..6fde8216 100644
--- a/internal/serving/serving.go
+++ b/internal/serving/serving.go
@@ -1,23 +1,7 @@
package serving
-import (
- "gitlab.com/gitlab-org/gitlab-pages/internal/serving/disk"
-)
-
// Serving is an interface used to define a serving driver
type Serving interface {
ServeFileHTTP(Handler) bool
ServeNotFoundHTTP(Handler)
- HasAcmeChallenge(handler Handler, token string) bool
-}
-
-// NewDiskServing returns a serving instance that is capable of reading files
-// from the disk
-func NewDiskServing(domain, location string) Serving {
- return &diskServing{
- disk: &disk.Serving{
- Domain: domain,
- Reader: &disk.Reader{Location: location},
- },
- }
}
diff --git a/internal/source/disk/custom.go b/internal/source/disk/custom.go
index 0cf443b0..a7c89700 100644
--- a/internal/source/disk/custom.go
+++ b/internal/source/disk/custom.go
@@ -3,17 +3,20 @@ package disk
import (
"net/http"
- "gitlab.com/gitlab-org/gitlab-pages/internal/domain"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
)
type customProjectResolver struct {
config *domainConfig
+
+ path string
}
// TODO tests
-func (p *customProjectResolver) Resolve(r *http.Request) (*domain.Project, string, error) {
- project := &domain.Project{
- LookupPath: "/",
+func (p *customProjectResolver) Resolve(r *http.Request) (*serving.LookupPath, string, error) {
+ project := &serving.LookupPath{
+ Location: "/",
+ Path: p.path,
IsNamespaceProject: false,
IsHTTPSOnly: p.config.HTTPSOnly,
HasAccessControl: p.config.AccessControl,
diff --git a/internal/source/disk/domain_test.go b/internal/source/disk/domain_test.go
index 4140241e..ba4fb161 100644
--- a/internal/source/disk/domain_test.go
+++ b/internal/source/disk/domain_test.go
@@ -27,7 +27,6 @@ func serveFileOrNotFound(domain *domain.Domain) http.HandlerFunc {
func testGroupServeHTTPHost(t *testing.T, host string) {
testGroup := &domain.Domain{
- Location: "group",
Resolver: &Group{
name: "group",
projects: map[string]*projectConfig{
@@ -81,9 +80,9 @@ func TestDomainServeHTTP(t *testing.T) {
defer cleanup()
testDomain := &domain.Domain{
- Name: "test.domain.com",
- Location: "group/project2",
+ Name: "test.domain.com",
Resolver: &customProjectResolver{
+ path: "group/project2/public",
config: &domainConfig{},
},
}
@@ -109,7 +108,6 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Default group domain with HTTPS-only enabled",
domain: &domain.Domain{
- Location: "group/project",
Resolver: &Group{
name: "group",
projects: projects{"test-domain": &projectConfig{HTTPSOnly: true}},
@@ -121,7 +119,6 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Default group domain with HTTPS-only disabled",
domain: &domain.Domain{
- Location: "group/project",
Resolver: &Group{
name: "group",
projects: projects{"test-domain": &projectConfig{HTTPSOnly: false}},
@@ -133,7 +130,6 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Case-insensitive default group domain with HTTPS-only enabled",
domain: &domain.Domain{
- Location: "group/project",
Resolver: &Group{
name: "group",
projects: projects{"test-domain": &projectConfig{HTTPSOnly: true}},
@@ -145,7 +141,6 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Other group domain with HTTPS-only enabled",
domain: &domain.Domain{
- Location: "group/project",
Resolver: &Group{
name: "group",
projects: projects{"project": &projectConfig{HTTPSOnly: true}},
@@ -157,7 +152,6 @@ func TestIsHTTPSOnly(t *testing.T) {
{
name: "Other group domain with HTTPS-only disabled",
domain: &domain.Domain{
- Location: "group/project",
Resolver: &Group{
name: "group",
projects: projects{"project": &projectConfig{HTTPSOnly: false}},
@@ -167,10 +161,8 @@ func TestIsHTTPSOnly(t *testing.T) {
expected: false,
},
{
- name: "Unknown project",
- domain: &domain.Domain{
- Location: "group/project",
- },
+ name: "Unknown project",
+ domain: &domain.Domain{},
url: "http://test-domain/project",
expected: false,
},
@@ -216,7 +208,6 @@ func TestGroupServeHTTPGzip(t *testing.T) {
defer cleanup()
testGroup := &domain.Domain{
- Location: "group",
Resolver: &Group{
name: "group",
projects: map[string]*projectConfig{
@@ -283,7 +274,6 @@ func TestGroup404ServeHTTP(t *testing.T) {
defer cleanup()
testGroup := &domain.Domain{
- Location: "group.404",
Resolver: &Group{
name: "group.404",
projects: map[string]*projectConfig{
@@ -312,8 +302,8 @@ func TestDomain404ServeHTTP(t *testing.T) {
defer cleanup()
testDomain := &domain.Domain{
- Location: "group.404/domain.404",
Resolver: &customProjectResolver{
+ path: "group.404/domain.404/public",
config: &domainConfig{Domain: "domain.404.com"},
},
}
@@ -326,17 +316,13 @@ func TestPredefined404ServeHTTP(t *testing.T) {
cleanup := setUpTests(t)
defer cleanup()
- testDomain := &domain.Domain{
- Location: "group",
- }
+ testDomain := &domain.Domain{}
testhelpers.AssertHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.test.io/not-existing-file", nil, "The page you're looking for could not be found")
}
func TestGroupCertificate(t *testing.T) {
- testGroup := &domain.Domain{
- Location: "group",
- }
+ testGroup := &domain.Domain{}
tls, err := testGroup.EnsureCertificate()
require.Nil(t, tls)
@@ -345,8 +331,8 @@ func TestGroupCertificate(t *testing.T) {
func TestDomainNoCertificate(t *testing.T) {
testDomain := &domain.Domain{
- Location: "group/project2",
Resolver: &customProjectResolver{
+ path: "group/project2/public",
config: &domainConfig{Domain: "test.domain.com"},
},
}
@@ -362,11 +348,12 @@ func TestDomainNoCertificate(t *testing.T) {
func TestDomainCertificate(t *testing.T) {
testDomain := &domain.Domain{
- Location: "group/project2",
Name: "test.domain.com",
CertificateCert: fixture.Certificate,
CertificateKey: fixture.Key,
- Resolver: &customProjectResolver{},
+ Resolver: &customProjectResolver{
+ path: "group/project2/public",
+ },
}
tls, err := testDomain.EnsureCertificate()
@@ -379,7 +366,6 @@ func TestCacheControlHeaders(t *testing.T) {
defer cleanup()
testGroup := &domain.Domain{
- Location: "group",
Resolver: &Group{
name: "group",
projects: map[string]*projectConfig{
diff --git a/internal/source/disk/group.go b/internal/source/disk/group.go
index efa3fce5..df093926 100644
--- a/internal/source/disk/group.go
+++ b/internal/source/disk/group.go
@@ -3,10 +3,11 @@ package disk
import (
"net/http"
"path"
+ "path/filepath"
"strings"
- "gitlab.com/gitlab-org/gitlab-pages/internal/domain"
"gitlab.com/gitlab-org/gitlab-pages/internal/host"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
)
const (
@@ -52,14 +53,14 @@ func (g *Group) digProjectWithSubpath(parentPath string, keys []string) (*projec
// Look up a project inside the domain based on the host and path. Returns the
// project and its name (if applicable)
-func (g *Group) getProjectConfigWithSubpath(r *http.Request) (*projectConfig, string, string) {
+func (g *Group) getProjectConfigWithSubpath(r *http.Request) (*projectConfig, string, string, string) {
// Check for a project specified in the URL: http://group.gitlab.io/projectA
// If present, these projects shadow the group domain.
split := strings.SplitN(r.URL.Path, "/", maxProjectDepth)
if len(split) >= 2 {
projectConfig, projectPath, urlPath := g.digProjectWithSubpath("", split[1:])
if projectConfig != nil {
- return projectConfig, projectPath, urlPath
+ return projectConfig, "/" + projectPath, projectPath, urlPath
}
}
@@ -67,24 +68,26 @@ func (g *Group) getProjectConfigWithSubpath(r *http.Request) (*projectConfig, st
// return the group project if it exists.
if host := host.FromRequest(r); host != "" {
if groupProject := g.projects[host]; groupProject != nil {
- return groupProject, host, strings.Join(split[1:], "/")
+ // TODOHERE: the location here should be "/", so we return ""
+ return groupProject, "/", host, strings.Join(split[1:], "/")
}
}
- return nil, "", ""
+ return nil, "", "", ""
}
// Resolve tries to find project and its config recursively for a given request
// to a group domain
-func (g *Group) Resolve(r *http.Request) (*domain.Project, string, error) {
- projectConfig, projectPath, subPath := g.getProjectConfigWithSubpath(r)
+func (g *Group) Resolve(r *http.Request) (*serving.LookupPath, string, error) {
+ projectConfig, location, projectPath, subPath := g.getProjectConfigWithSubpath(r)
if projectConfig == nil {
return nil, "", nil // it is not an error when project does not exist
}
- project := &domain.Project{
- LookupPath: projectPath,
+ project := &serving.LookupPath{
+ Location: location,
+ Path: filepath.Join(g.name, projectPath, "public"),
IsNamespaceProject: projectConfig.NamespaceProject,
IsHTTPSOnly: projectConfig.HTTPSOnly,
HasAccessControl: projectConfig.AccessControl,
diff --git a/internal/source/disk/map.go b/internal/source/disk/map.go
index 09902241..3fb7bd4a 100644
--- a/internal/source/disk/map.go
+++ b/internal/source/disk/map.go
@@ -22,13 +22,14 @@ type Map map[string]*domain.Domain
type domainsUpdater func(Map)
func (dm Map) updateDomainMap(domainName string, domain *domain.Domain) {
- if old, ok := dm[domainName]; ok {
- log.WithFields(log.Fields{
- "domain_name": domainName,
- "new_location": domain.Location,
- "old_location": old.Location,
- }).Error("Duplicate domain")
- }
+ // TODOHERE:
+ // if old, ok := dm[domainName]; ok {
+ // log.WithFields(log.Fields{
+ // "domain_name": domainName,
+ // "new_location": domain.Location,
+ // "old_location": old.Location,
+ // }).Error("Duplicate domain")
+ // }
dm[domainName] = domain
}
@@ -38,8 +39,10 @@ func (dm Map) addDomain(rootDomain, groupName, projectName string, config *domai
Name: strings.ToLower(config.Domain),
CertificateCert: config.Certificate,
CertificateKey: config.Key,
- Location: filepath.Join(groupName, projectName),
- Resolver: &customProjectResolver{config: config},
+ Resolver: &customProjectResolver{
+ config: config,
+ path: filepath.Join(groupName, projectName, "public"),
+ },
}
dm.updateDomainMap(newDomain.Name, newDomain)
@@ -58,7 +61,6 @@ func (dm Map) updateGroupDomain(rootDomain, groupName, projectPath string, https
groupDomain = &domain.Domain{
Name: domainName,
- Location: groupName,
Resolver: groupResolver,
}
}