pages-server/server/handler/handler.go

112 lines
3.5 KiB
Go
Raw Normal View History

2022-11-12 18:44:04 +01:00
package handler
2021-12-05 14:45:17 +01:00
import (
2022-07-27 17:25:08 +02:00
"net/http"
2021-12-05 14:45:17 +01:00
"strings"
2021-12-05 15:02:44 +01:00
"github.com/rs/zerolog/log"
2021-12-05 14:45:17 +01:00
"codeberg.org/codeberg/pages/html"
2021-12-05 15:02:44 +01:00
"codeberg.org/codeberg/pages/server/cache"
2022-08-28 15:33:10 +02:00
"codeberg.org/codeberg/pages/server/context"
"codeberg.org/codeberg/pages/server/gitea"
"codeberg.org/codeberg/pages/server/version"
2021-12-05 14:45:17 +01:00
)
2022-08-28 15:33:10 +02:00
const (
headerAccessControlAllowOrigin = "Access-Control-Allow-Origin"
headerAccessControlAllowMethods = "Access-Control-Allow-Methods"
)
2021-12-05 14:45:17 +01:00
// Handler handles a single HTTP request to the web server.
2022-08-28 16:21:37 +02:00
func Handler(mainDomainSuffix, rawDomain string,
giteaClient *gitea.Client,
2022-11-12 02:54:56 +01:00
rawInfoPage string,
2022-08-28 15:33:10 +02:00
blacklistedPaths, allowedCorsDomains []string,
2022-07-27 15:39:46 +02:00
dnsLookupCache, canonicalDomainCache cache.SetGetKey,
2022-07-27 17:25:08 +02:00
) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
2022-08-28 14:35:27 +02:00
log := log.With().Strs("Handler", []string{string(req.Host), req.RequestURI}).Logger()
2022-08-28 15:33:10 +02:00
ctx := context.New(w, req)
2021-12-05 14:45:17 +01:00
2022-08-28 15:33:10 +02:00
ctx.RespWriter.Header().Set("Server", "CodebergPages/"+version.Version)
2021-12-05 14:45:17 +01:00
// Force new default from specification (since November 2020) - see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#strict-origin-when-cross-origin
2022-08-28 15:33:10 +02:00
ctx.RespWriter.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
2021-12-05 14:45:17 +01:00
// Enable browser caching for up to 10 minutes
2022-08-28 15:33:10 +02:00
ctx.RespWriter.Header().Set("Cache-Control", "public, max-age=600")
2021-12-05 14:45:17 +01:00
2022-11-12 19:57:37 +01:00
trimmedHost := ctx.TrimHostPort()
2021-12-05 14:45:17 +01:00
// Add HSTS for RawDomain and MainDomainSuffix
2022-11-07 23:01:31 +01:00
if hsts := getHSTSHeader(trimmedHost, mainDomainSuffix, rawDomain); hsts != "" {
2022-08-28 15:33:10 +02:00
ctx.RespWriter.Header().Set("Strict-Transport-Security", hsts)
2021-12-05 14:45:17 +01:00
}
2022-11-12 13:10:07 +01:00
// Handle all http methods
ctx.RespWriter.Header().Set("Allow", http.MethodGet+", "+http.MethodHead+", "+http.MethodOptions)
switch ctx.Req.Method {
case http.MethodOptions:
// return Allow header
ctx.RespWriter.WriteHeader(http.StatusNoContent)
return
case http.MethodGet,
http.MethodHead:
// end switch case and handle allowed requests
break
default:
// Block all methods not required for static pages
2022-11-07 21:34:23 +01:00
ctx.String("Method not allowed", http.StatusMethodNotAllowed)
2021-12-05 14:45:17 +01:00
return
}
// Block blacklisted paths (like ACME challenges)
for _, blacklistedPath := range blacklistedPaths {
2022-08-28 15:33:10 +02:00
if strings.HasPrefix(ctx.Path(), blacklistedPath) {
html.ReturnErrorPage(ctx, "requested blacklisted path", http.StatusForbidden)
2021-12-05 14:45:17 +01:00
return
}
}
// Allow CORS for specified domains
allowCors := false
for _, allowedCorsDomain := range allowedCorsDomains {
2022-08-28 16:21:37 +02:00
if strings.EqualFold(trimmedHost, allowedCorsDomain) {
allowCors = true
break
2021-12-05 14:45:17 +01:00
}
}
if allowCors {
2022-08-28 15:33:10 +02:00
ctx.RespWriter.Header().Set(headerAccessControlAllowOrigin, "*")
ctx.RespWriter.Header().Set(headerAccessControlAllowMethods, http.MethodGet+", "+http.MethodHead)
}
2022-07-27 17:25:08 +02:00
2021-12-05 14:45:17 +01:00
// Prepare request information to Gitea
2022-11-12 14:08:08 +01:00
pathElements := strings.Split(strings.Trim(ctx.Path(), "/"), "/")
2021-12-05 14:45:17 +01:00
2022-08-28 16:21:37 +02:00
if rawDomain != "" && strings.EqualFold(trimmedHost, rawDomain) {
2022-11-12 19:57:37 +01:00
log.Debug().Msg("raw domain request detecded")
handleRaw(log, ctx, giteaClient,
mainDomainSuffix, rawInfoPage,
trimmedHost,
pathElements,
canonicalDomainCache)
2022-08-28 16:21:37 +02:00
} else if strings.HasSuffix(trimmedHost, mainDomainSuffix) {
2022-11-12 19:57:37 +01:00
log.Debug().Msg("subdomain request detecded")
handleSubDomain(log, ctx, giteaClient,
mainDomainSuffix,
trimmedHost,
pathElements,
canonicalDomainCache)
2021-12-05 14:45:17 +01:00
} else {
2022-11-12 19:57:37 +01:00
log.Debug().Msg("custom domain request detecded")
handleCustomDomain(log, ctx, giteaClient,
mainDomainSuffix,
trimmedHost,
pathElements,
dnsLookupCache, canonicalDomainCache)
2021-12-05 14:45:17 +01:00
}
}
}