summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2014-03-27 15:17:37 +0100
committerKevin Chabowski <kevin@kch42.de>2014-03-27 23:51:08 +0100
commitccdba88b73eae78984e31831079ff8798c2ddd59 (patch)
treeb3a40da8b6d55dc173b05bb4b98e7a3ef205fdbd
parentaddb75b981a2044a47adb7ff26850d6ff12b6144 (diff)
downloadsimplechat-ccdba88b73eae78984e31831079ff8798c2ddd59.tar.gz
simplechat-ccdba88b73eae78984e31831079ff8798c2ddd59.tar.bz2
simplechat-ccdba88b73eae78984e31831079ff8798c2ddd59.zip
Prevent users from flooding the server
-rw-r--r--floodstop.go47
-rw-r--r--websock.go14
2 files changed, 61 insertions, 0 deletions
diff --git a/floodstop.go b/floodstop.go
new file mode 100644
index 0000000..ad4af0f
--- /dev/null
+++ b/floodstop.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+ "time"
+)
+
+type Floodstop struct {
+ ask chan chan bool
+ stop chan struct{}
+}
+
+func NewFloodstop(reset time.Duration, countMax int) (fs *Floodstop) {
+ fs = &Floodstop{
+ ask: make(chan chan bool),
+ stop: make(chan struct{}),
+ }
+
+ ticker := time.NewTicker(reset)
+ counter := 0
+
+ go func() {
+ defer ticker.Stop()
+ for {
+ select {
+ case <-fs.stop:
+ return
+ case retCh := <-fs.ask:
+ counter++
+ retCh <- (counter < countMax)
+ case <-ticker.C:
+ counter = 0
+ }
+ }
+ }()
+
+ return
+}
+
+func (fs *Floodstop) Stop() {
+ fs.stop <- struct{}{}
+}
+
+func (fs *Floodstop) Ask() bool {
+ ch := make(chan bool)
+ fs.ask <- ch
+ return <-ch
+}
diff --git a/websock.go b/websock.go
index 9734e65..f42580f 100644
--- a/websock.go
+++ b/websock.go
@@ -5,6 +5,7 @@ import (
"github.com/gorilla/mux"
"github.com/kch42/simplechat/chat"
"net/http"
+ "time"
)
type JoinResponse struct {
@@ -13,6 +14,11 @@ type JoinResponse struct {
Buddies []string `json:"buddies,omitempty"`
}
+const (
+ floodstopReset = 1 * time.Second
+ floodstopMax = 3
+)
+
func AcceptWebSock(rw http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
roomname := vars["chatroom"]
@@ -45,6 +51,9 @@ func AcceptWebSock(rw http.ResponseWriter, req *http.Request) {
exit := make(chan struct{})
+ floodstop := NewFloodstop(floodstopReset, floodstopMax)
+ defer floodstop.Stop()
+
go func() {
var s string
for {
@@ -52,6 +61,11 @@ func AcceptWebSock(rw http.ResponseWriter, req *http.Request) {
break
}
+ if !floodstop.Ask() {
+ // User sent too many requests in a short amount of time. Kick them!
+ break
+ }
+
if s == "" {
continue
}