diff --git a/notwebsocket.js b/notwebsocket.js
index f1b65f91..2f6409cd 100644
--- a/notwebsocket.js
+++ b/notwebsocket.js
@@ -14,6 +14,23 @@ var NotWebsocket = function() {
this.handlers = {};
this.room = "";
this.lastpoll = Date.now();
+ this.noflood = {};
+}
+
+NotWebsocket.prototype.checkFlood = function(id, rate) {
+ if(id in this.noflood) {
+ this.noflood[id].push(Date.now());
+ }
+ else {
+ this.noflood[id] = [Date.now()];
+ }
+ if(this.noflood[id].length > 10) {
+ this.noflood[id].shift();
+ var hz = 10000 / (this.noflood[id][9] - this.noflood[id][0]);
+ if(hz > rate) {
+ throw "Rate is too high: " + id;
+ }
+ }
}
NotWebsocket.prototype.emit = function(msg, data) {
@@ -22,6 +39,7 @@ NotWebsocket.prototype.emit = function(msg, data) {
}
NotWebsocket.prototype.poll = function() {
+ this.checkFlood("poll", 100);
this.lastpoll = Date.now();
var q = [];
for(var i = 0; i < this.pktqueue.length; i++) {
@@ -38,6 +56,7 @@ NotWebsocket.prototype.on = function(msg, callback) {
}
NotWebsocket.prototype.recv = function(urlstr) {
+ this.checkFlood("recv", 100);
var msg, data;
try {
var js = JSON.parse(urlstr);
@@ -115,12 +134,17 @@ function msgReceived(req, res) {
if(h in clients && clients[h] != null) {
var str = req.params.str;
res.callback = req.query.callback;
- if(str == "poll") {
- sendJSON(res, clients[h].poll());
+ try {
+ if(str == "poll") {
+ sendJSON(res, clients[h].poll());
+ }
+ else {
+ clients[h].recv(unescape(str));
+ sendJSON(res, "");
+ }
}
- else {
- clients[h].recv(unescape(str));
- sendJSON(res, "");
+ catch(e) {
+ res.send(429); // 429 Too Many Requests
}
}
else {
diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js
index 2c2201b5..f34a7b33 100644
--- a/www/assets/js/callbacks.js
+++ b/www/assets/js/callbacks.js
@@ -846,3 +846,9 @@ $.getScript(IO_URL+"/socket.io/socket.io.js", function() {
Callbacks.disconnect();
}
});
+
+window.setupNewSocket = function() {
+ for(var key in Callbacks) {
+ socket.on(key, Callbacks[key]);
+ }
+}
diff --git a/www/assets/js/functions.js b/www/assets/js/functions.js
index 7b41dd17..d344b813 100644
--- a/www/assets/js/functions.js
+++ b/www/assets/js/functions.js
@@ -1129,6 +1129,9 @@ function saveOpts() {
}
}
+// To be overridden in callbacks.js
+function setupNewSocket() { }
+
function applyOpts() {
$("#usertheme").remove();
if(USEROPTS.theme != "default") {
@@ -1189,22 +1192,18 @@ function applyOpts() {
}
if(USEROPTS.altsocket) {
- socket.disconnect();
+ if(socket)
+ socket.disconnect();
socket = new NotWebsocket();
- for(var key in Callbacks) {
- socket.on(key, Callbacks[key]);
- }
+ setupNewSocket();
}
// Switch from NotWebsocket => Socket.io
else if(socket && typeof socket.poll !== "undefined") {
try {
socket = io.connect(IO_URL);
- for(var key in Callbacks) {
- socket.on(key, Callbacks[key]);
- }
+ setupNewSocket();
}
catch(e) {
- Callbacks.disconnect();
}
}
}
diff --git a/www/assets/js/notwebsocket.js b/www/assets/js/notwebsocket.js
index a5e67ee1..a0495b26 100644
--- a/www/assets/js/notwebsocket.js
+++ b/www/assets/js/notwebsocket.js
@@ -118,3 +118,4 @@ NotWebsocket.prototype.disconnect = function() {
this.reconnect();
}.bind(this), this.reconndelay);
}
+
diff --git a/www/channel.html b/www/channel.html
index c3413473..3d8e62a3 100644
--- a/www/channel.html
+++ b/www/channel.html
@@ -310,10 +310,10 @@
+
-