diff --git a/package.json b/package.json index 437bd331..658856d9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "3.14.2", + "version": "3.14.3", "repository": { "url": "http://github.com/calzoneman/sync" }, diff --git a/src/channel/playlist.js b/src/channel/playlist.js index 0beb9777..f4a40bf0 100644 --- a/src/channel/playlist.js +++ b/src/channel/playlist.js @@ -11,6 +11,13 @@ var CustomEmbedFilter = require("../customembed").filter; var XSS = require("../xss"); 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 = { id: "string,boolean", @@ -216,9 +223,7 @@ PlaylistModule.prototype.onUserPostJoin = function (user) { user.socket.on("playerReady", function () { self.sendChangeMedia([user]); }); - user.socket.on("requestPlaylist", function () { - self.sendPlaylist([user]); - }); + user.socket.on("requestPlaylist", this.handleRequestPlaylist.bind(this, user)); user.on("login", function () { 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; diff --git a/src/user.js b/src/user.js index 0c21b68f..1e6612c0 100644 --- a/src/user.js +++ b/src/user.js @@ -21,6 +21,7 @@ function User(socket) { self.channel = null; self.queueLimiter = util.newRateLimiter(); self.chatLimiter = util.newRateLimiter(); + self.reqPlaylistLimiter = util.newRateLimiter(); self.awaytimer = false; var announcement = Server.getServer().announcement; diff --git a/www/js/ui.js b/www/js/ui.js index 5219aa85..bb80663a 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -490,9 +490,14 @@ $("#voteskip").click(function() { $("#getplaylist").click(function() { var callback = function(data) { hidePlayer(); - socket.listeners("playlist").splice( - socket.listeners("playlist").indexOf(callback) - ); + 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); + } var list = []; for(var i = 0; i < data.length; i++) { var entry = formatURL(data[i].media); @@ -524,6 +529,22 @@ $("#getplaylist").click(function() { outer.modal(); }; 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"); });