-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandler.go
91 lines (68 loc) · 1.71 KB
/
handler.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
package main
import (
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/diegohce/droneip/dronebl"
"github.com/diegohce/droneip/config"
mx2 "github.com/diegohce/droneip/mxcache"
"github.com/diegohce/droneip/logger"
)
type CacheValue struct {
ValidIP bool
}
type DroneHandler struct {
cache mx2.MXCacher
cacheTTL int
}
func (h *DroneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
remoteIP := strings.SplitN(r.RemoteAddr, ":", 2)[0]
inspectHeader := config.Get("INSPECT_HEADER")
if inspectHeader != "" {
remoteIP = getRemoteIP(r.Header.Get(inspectHeader))
}
cacheKey := fmt.Sprintf("droneip-%s", remoteIP)
var cv CacheValue
err := h.cache.Get(cacheKey, &cv)
if errors.Is(err, mx2.ErrNotFound) {
if err := dronebl.Probe(remoteIP); err != nil {
logger.LogInfo("ip exists in dronebl DB",
"ip", remoteIP, "source", "dronebl.org").Write()
cv.ValidIP = false
h.cache.Set(cacheKey, &cv, h.cacheTTL)
w.WriteHeader(http.StatusTeapot)
return
}
cv.ValidIP = true
h.cache.Set(cacheKey, &cv, h.cacheTTL)
}
if !cv.ValidIP {
logger.LogInfo("ip exists in dronebl DB",
"ip", remoteIP, "source", "cache").Write()
w.WriteHeader(http.StatusTeapot)
return
}
destURL := config.Get("DESTINATION_URL")
req, err := http.NewRequest(r.Method, destURL, r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
req.Header = r.Header
res, err := http.DefaultClient.Do(req)
if err != nil {
w.WriteHeader(http.StatusBadGateway)
return
}
defer res.Body.Close()
io.Copy(w, res.Body)
}
func getRemoteIP(ips string) string {
if !strings.Contains(ips, ",") {
return ips
}
ipList := strings.Split(ips, ",")
return strings.Trim(ipList[0], " ")
}