-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
110 lines (102 loc) · 2.84 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Binary main runs a web server for my (Spencer Greene's) personal website.
//
// It runs on the Fly app platform (fly.io) in 2 regions, San Jose and Atlanta.
// DNS is on Cloudflare, which also proxies requests through its CDN. There are
// A and AAAA records that point to the app on Fly. When a request is made for
// spencergreene.com, DNS resolution talks to the Cloudflare nameservers, which
// return IP addresses that route to its own CDN. If there's no cache hit, it
// sends the request to Fly. Fly terminates the TLS connection from Cloudflare
// and forwards the request to this web server.
package main
import (
"embed"
"errors"
"flag"
"fmt"
"io/fs"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"github.com/golang/glog"
"github.com/spwg/personal-website/internal/handlers"
"github.com/unrolled/secure"
)
var (
//go:embed cloudflare_ipv4.txt
cloudflareIPv4Addresses string
//go:embed cloudflare_ipv6.txt
cloudflareIPv6Addresses string
//go:embed static/*
embeddedStatic embed.FS
bindAddr = flag.String("bind_addr", defaultBindAddr(), "Full address to bind to.")
)
func defaultBindAddr() string {
if os.Getenv("BIND_ADDR") != "" {
return os.Getenv("BIND_ADDR")
}
return "localhost:8080"
}
// installMiddleware sets up logging and recovery first so that the logging
// happens first and then recovery happens before any other middleware.
func installMiddleware(r *gin.Engine) error {
r.Use(gin.Logger())
r.Use(gin.Recovery())
secureMiddleware := secure.New(secure.Options{
AllowedHosts: []string{
"spencergreene.com",
"www.spencergreene.com",
"spencergreene.fly.dev",
},
FrameDeny: true,
IsDevelopment: gin.IsDebugging(),
HostsProxyHeaders: []string{"X-Forwarded-Host"},
})
r.Use(func(c *gin.Context) {
err := secureMiddleware.Process(c.Writer, c.Request)
if err != nil {
c.Abort()
return
}
if status := c.Writer.Status(); status > 300 && status < 399 {
c.Abort()
}
})
var proxies []string
proxies = append(proxies, strings.Fields(cloudflareIPv4Addresses)...)
proxies = append(proxies, strings.Fields(cloudflareIPv6Addresses)...)
if err := r.SetTrustedProxies(proxies); err != nil {
return fmt.Errorf("install middleware: %v", err)
}
return nil
}
func run() error {
defer glog.Flush()
engine := gin.New()
installMiddleware(engine)
staticFS, err := fs.Sub(embeddedStatic, "static")
if err != nil {
return err
}
if err := handlers.InstallRoutes(staticFS, engine); err != nil {
return err
}
srv := &http.Server{
Addr: *bindAddr,
Handler: engine,
}
glog.Infof("Listening on %q\n", *bindAddr)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
return err
}
return nil
}
func main() {
flag.Parse()
if err := flag.Set("alsologtostderr", "true"); err != nil {
glog.Fatal(err)
}
if err := run(); err != nil {
glog.Fatal(err)
}
}