/
nogame.go
105 lines (84 loc) · 2.06 KB
/
nogame.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
package main
import (
"fmt"
"github.com/elazarl/goproxy"
"log"
"net/http"
"regexp"
"time"
)
const AllowedTime time.Duration = time.Minute * 30
const Timeout time.Duration = time.Hour * 18
type BlockClock struct {
// When to start blocking the hosts
LockAt time.Time
// When to unlock the hosts
UnlockAt time.Time
// What hosts are blocked
Hosts []string
// regex to unlock the hosts
HostsPattern *regexp.Regexp
}
func (bl *BlockClock) Set(t time.Time) *BlockClock {
bl.LockAt = t.Add(AllowedTime)
bl.UnlockAt = t.Add(Timeout)
return bl
}
func (bl *BlockClock) startTimer() bool {
if bl.UnlockAt.Before(time.Now()) {
bl.Set(time.Now())
return true
}
return false
}
func (bl *BlockClock) locked() bool {
return bl.LockAt.After(time.Now())
}
func (bl *BlockClock) Block(r *http.Request) *http.Request {
if bl.startTimer() {
log.Printf("will block %s at %s", r.URL.Host, bl.LockAt)
}
if !bl.locked() {
r.URL.Host = "khanacademy.org"
r.URL.Path = "/"
}
return r
}
func (bl *BlockClock) blockedHost(host string) bool {
return bl.HostsPattern.Match([]byte(host))
}
func (bl *BlockClock) checkHost(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
if bl.blockedHost(r.URL.Host) {
time.Sleep(time.Second * 4)
return bl.Block(r), nil
} else {
return r, nil
}
}
// display the configuration
func (bl *BlockClock) conf(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
bl.update()
return r, goproxy.NewResponse(r,
goproxy.ContentTypeText,
http.StatusOK,
fmt.Sprintf("hosts %s\nstart blocking at: %s", bl.Hosts, bl.LockAt))
}
func Create() *BlockClock {
bl := &BlockClock{}
bl.update()
return bl
}
func (bl *BlockClock) update() *BlockClock {
bl.Hosts = Hosts()
bl.HostsPattern = BlockedHosts()
log.Printf("blocking %v\n", bl.Hosts)
return bl
}
func main() {
bl := Create()
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = false
proxy.OnRequest(goproxy.DstHostIs("nogame")).DoFunc(bl.conf)
proxy.OnRequest().DoFunc(bl.checkHost)
log.Fatal(http.ListenAndServe(":8080", proxy))
}