-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeofeed.go
96 lines (77 loc) · 2.34 KB
/
geofeed.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
package main
import (
"fmt"
"log"
"net/http"
"net/netip"
"time"
)
// Generates the geofeed and stores it into memory
func generateGeofeed() {
var feed Geofeed
log.Print("Generating geofeed...")
for _, supernet := range cfg.Networks {
tmp, err := netip.ParsePrefix(supernet)
if err != nil {
log.Println(err)
continue
}
// Get the supernet data
allocationData, err := getSupernetData(tmp)
if err != nil {
log.Println(err)
continue
}
// Get all subnets contained within the supernet
subnetData, err := getSubnetData(tmp)
if err != nil {
log.Println(err)
continue
}
for _, i := range subnetData {
// If the subnet country is different from the supernet country then add it to the list
if i.Country != allocationData.Country {
allocationData.Subnets = append(allocationData.Subnets, i)
}
}
feed.Allocations = append(feed.Allocations, allocationData)
}
feed.Generated = time.Now().UTC()
geofeed = feed
log.Println("Geofeed generation done")
}
func handleGeofeed(w http.ResponseWriter, r *http.Request) {
if len(geofeed.Allocations) == 0 {
// If the geofeed is still being generated we return a 503 Service Unavailable
w.Header().Set("Retry-After", "300") // Tell the client to retry after 5 minutes
w.WriteHeader(http.StatusServiceUnavailable)
return
}
w.Header().Set("Last-Modified", geofeed.Generated.Format(time.RFC1123))
fmt.Fprintf(w, "# Generated %s\n", geofeed.Generated.Format(time.RFC3339Nano))
// Loop through the geofeed struct and print out the entries
for _, allocation := range geofeed.Allocations {
fmt.Fprintf(w, "%s,%s,,,\n", allocation.Prefix, allocation.Country)
for _, subnet := range allocation.Subnets {
fmt.Fprintf(w, "%s,%s,,,\n", subnet.Prefix, subnet.Country)
}
}
fmt.Fprintf(w, "# EOF\n")
}
// Regenerates the geofeed if we want to force an update
func handleRegenerateGeofeed(w http.ResponseWriter, r *http.Request) {
if cfg.Key == "" {
w.WriteHeader(http.StatusForbidden)
return
}
if r.Header.Get("X-Geofeed-Key") != cfg.Key {
w.WriteHeader(http.StatusForbidden)
return
}
generateGeofeed()
w.WriteHeader(http.StatusOK)
}
// Any requests not matching the above handlers will be redirected to the geofeed instead of a 404
func handleUnknown(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/geofeed.csv", http.StatusMovedPermanently)
}