| Index: lib/synchronizer.js |
| =================================================================== |
| --- a/lib/synchronizer.js |
| +++ b/lib/synchronizer.js |
| @@ -19,22 +19,20 @@ |
| /** |
| * @fileOverview Manages synchronization of filter subscriptions. |
| */ |
| const {Downloader, Downloadable, |
| MILLIS_IN_SECOND, MILLIS_IN_MINUTE, |
| MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); |
| -const {Filter} = require("filterClasses"); |
| const {FilterStorage} = require("filterStorage"); |
| const {FilterNotifier} = require("filterNotifier"); |
| const {Prefs} = require("prefs"); |
| const {Subscription, DownloadableSubscription} = require("subscriptionClasses"); |
| -const {Utils} = require("utils"); |
| const INITIAL_DELAY = 1 * MILLIS_IN_MINUTE; |
| const CHECK_INTERVAL = 1 * MILLIS_IN_HOUR; |
| const DEFAULT_EXPIRATION_INTERVAL = 5 * MILLIS_IN_DAY; |
| /** |
| * The object providing actual downloading functionality. |
| * @type {Downloader} |
| @@ -148,148 +146,94 @@ |
| redirectCallback) |
| { |
| let lines = responseText.split(/[\r\n]+/); |
| let headerMatch = /\[Adblock(?:\s*Plus\s*([\d.]+)?)?\]/i.exec(lines[0]); |
| if (!headerMatch) |
| return errorCallback("synchronize_invalid_data"); |
| let minVersion = headerMatch[1]; |
| - // Don't remove parameter comments immediately but add them to a list first, |
| - // they need to be considered in the checksum calculation. |
| - let remove = []; |
| - let params = { |
| - redirect: null, |
| - homepage: null, |
| - title: null, |
| - version: null, |
| - expires: null |
| - }; |
| - for (let i = 0; i < lines.length; i++) |
| + let parser = DownloadableSubscription.parseDownload(); |
| + |
| + // Process filters |
| + for (let line of lines) |
| + parser.process(line); |
| + |
| + if (!parser.verifyChecksum()) |
| + return errorCallback("synchronize_checksum_mismatch"); |
| + |
| + if (parser.redirect) |
| { |
| - let match = /^\s*!\s*(\w+)\s*:\s*(.*)/.exec(lines[i]); |
| - if (match) |
| - { |
| - let keyword = match[1].toLowerCase(); |
| - let value = match[2]; |
| - if (keyword in params) |
| - { |
| - params[keyword] = value; |
| - remove.push(i); |
| - } |
| - else if (keyword == "checksum") |
| - { |
| - lines.splice(i--, 1); |
| - let checksum = Utils.generateChecksum(lines); |
| - if (checksum && checksum != value.replace(/=+$/, "")) |
| - return errorCallback("synchronize_checksum_mismatch"); |
| - } |
| - } |
| + let {redirect} = parser; |
| + parser.delete(); |
| + return redirectCallback(redirect); |
| } |
| - if (params.redirect) |
| - return redirectCallback(params.redirect); |
| - |
| // Handle redirects |
| let subscription = Subscription.fromURL(downloadable.redirectURL || |
| downloadable.url); |
| if (downloadable.redirectURL && |
| downloadable.redirectURL != downloadable.url) |
| { |
| let oldSubscription = Subscription.fromURL(downloadable.url); |
| subscription.title = oldSubscription.title; |
| subscription.disabled = oldSubscription.disabled; |
| subscription.lastCheck = oldSubscription.lastCheck; |
| - let listed = (oldSubscription.url in FilterStorage.knownSubscriptions); |
| + let {listed} = oldSubscription; |
| if (listed) |
| FilterStorage.removeSubscription(oldSubscription); |
| - delete Subscription.knownSubscriptions[oldSubscription.url]; |
| - |
| if (listed) |
| FilterStorage.addSubscription(subscription); |
| } |
| // The download actually succeeded |
| subscription.lastSuccess = subscription.lastDownload = Math.round( |
| Date.now() / MILLIS_IN_SECOND |
| ); |
| subscription.downloadStatus = "synchronize_ok"; |
| subscription.downloadCount = downloadable.downloadCount; |
| subscription.errors = 0; |
| - // Remove lines containing parameters |
| - for (let i = remove.length - 1; i >= 0; i--) |
| - lines.splice(remove[i], 1); |
| - |
| // Process parameters |
| - if (params.homepage) |
| + if (parser.homepage) |
| { |
| let url; |
| try |
| { |
| - url = new URL(params.homepage); |
| + url = new URL(parser.homepage); |
| } |
| catch (e) |
| { |
| url = null; |
| } |
| if (url && (url.protocol == "http:" || url.protocol == "https:")) |
| subscription.homepage = url.href; |
| } |
| - if (params.title) |
| - { |
| - subscription.title = params.title; |
| - subscription.fixedTitle = true; |
| - } |
| + if (minVersion) |
| + subscription.requiredVersion = minVersion; |
| else |
| - subscription.fixedTitle = false; |
| - |
| - subscription.version = (params.version ? parseInt(params.version, 10) : 0); |
| + delete subscription.requiredVersion; |
| let expirationInterval = DEFAULT_EXPIRATION_INTERVAL; |
| - if (params.expires) |
| - { |
| - let match = /^(\d+)\s*(h)?/.exec(params.expires); |
| - if (match) |
| - { |
| - let interval = parseInt(match[1], 10); |
| - if (match[2]) |
| - expirationInterval = interval * MILLIS_IN_HOUR; |
| - else |
| - expirationInterval = interval * MILLIS_IN_DAY; |
| - } |
| - } |
| + let expiration = parser.finalize(subscription); |
| + if (expiration != 0) |
| + expirationInterval = expiration; |
| let [ |
| softExpiration, |
| hardExpiration |
| ] = downloader.processExpirationInterval(expirationInterval); |
| subscription.softExpiration = Math.round(softExpiration / MILLIS_IN_SECOND); |
| subscription.expires = Math.round(hardExpiration / MILLIS_IN_SECOND); |
| - if (minVersion) |
| - subscription.requiredVersion = minVersion; |
| - else |
| - delete subscription.requiredVersion; |
| - |
| - // Process filters |
| - lines.shift(); |
| - let filters = []; |
| - for (let line of lines) |
| - { |
| - line = Filter.normalize(line); |
| - if (line) |
| - filters.push(Filter.fromText(line)); |
| - } |
| - |
| - FilterStorage.updateSubscriptionFilters(subscription, filters); |
| + parser.delete(); |
| return undefined; |
| }, |
| _onDownloadError(downloadable, downloadURL, error, channelStatus, |
| responseStatus, redirectCallback) |
| { |
| let subscription = Subscription.fromURL(downloadable.url); |
| @@ -329,29 +273,29 @@ |
| request.channel.loadFlags = request.channel.loadFlags | |
| request.channel.INHIBIT_CACHING | |
| request.channel.VALIDATE_ALWAYS; |
| request.addEventListener("load", ev => |
| { |
| if (onShutdown.done) |
| return; |
| - if (!(subscription.url in FilterStorage.knownSubscriptions)) |
| + if (!subscription.listed) |
| return; |
| let match = /^(\d+)(?:\s+(\S+))?$/.exec(request.responseText); |
| if (match && match[1] == "301" && // Moved permanently |
| match[2] && /^https?:\/\//i.test(match[2])) |
| { |
| redirectCallback(match[2]); |
| } |
| else if (match && match[1] == "410") // Gone |
| { |
| let data = "[Adblock]\n" + |
| - subscription.filters.map(f => f.text).join("\n"); |
| + Array.from(subscription.filters, f => f.text).join("\n"); |
| redirectCallback("data:text/plain," + encodeURIComponent(data)); |
| } |
| }, false); |
| request.send(null); |
| } |
| } |
| } |
| }; |