-
Notifications
You must be signed in to change notification settings - Fork 12
/
main.go
102 lines (84 loc) · 2.25 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
package main
import (
"flag"
"fmt"
"net/http"
"os"
"strings"
"time"
"github.com/allegro/bigcache"
"github.com/cloudfoundry-community/go-cfenv"
log "github.com/sirupsen/logrus"
"gopkg.in/robfig/cron.v2"
)
var (
defaultPort = 8080
)
func init() {
// TODO add runtime.Caller(1) info to it.
log.SetFormatter(&log.JSONFormatter{})
log.SetOutput(os.Stdout)
flag.IntVar(&defaultPort, "port", 8080, "Port to run the server on.")
}
func main() {
flag.Parse()
var port string
// this logic just feels weird to me. idk.
appEnv, err := cfenv.Current()
if err != nil {
log.Error(err)
port = fmt.Sprintf(":%d", defaultPort)
} else {
port = fmt.Sprintf(":%d", appEnv.Port)
}
// overkill, but it's a sane library.
// we're going to cache the AV definition files.
cache, err := bigcache.NewBigCache(bigcache.Config{
MaxEntrySize: 500,
Shards: 1024,
LifeWindow: time.Hour * 3,
MaxEntriesInWindow: 1000 * 10 * 60,
Verbose: true,
HardMaxCacheSize: 0,
})
if err != nil {
log.Errorf("cannot initialise cache. %s", err)
}
// let the initial seed run in the background so the web server can start.
log.Info("starting initial seed in the background.")
dl := NewDownloader(true)
dl.DownloadDatabase(cache)
// start a new crontab asynchronously.
c := cron.New()
if _, err = c.AddFunc("@hourly", func() { NewDownloader(true).DownloadDatabase(cache) }); err != nil {
log.Error(err)
}
c.Start()
log.Info("started cron job for definition updates.")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
cacheHandler(w, r, cache)
})
log.Fatal(http.ListenAndServe(port, nil))
}
// cacheHandler is just a standard handler, but returns stuff from cache.
func cacheHandler(w http.ResponseWriter, r *http.Request, c *bigcache.BigCache) {
filename := r.URL.Path[1:]
// logs from the gorouter.
if strings.Contains(filename, "cloudfoundry") {
log.Warn("nothing to see here, move along.")
http.NotFound(w, r)
}
entry, err := c.Get(filename)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"filename": filename,
}).Error("cannot return cached file!")
log.Error(err)
http.NotFound(w, r)
}
log.WithFields(log.Fields{
"filename": filename,
}).Info("found!")
w.Write(entry)
}