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:
authorVladimir Shushlin <vshushlin@gitlab.com>2019-06-03 14:22:03 +0300
committerNick Thomas <nick@gitlab.com>2019-06-03 14:22:03 +0300
commit9df35356572e09dc2c0907113bf64479204e46a9 (patch)
tree70297534cace3ad4c6015df32757690cc9244992 /internal/domain
parent80fa0bb4e200a6b3b9194766dd209de28d1cf08a (diff)
Redirect unknown ACME challenges to the GitLab instance
Diffstat (limited to 'internal/domain')
-rw-r--r--internal/domain/domain.go34
-rw-r--r--internal/domain/domain_test.go97
-rw-r--r--internal/domain/map_test.go2
3 files changed, 91 insertions, 42 deletions
diff --git a/internal/domain/domain.go b/internal/domain/domain.go
index 1455d436..4ce8a561 100644
--- a/internal/domain/domain.go
+++ b/internal/domain/domain.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"mime"
- "net"
"net/http"
"os"
"path/filepath"
@@ -17,6 +16,7 @@ import (
"golang.org/x/sys/unix"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/host"
"gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
"gitlab.com/gitlab-org/gitlab-pages/internal/httputil"
)
@@ -106,16 +106,6 @@ func handleGZip(w http.ResponseWriter, r *http.Request, fullPath string) string
return gzipPath
}
-func getHost(r *http.Request) string {
- host := strings.ToLower(r.Host)
-
- if splitHost, _, err := net.SplitHostPort(host); err == nil {
- host = splitHost
- }
-
- return host
-}
-
// Look up a project inside the domain based on the host and path. Returns the
// project and its name (if applicable)
func (d *D) getProjectWithSubpath(r *http.Request) (*project, string, string) {
@@ -131,7 +121,7 @@ func (d *D) getProjectWithSubpath(r *http.Request) (*project, string, string) {
// Since the URL doesn't specify a project (e.g. http://mydomain.gitlab.io),
// return the group project if it exists.
- if host := getHost(r); host != "" {
+ if host := host.FromRequest(r); host != "" {
if groupProject := d.projects[host]; groupProject != nil {
return groupProject, host, strings.Join(split[1:], "/")
}
@@ -179,6 +169,26 @@ func (d *D) IsAccessControlEnabled(r *http.Request) bool {
return false
}
+// HasAcmeChallenge checks domain directory contains particular acme challenge
+func (d *D) HasAcmeChallenge(token string) bool {
+ if d == nil {
+ return false
+ }
+
+ if d.config == nil {
+ return false
+ }
+
+ _, err := d.resolvePath(d.projectName, ".well-known/acme-challenge", token)
+
+ // there is an acme challenge on disk
+ if err == nil {
+ return true
+ }
+
+ return false
+}
+
// IsNamespaceProject figures out if the request is to a namespace project
func (d *D) IsNamespaceProject(r *http.Request) bool {
if d == nil {
diff --git a/internal/domain/domain_test.go b/internal/domain/domain_test.go
index add9b616..a05dbe7e 100644
--- a/internal/domain/domain_test.go
+++ b/internal/domain/domain_test.go
@@ -3,7 +3,6 @@ package domain
import (
"compress/gzip"
"io/ioutil"
- "mime"
"net/http"
"net/http/httptest"
"net/url"
@@ -15,6 +14,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-pages/internal/fixture"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/testhelpers"
)
func serveFileOrNotFound(domain *D) http.HandlerFunc {
@@ -25,11 +25,6 @@ func serveFileOrNotFound(domain *D) http.HandlerFunc {
}
}
-func assertRedirectTo(t *testing.T, h http.HandlerFunc, method string, url string, values url.Values, expectedURL string) {
- assert.HTTPRedirect(t, h, method, url, values)
- assert.HTTPBodyContains(t, h, method, url, values, `<a href="//`+expectedURL+`">Found</a>`)
-}
-
func testGroupServeHTTPHost(t *testing.T, host string) {
testGroup := &D{
projectName: "",
@@ -53,12 +48,12 @@ func testGroupServeHTTPHost(t *testing.T, host string) {
assert.HTTPBodyContains(t, serve, "GET", makeURL("/"), nil, "main-dir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/index"), nil, "main-dir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/index.html"), nil, "main-dir")
- assertRedirectTo(t, serve, "GET", makeURL("/project"), nil, host+"/project/")
+ testhelpers.AssertRedirectTo(t, serve, "GET", makeURL("/project"), nil, "//"+host+"/project/")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project/"), nil, "project-subdir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project/index"), nil, "project-subdir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project/index/"), nil, "project-subdir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project/index.html"), nil, "project-subdir")
- assertRedirectTo(t, serve, "GET", makeURL("/project/subdir"), nil, host+"/project/subdir/")
+ testhelpers.AssertRedirectTo(t, serve, "GET", makeURL("/project/subdir"), nil, "//"+host+"/project/subdir/")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project/subdir/"), nil, "project-subsubdir")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project2/"), nil, "project2-main")
assert.HTTPBodyContains(t, serve, "GET", makeURL("/project2/index"), nil, "project2-main")
@@ -205,7 +200,61 @@ func TestIsHTTPSOnly(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req, _ := http.NewRequest(http.MethodGet, test.url, nil)
- assert.Equal(t, test.domain.IsHTTPSOnly(req), test.expected)
+ assert.Equal(t, test.expected, test.domain.IsHTTPSOnly(req))
+ })
+ }
+}
+
+func TestHasAcmeChallenge(t *testing.T) {
+ cleanup := setUpTests(t)
+ defer cleanup()
+
+ tests := []struct {
+ name string
+ domain *D
+ token string
+ expected bool
+ }{
+ {
+ name: "Project containing acme challenge",
+ domain: &D{
+ group: group{name: "group.acme"},
+ projectName: "with.acme.challenge",
+ config: &domainConfig{HTTPSOnly: true},
+ },
+ token: "existingtoken",
+ expected: true,
+ },
+ {
+ name: "Project containing another token",
+ domain: &D{
+ group: group{name: "group.acme"},
+ projectName: "with.acme.challenge",
+ config: &domainConfig{HTTPSOnly: true},
+ },
+ token: "notexistingtoken",
+ expected: false,
+ },
+ {
+ name: "nil domain",
+ domain: nil,
+ token: "existingtoken",
+ expected: false,
+ },
+ {
+ name: "Domain without config",
+ domain: &D{
+ group: group{name: "group.acme"},
+ projectName: "with.acme.challenge",
+ config: nil,
+ },
+ token: "existingtoken",
+ expected: false,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ assert.Equal(t, test.expected, test.domain.HasAcmeChallenge(test.token))
})
}
}
@@ -304,18 +353,6 @@ func TestGroupServeHTTPGzip(t *testing.T) {
}
}
-func testHTTP404(t *testing.T, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) {
- w := httptest.NewRecorder()
- req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
- require.NoError(t, err)
- handler(w, req)
-
- contentType, _, _ := mime.ParseMediaType(w.Header().Get("Content-Type"))
- assert.Equal(t, http.StatusNotFound, w.Code, "HTTP status")
- assert.Equal(t, "text/html", contentType, "Content-Type")
- assert.Contains(t, w.Body.String(), str)
-}
-
func TestGroup404ServeHTTP(t *testing.T) {
cleanup := setUpTests(t)
defer cleanup()
@@ -334,15 +371,15 @@ func TestGroup404ServeHTTP(t *testing.T) {
},
}
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.404/not/existing-file", nil, "Custom 404 project page")
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.404/", nil, "Custom 404 project page")
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/not/existing-file", nil, "Custom 404 group page")
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/not-existing-file", nil, "Custom 404 group page")
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/", nil, "Custom 404 group page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.404/not/existing-file", nil, "Custom 404 project page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.404/", nil, "Custom 404 project page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/not/existing-file", nil, "Custom 404 group page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/not-existing-file", nil, "Custom 404 group page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/", nil, "Custom 404 group page")
assert.HTTPBodyNotContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.404.symlink/not/existing-file", nil, "Custom 404 project page")
// Ensure the namespace project's custom 404.html is not used by projects
- testHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.no.404/not/existing-file", nil, "The page you're looking for could not be found.")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testGroup), "GET", "http://group.404.test.io/project.no.404/not/existing-file", nil, "The page you're looking for could not be found.")
}
func TestDomain404ServeHTTP(t *testing.T) {
@@ -357,8 +394,8 @@ func TestDomain404ServeHTTP(t *testing.T) {
},
}
- testHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.404.test.io/not-existing-file", nil, "Custom 404 group page")
- testHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.404.test.io/", nil, "Custom 404 group page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.404.test.io/not-existing-file", nil, "Custom 404 group page")
+ testhelpers.AssertHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.404.test.io/", nil, "Custom 404 group page")
}
func TestPredefined404ServeHTTP(t *testing.T) {
@@ -369,7 +406,7 @@ func TestPredefined404ServeHTTP(t *testing.T) {
group: group{name: "group"},
}
- testHTTP404(t, serveFileOrNotFound(testDomain), "GET", "http://group.test.io/not-existing-file", nil, "The page you're looking for could not be found")
+ 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) {
diff --git a/internal/domain/map_test.go b/internal/domain/map_test.go
index dc5e8648..156b039f 100644
--- a/internal/domain/map_test.go
+++ b/internal/domain/map_test.go
@@ -55,6 +55,8 @@ func TestReadProjects(t *testing.T) {
"no.cert.com",
"private.domain.com",
"group.auth.test.io",
+ "group.acme.test.io",
+ "withacmechallenge.domain.com",
"capitalgroup.test.io",
}