mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2024-11-18 10:29:43 +00:00
move helper func in related packages
This commit is contained in:
parent
5b81a8b8bc
commit
690879440a
6 changed files with 66 additions and 54 deletions
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"codeberg.org/codeberg/pages/server"
|
"codeberg.org/codeberg/pages/server"
|
||||||
|
"codeberg.org/codeberg/pages/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AllowedCorsDomains lists the domains for which Cross-Origin Resource Sharing is allowed.
|
// AllowedCorsDomains lists the domains for which Cross-Origin Resource Sharing is allowed.
|
||||||
|
@ -91,7 +92,7 @@ func Serve(ctx *cli.Context) error {
|
||||||
challengePath := []byte("/.well-known/acme-challenge/")
|
challengePath := []byte("/.well-known/acme-challenge/")
|
||||||
err := fasthttp.ListenAndServe("[::]:80", func(ctx *fasthttp.RequestCtx) {
|
err := fasthttp.ListenAndServe("[::]:80", func(ctx *fasthttp.RequestCtx) {
|
||||||
if bytes.HasPrefix(ctx.Path(), challengePath) {
|
if bytes.HasPrefix(ctx.Path(), challengePath) {
|
||||||
challenge, ok := server.ChallengeCache.Get(string(server.TrimHostPort(ctx.Host())) + "/" + string(bytes.TrimPrefix(ctx.Path(), challengePath)))
|
challenge, ok := server.ChallengeCache.Get(string(utils.TrimHostPort(ctx.Host())) + "/" + string(bytes.TrimPrefix(ctx.Path(), challengePath)))
|
||||||
if !ok || challenge == nil {
|
if !ok || challenge == nil {
|
||||||
ctx.SetStatusCode(http.StatusNotFound)
|
ctx.SetStatusCode(http.StatusNotFound)
|
||||||
ctx.SetBodyString("no challenge for this token")
|
ctx.SetBodyString("no challenge for this token")
|
||||||
|
|
|
@ -14,12 +14,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/OrlovEvgeny/go-mcache"
|
|
||||||
"github.com/akrylysov/pogreb/fs"
|
|
||||||
"github.com/go-acme/lego/v4/certificate"
|
|
||||||
"github.com/go-acme/lego/v4/challenge"
|
|
||||||
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
|
||||||
"github.com/go-acme/lego/v4/providers/dns"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -29,12 +23,20 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OrlovEvgeny/go-mcache"
|
||||||
"github.com/akrylysov/pogreb"
|
"github.com/akrylysov/pogreb"
|
||||||
|
"github.com/akrylysov/pogreb/fs"
|
||||||
"github.com/reugn/equalizer"
|
"github.com/reugn/equalizer"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
|
"github.com/go-acme/lego/v4/certificate"
|
||||||
|
"github.com/go-acme/lego/v4/challenge"
|
||||||
|
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
||||||
"github.com/go-acme/lego/v4/lego"
|
"github.com/go-acme/lego/v4/lego"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns"
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
|
|
||||||
|
"codeberg.org/codeberg/pages/server/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TlsConfig returns the configuration for generating, serving and cleaning up Let's Encrypt certificates.
|
// TlsConfig returns the configuration for generating, serving and cleaning up Let's Encrypt certificates.
|
||||||
|
@ -212,7 +214,7 @@ func (a AcmeHTTPChallengeProvider) CleanUp(domain, token, _ string) error {
|
||||||
func retrieveCertFromDB(sni, mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool) (tls.Certificate, bool) {
|
func retrieveCertFromDB(sni, mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool) (tls.Certificate, bool) {
|
||||||
// parse certificate from database
|
// parse certificate from database
|
||||||
res := &certificate.Resource{}
|
res := &certificate.Resource{}
|
||||||
if !PogrebGet(KeyDatabase, sni, res) {
|
if !database.PogrebGet(KeyDatabase, sni, res) {
|
||||||
return tls.Certificate{}, false
|
return tls.Certificate{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +319,7 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
|
||||||
if err == nil && tlsCertificate.Leaf.NotAfter.After(time.Now()) {
|
if err == nil && tlsCertificate.Leaf.NotAfter.After(time.Now()) {
|
||||||
// avoid sending a mock cert instead of a still valid cert, instead abuse CSR field to store time to try again at
|
// avoid sending a mock cert instead of a still valid cert, instead abuse CSR field to store time to try again at
|
||||||
renew.CSR = []byte(strconv.FormatInt(time.Now().Add(6*time.Hour).Unix(), 10))
|
renew.CSR = []byte(strconv.FormatInt(time.Now().Add(6*time.Hour).Unix(), 10))
|
||||||
PogrebPut(KeyDatabase, []byte(name), renew)
|
database.PogrebPut(KeyDatabase, []byte(name), renew)
|
||||||
return tlsCertificate, nil
|
return tlsCertificate, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,7 +327,7 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
|
||||||
}
|
}
|
||||||
log.Printf("Obtained certificate for %v", domains)
|
log.Printf("Obtained certificate for %v", domains)
|
||||||
|
|
||||||
PogrebPut(KeyDatabase, []byte(name), res)
|
database.PogrebPut(KeyDatabase, []byte(name), res)
|
||||||
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tls.Certificate{}, err
|
return tls.Certificate{}, err
|
||||||
|
@ -390,7 +392,7 @@ func mockCert(domain, msg, mainDomainSuffix string) tls.Certificate {
|
||||||
if domain == "*"+mainDomainSuffix || domain == mainDomainSuffix[1:] {
|
if domain == "*"+mainDomainSuffix || domain == mainDomainSuffix[1:] {
|
||||||
databaseName = mainDomainSuffix
|
databaseName = mainDomainSuffix
|
||||||
}
|
}
|
||||||
PogrebPut(KeyDatabase, []byte(databaseName), res)
|
database.PogrebPut(KeyDatabase, []byte(databaseName), res)
|
||||||
|
|
||||||
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -578,7 +580,7 @@ func SetupCertificates(mainDomainSuffix []byte, acmeAPI, acmeMail, acmeEabHmac,
|
||||||
|
|
||||||
// update main cert
|
// update main cert
|
||||||
res := &certificate.Resource{}
|
res := &certificate.Resource{}
|
||||||
if !PogrebGet(KeyDatabase, mainDomainSuffix, res) {
|
if !database.PogrebGet(KeyDatabase, mainDomainSuffix, res) {
|
||||||
log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", "expected main domain cert to exist, but it's missing - seems like the database is corrupted")
|
log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", "expected main domain cert to exist, but it's missing - seems like the database is corrupted")
|
||||||
} else {
|
} else {
|
||||||
tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate)
|
tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate)
|
||||||
|
|
38
server/database/helpers.go
Normal file
38
server/database/helpers.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"github.com/akrylysov/pogreb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PogrebPut(db *pogreb.DB, name []byte, obj interface{}) {
|
||||||
|
var resGob bytes.Buffer
|
||||||
|
resEnc := gob.NewEncoder(&resGob)
|
||||||
|
err := resEnc.Encode(obj)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = db.Put(name, resGob.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PogrebGet(db *pogreb.DB, name []byte, obj interface{}) bool {
|
||||||
|
resBytes, err := db.Get(name)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if resBytes == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
resGob := bytes.NewBuffer(resBytes)
|
||||||
|
resDec := gob.NewDecoder(resGob)
|
||||||
|
err = resDec.Decode(obj)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/valyala/fastjson"
|
"github.com/valyala/fastjson"
|
||||||
|
|
||||||
"codeberg.org/codeberg/pages/html"
|
"codeberg.org/codeberg/pages/html"
|
||||||
|
"codeberg.org/codeberg/pages/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler handles a single HTTP request to the web server.
|
// Handler handles a single HTTP request to the web server.
|
||||||
|
@ -31,7 +32,7 @@ func Handler(mainDomainSuffix, rawDomain []byte, giteaRoot, rawInfoPage, giteaAp
|
||||||
// Enable browser caching for up to 10 minutes
|
// Enable browser caching for up to 10 minutes
|
||||||
ctx.Response.Header.Set("Cache-Control", "public, max-age=600")
|
ctx.Response.Header.Set("Cache-Control", "public, max-age=600")
|
||||||
|
|
||||||
trimmedHost := TrimHostPort(ctx.Request.Host())
|
trimmedHost := utils.TrimHostPort(ctx.Request.Host())
|
||||||
|
|
||||||
// Add HSTS for RawDomain and MainDomainSuffix
|
// Add HSTS for RawDomain and MainDomainSuffix
|
||||||
if hsts := GetHSTSHeader(trimmedHost, mainDomainSuffix, rawDomain); hsts != "" {
|
if hsts := GetHSTSHeader(trimmedHost, mainDomainSuffix, rawDomain); hsts != "" {
|
||||||
|
|
|
@ -2,8 +2,6 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
|
||||||
"github.com/akrylysov/pogreb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetHSTSHeader returns a HSTS header with includeSubdomains & preload for MainDomainSuffix and RawDomain, or an empty
|
// GetHSTSHeader returns a HSTS header with includeSubdomains & preload for MainDomainSuffix and RawDomain, or an empty
|
||||||
|
@ -15,42 +13,3 @@ func GetHSTSHeader(host, mainDomainSuffix, rawDomain []byte) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TrimHostPort(host []byte) []byte {
|
|
||||||
i := bytes.IndexByte(host, ':')
|
|
||||||
if i >= 0 {
|
|
||||||
return host[:i]
|
|
||||||
}
|
|
||||||
return host
|
|
||||||
}
|
|
||||||
|
|
||||||
func PogrebPut(db *pogreb.DB, name []byte, obj interface{}) {
|
|
||||||
var resGob bytes.Buffer
|
|
||||||
resEnc := gob.NewEncoder(&resGob)
|
|
||||||
err := resEnc.Encode(obj)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
err = db.Put(name, resGob.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PogrebGet(db *pogreb.DB, name []byte, obj interface{}) bool {
|
|
||||||
resBytes, err := db.Get(name)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if resBytes == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
resGob := bytes.NewBuffer(resBytes)
|
|
||||||
resDec := gob.NewDecoder(resGob)
|
|
||||||
err = resDec.Decode(obj)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
11
server/utils/utils.go
Normal file
11
server/utils/utils.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
|
func TrimHostPort(host []byte) []byte {
|
||||||
|
i := bytes.IndexByte(host, ':')
|
||||||
|
if i >= 0 {
|
||||||
|
return host[:i]
|
||||||
|
}
|
||||||
|
return host
|
||||||
|
}
|
Loading…
Reference in a new issue