-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmain.go
90 lines (74 loc) · 2.28 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
package main
import (
"github.com/oschwald/geoip2-golang"
"github.com/fatih/structs"
aegis "github.com/tmaiaroto/aegis/framework"
"github.com/aws/aws-xray-sdk-go/xray"
"net"
"context"
"net/url"
"log"
"errors"
)
var db *geoip2.Reader
func main() {
// log.SetFlags(log.LstdFlags | log.Lshortfile)
// Load the database in main() in order to benefit from Lambda container re-use.
var err error
var data []byte
ctx, seg := xray.BeginSegment(context.Background(), "GeoipInit")
ctx, subSeg := xray.BeginSubsegment(ctx, "LoadDatabase")
err = xray.Capture(ctx, "LoadBytes", func(ctx1 context.Context) error {
data, err = Asset("GeoLite2-City.mmdb")
return err
})
if err == nil {
xray.Capture(ctx, "DatabaseFromBytes", func(ctx1 context.Context) error {
db, _ = geoip2.FromBytes(data)
return nil
})
defer db.Close()
// Close the segment and subsegment
subSeg.Close(nil)
seg.Close(nil)
// Handle API requests
router := aegis.NewRouter(fallThrough)
router.Handle("GET", "/", root)
// router.Listen()
// Handle RPCs
rpcRouter := aegis.NewRPCRouter()
rpcRouter.Handle("lookup", lookupProcedure)
handlers := aegis.Handlers{
Router: router,
RPCRouter: rpcRouter,
}
handlers.Listen()
} else {
log.Println("Could not load GeoLite2-City.mmdb. Is it included in the binary?", err)
}
}
func fallThrough(ctx context.Context, d *aegis.HandlerDependencies, evt *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
res.StatusCode = 404
return nil
}
func root(ctx context.Context, d *aegis.HandlerDependencies, evt *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
record, err := lookup(evt.RequestContext.Identity.SourceIP)
res.JSON(200, record)
return err
}
func lookupProcedure(ctx context.Context, d *aegis.HandlerDependencies, evt map[string]interface{}) (map[string]interface{}, error) {
var resp map[string]interface{}
if evt != nil {
record, err := lookup(evt["ipAddress"].(string))
if err == nil {
resp = structs.Map(record)
return resp, err
}
return resp, err
}
return resp, errors.New("no IP address passed to procedure")
}
func lookup(ipAddress string) (*geoip2.City, error) {
parsedIP := net.ParseIP(ipAddress)
return db.City(parsedIP)
}