Limit requestPlaylist to once per 60 seconds
If clients call it quickly in succession with large playlists, it can cause node to get stuck stringifying socket.io frames and cause an out of memory crash.
This commit is contained in:
parent
65d4ea9496
commit
b3c85e8534
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.14.2",
|
"version": "3.14.3",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,6 +11,13 @@ var CustomEmbedFilter = require("../customembed").filter;
|
||||||
var XSS = require("../xss");
|
var XSS = require("../xss");
|
||||||
|
|
||||||
const MAX_ITEMS = Config.get("playlist.max-items");
|
const MAX_ITEMS = Config.get("playlist.max-items");
|
||||||
|
// Limit requestPlaylist to once per 60 seconds
|
||||||
|
const REQ_PLAYLIST_THROTTLE = {
|
||||||
|
burst: 1,
|
||||||
|
sustained: 0,
|
||||||
|
cooldown: 60
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const TYPE_QUEUE = {
|
const TYPE_QUEUE = {
|
||||||
id: "string,boolean",
|
id: "string,boolean",
|
||||||
|
@ -216,9 +223,7 @@ PlaylistModule.prototype.onUserPostJoin = function (user) {
|
||||||
user.socket.on("playerReady", function () {
|
user.socket.on("playerReady", function () {
|
||||||
self.sendChangeMedia([user]);
|
self.sendChangeMedia([user]);
|
||||||
});
|
});
|
||||||
user.socket.on("requestPlaylist", function () {
|
user.socket.on("requestPlaylist", this.handleRequestPlaylist.bind(this, user));
|
||||||
self.sendPlaylist([user]);
|
|
||||||
});
|
|
||||||
user.on("login", function () {
|
user.on("login", function () {
|
||||||
self.sendPlaylist([user]);
|
self.sendPlaylist([user]);
|
||||||
});
|
});
|
||||||
|
@ -1323,4 +1328,16 @@ PlaylistModule.prototype.handleQueuePlaylist = function (user, data) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlaylistModule.prototype.handleRequestPlaylist = function (user) {
|
||||||
|
if (user.reqPlaylistLimiter.throttle(REQ_PLAYLIST_THROTTLE)) {
|
||||||
|
user.socket.emit("errorMsg", {
|
||||||
|
msg: "Get Playlist URLs is limited to 1 usage every 60 seconds. " +
|
||||||
|
"Please try again later.",
|
||||||
|
code: "REQ_PLAYLIST_LIMIT_REACHED"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.sendPlaylist([user]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = PlaylistModule;
|
module.exports = PlaylistModule;
|
||||||
|
|
|
@ -21,6 +21,7 @@ function User(socket) {
|
||||||
self.channel = null;
|
self.channel = null;
|
||||||
self.queueLimiter = util.newRateLimiter();
|
self.queueLimiter = util.newRateLimiter();
|
||||||
self.chatLimiter = util.newRateLimiter();
|
self.chatLimiter = util.newRateLimiter();
|
||||||
|
self.reqPlaylistLimiter = util.newRateLimiter();
|
||||||
self.awaytimer = false;
|
self.awaytimer = false;
|
||||||
|
|
||||||
var announcement = Server.getServer().announcement;
|
var announcement = Server.getServer().announcement;
|
||||||
|
|
27
www/js/ui.js
27
www/js/ui.js
|
@ -490,9 +490,14 @@ $("#voteskip").click(function() {
|
||||||
$("#getplaylist").click(function() {
|
$("#getplaylist").click(function() {
|
||||||
var callback = function(data) {
|
var callback = function(data) {
|
||||||
hidePlayer();
|
hidePlayer();
|
||||||
socket.listeners("playlist").splice(
|
var idx = socket.listeners("errorMsg").indexOf(errCallback);
|
||||||
socket.listeners("playlist").indexOf(callback)
|
if (idx >= 0) {
|
||||||
);
|
socket.listeners("errorMsg").splice(idx);
|
||||||
|
}
|
||||||
|
idx = socket.listeners("playlist").indexOf(callback);
|
||||||
|
if (idx >= 0) {
|
||||||
|
socket.listeners("playlist").splice(idx);
|
||||||
|
}
|
||||||
var list = [];
|
var list = [];
|
||||||
for(var i = 0; i < data.length; i++) {
|
for(var i = 0; i < data.length; i++) {
|
||||||
var entry = formatURL(data[i].media);
|
var entry = formatURL(data[i].media);
|
||||||
|
@ -524,6 +529,22 @@ $("#getplaylist").click(function() {
|
||||||
outer.modal();
|
outer.modal();
|
||||||
};
|
};
|
||||||
socket.on("playlist", callback);
|
socket.on("playlist", callback);
|
||||||
|
var errCallback = function(data) {
|
||||||
|
if (data.code !== "REQ_PLAYLIST_LIMIT_REACHED") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx = socket.listeners("errorMsg").indexOf(errCallback);
|
||||||
|
if (idx >= 0) {
|
||||||
|
socket.listeners("errorMsg").splice(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = socket.listeners("playlist").indexOf(callback);
|
||||||
|
if (idx >= 0) {
|
||||||
|
socket.listeners("playlist").splice(idx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
socket.on("errorMsg", errCallback);
|
||||||
socket.emit("requestPlaylist");
|
socket.emit("requestPlaylist");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue