diff options
author | Vladimir Shushlin <vshushlin@gitlab.com> | 2019-06-03 14:22:03 +0300 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2019-06-03 14:22:03 +0300 |
commit | 9df35356572e09dc2c0907113bf64479204e46a9 (patch) | |
tree | 70297534cace3ad4c6015df32757690cc9244992 /internal/acme/acme.go | |
parent | 80fa0bb4e200a6b3b9194766dd209de28d1cf08a (diff) |
Redirect unknown ACME challenges to the GitLab instance
Diffstat (limited to 'internal/acme/acme.go')
-rw-r--r-- | internal/acme/acme.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/acme/acme.go b/internal/acme/acme.go new file mode 100644 index 00000000..89881f34 --- /dev/null +++ b/internal/acme/acme.go @@ -0,0 +1,62 @@ +package acme + +import ( + "net/http" + "net/url" + "path/filepath" + "strings" + + log "github.com/sirupsen/logrus" + + "gitlab.com/gitlab-org/gitlab-pages/internal/host" +) + +// Middleware handles acme challenges by redirecting them to GitLab instance +type Middleware struct { + GitlabURL string +} + +// Domain interface represent D from domain package +type Domain interface { + HasAcmeChallenge(string) bool +} + +// ServeAcmeChallenges identifies if request is acme-challenge and redirects to GitLab in that case +func (m *Middleware) ServeAcmeChallenges(w http.ResponseWriter, r *http.Request, domain Domain) bool { + if m == nil { + return false + } + + if !isAcmeChallenge(r.URL.Path) { + return false + } + + if domain.HasAcmeChallenge(filepath.Base(r.URL.Path)) { + return false + } + + return m.redirectToGitlab(w, r) +} + +func isAcmeChallenge(path string) bool { + return strings.HasPrefix(filepath.Clean(path), "/.well-known/acme-challenge/") +} + +func (m *Middleware) redirectToGitlab(w http.ResponseWriter, r *http.Request) bool { + redirectURL, err := url.Parse(m.GitlabURL) + if err != nil { + log.WithError(err).Error("Can't parse GitLab URL for acme challenge redirect") + return false + } + + redirectURL.Path = "/-/acme-challenge" + query := redirectURL.Query() + query.Set("domain", host.FromRequest(r)) + query.Set("token", filepath.Base(r.URL.Path)) + redirectURL.RawQuery = query.Encode() + + log.WithField("redirect_url", redirectURL).Debug("Redirecting to GitLab for processing acme challenge") + + http.Redirect(w, r, redirectURL.String(), http.StatusTemporaryRedirect) + return true +} |