| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 Eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 let MILLIS_IN_SECOND = exports.MILLIS_IN_SECOND = 1000; | 24 let MILLIS_IN_SECOND = exports.MILLIS_IN_SECOND = 1000; |
| 25 let MILLIS_IN_MINUTE = exports.MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND; | 25 let MILLIS_IN_MINUTE = exports.MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND; |
| 26 let MILLIS_IN_HOUR = exports.MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; | 26 let MILLIS_IN_HOUR = exports.MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; |
| 27 let MILLIS_IN_DAY = exports.MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; | 27 let MILLIS_IN_DAY = exports.MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * Creates a new downloader instance. | 30 * Creates a new downloader instance. |
| 31 * @param {Function} dataSource Function that will yield downloadable objects o n each check | 31 * @param {Function} dataSource Function that will yield downloadable objects o n each check |
| 32 * @param {Integer} initialDelay Number of milliseconds to wait before the firs t check | 32 * @param {Integer} initialDelay Number of milliseconds to wait before the firs t check |
| 33 * @param {Integer} checkInterval Interval between the checks | 33 * @param {Integer} checkInterval Interval between the checks |
| 34 * @param {function} downloadCallback optional function that's being called when something needs to be downloaded | |
| 35 * @constructor | 34 * @constructor |
| 36 */ | 35 */ |
| 37 let Downloader = exports.Downloader = function Downloader(dataSource, initialDel ay, checkInterval, downloadCallback) | 36 let Downloader = exports.Downloader = function Downloader(dataSource, initialDel ay, checkInterval) |
|
saroyanm
2016/03/18 18:24:48
Maybe this changes will be reverted if you agree w
Wladimir Palant
2016/03/23 11:06:01
You are still duplicating quite a bit of the logic
saroyanm
2016/04/06 15:12:49
Thanks for detailed explanation, Done.
| |
| 38 { | 37 { |
| 39 this.dataSource = dataSource; | 38 this.dataSource = dataSource; |
| 40 this.downloadCallback = downloadCallback || this._download; | |
| 41 this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); | 39 this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); |
| 42 this._timer.initWithCallback(function() | 40 this._timer.initWithCallback(function() |
| 43 { | 41 { |
| 44 this._timer.delay = checkInterval; | 42 this._timer.delay = checkInterval; |
| 45 this._doCheck(); | 43 this._doCheck(); |
| 46 }.bind(this), initialDelay, Ci.nsITimer.TYPE_REPEATING_SLACK); | 44 }.bind(this), initialDelay, Ci.nsITimer.TYPE_REPEATING_SLACK); |
| 47 this._downloading = Object.create(null); | 45 this._downloading = Object.create(null); |
| 48 } | 46 } |
| 49 Downloader.prototype = | 47 Downloader.prototype = |
| 50 { | 48 { |
| 51 /** | 49 /** |
| 52 * Timer triggering the downloads. | 50 * Timer triggering the downloads. |
| 53 * @type nsITimer | 51 * @type nsITimer |
| 54 */ | 52 */ |
| 55 _timer: null, | 53 _timer: null, |
| 56 | 54 |
| 57 /** | 55 /** |
| 58 * Map containing the URLs of objects currently being downloaded as its keys. | 56 * Map containing the URLs of objects currently being downloaded as its keys. |
| 59 */ | 57 */ |
| 60 _downloading: null, | 58 _downloading: null, |
| 61 | 59 |
| 62 /** | 60 /** |
| 63 * Function that will yield downloadable objects on each check. | 61 * Function that will yield downloadable objects on each check. |
| 64 * @type Function | 62 * @type Function |
| 65 */ | 63 */ |
| 66 dataSource: null, | 64 dataSource: null, |
| 67 | 65 |
| 68 /** | 66 /** |
| 69 * Function that's being called when something needs to be downloaded. | |
| 70 * @type Function | |
| 71 */ | |
| 72 downloadCallback: null, | |
| 73 | |
| 74 /** | |
| 75 * Maximal time interval that the checks can be left out until the soft | 67 * Maximal time interval that the checks can be left out until the soft |
| 76 * expiration interval increases. | 68 * expiration interval increases. |
| 77 * @type Integer | 69 * @type Integer |
| 78 */ | 70 */ |
| 79 maxAbsenceInterval: 1 * MILLIS_IN_DAY, | 71 maxAbsenceInterval: 1 * MILLIS_IN_DAY, |
| 80 | 72 |
| 81 /** | 73 /** |
| 82 * Minimal time interval before retrying a download after an error. | 74 * Minimal time interval before retrying a download after an error. |
| 83 * @type Integer | 75 * @type Integer |
| 84 */ | 76 */ |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 114 * callback can return an error code to indicate that the data is wrong. | 106 * callback can return an error code to indicate that the data is wrong. |
| 115 * @type Function | 107 * @type Function |
| 116 */ | 108 */ |
| 117 onDownloadSuccess: null, | 109 onDownloadSuccess: null, |
| 118 | 110 |
| 119 /** | 111 /** |
| 120 * Callback to be triggered whenever a download fails. | 112 * Callback to be triggered whenever a download fails. |
| 121 * @type Function | 113 * @type Function |
| 122 */ | 114 */ |
| 123 onDownloadError: null, | 115 onDownloadError: null, |
| 116 | |
| 117 /** | |
| 118 * Callback to be triggered for POST request data generation. | |
| 119 * @type Function | |
| 120 */ | |
| 121 generateRequestData: null, | |
| 122 | |
| 123 /** | |
| 124 * List of valid responses. | |
| 125 * @type Array | |
| 126 */ | |
| 127 validResponses: [200], | |
| 124 | 128 |
| 125 /** | 129 /** |
| 126 * Checks whether anything needs downloading. | 130 * Checks whether anything needs downloading. |
| 127 */ | 131 */ |
| 128 _doCheck: function() | 132 _doCheck: function() |
| 129 { | 133 { |
| 130 let now = Date.now(); | 134 let now = Date.now(); |
| 131 for (let downloadable of this.dataSource()) | 135 for (let downloadable of this.dataSource()) |
| 132 { | 136 { |
| 133 if (downloadable.lastCheck && now - downloadable.lastCheck > this.maxAbsen ceInterval) | 137 if (downloadable.lastCheck && now - downloadable.lastCheck > this.maxAbsen ceInterval) |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 151 this.onExpirationChange(downloadable); | 155 this.onExpirationChange(downloadable); |
| 152 | 156 |
| 153 // Does that object need downloading? | 157 // Does that object need downloading? |
| 154 if (downloadable.softExpiration > now && downloadable.hardExpiration > now ) | 158 if (downloadable.softExpiration > now && downloadable.hardExpiration > now ) |
| 155 continue; | 159 continue; |
| 156 | 160 |
| 157 // Do not retry downloads too often | 161 // Do not retry downloads too often |
| 158 if (downloadable.lastError && now - downloadable.lastError < this.minRetry Interval) | 162 if (downloadable.lastError && now - downloadable.lastError < this.minRetry Interval) |
| 159 continue; | 163 continue; |
| 160 | 164 |
| 161 this.downloadCallback(downloadable, 0); | 165 this._download(downloadable, 0); |
| 162 } | 166 } |
| 163 }, | 167 }, |
| 164 | 168 |
| 165 /** | 169 /** |
| 166 * Stops the periodic checks. | 170 * Stops the periodic checks. |
| 167 */ | 171 */ |
| 168 cancel: function() | 172 cancel: function() |
| 169 { | 173 { |
| 170 this._timer.cancel(); | 174 this._timer.cancel(); |
| 171 }, | 175 }, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 } | 255 } |
| 252 | 256 |
| 253 this.onDownloadError(downloadable, downloadUrl, error, channelStatus, re sponseStatus, redirectCallback); | 257 this.onDownloadError(downloadable, downloadUrl, error, channelStatus, re sponseStatus, redirectCallback); |
| 254 } | 258 } |
| 255 }.bind(this); | 259 }.bind(this); |
| 256 | 260 |
| 257 try | 261 try |
| 258 { | 262 { |
| 259 request = new XMLHttpRequest(); | 263 request = new XMLHttpRequest(); |
| 260 request.mozBackgroundRequest = true; | 264 request.mozBackgroundRequest = true; |
| 261 request.open("GET", downloadUrl); | 265 request.open(this.generateRequestData ? "POST" : "GET", downloadUrl); |
| 262 } | 266 } |
| 263 catch (e) | 267 catch (e) |
| 264 { | 268 { |
| 265 errorCallback("synchronize_invalid_url"); | 269 errorCallback("synchronize_invalid_url"); |
| 266 return; | 270 return; |
| 267 } | 271 } |
| 268 | 272 |
| 269 try { | 273 try { |
| 270 request.overrideMimeType("text/plain"); | 274 request.overrideMimeType("text/plain"); |
| 271 request.channel.loadFlags = request.channel.loadFlags | | 275 request.channel.loadFlags = request.channel.loadFlags | |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 291 }.bind(this), false); | 295 }.bind(this), false); |
| 292 | 296 |
| 293 request.addEventListener("load", function(event) | 297 request.addEventListener("load", function(event) |
| 294 { | 298 { |
| 295 if (onShutdown.done) | 299 if (onShutdown.done) |
| 296 return; | 300 return; |
| 297 | 301 |
| 298 delete this._downloading[downloadable.url]; | 302 delete this._downloading[downloadable.url]; |
| 299 | 303 |
| 300 // Status will be 0 for non-HTTP requests | 304 // Status will be 0 for non-HTTP requests |
| 301 if (request.status && request.status != 200) | 305 if (request.status && this.validResponses.indexOf(request.status) == -1) |
| 302 { | 306 { |
| 303 errorCallback("synchronize_connection_error"); | 307 errorCallback("synchronize_connection_error"); |
| 304 return; | 308 return; |
| 305 } | 309 } |
| 306 | 310 |
| 307 downloadable.downloadCount++; | 311 downloadable.downloadCount++; |
| 308 | 312 |
| 309 this.onDownloadSuccess(downloadable, request.responseText, errorCallback, function redirectCallback(url) | 313 this.onDownloadSuccess(downloadable, request.responseText, errorCallback, function redirectCallback(url) |
| 310 { | 314 { |
| 311 if (redirects >= this.maxRedirects) | 315 if (redirects >= this.maxRedirects) |
| 312 errorCallback("synchronize_connection_error"); | 316 errorCallback("synchronize_connection_error"); |
| 313 else | 317 else |
| 314 { | 318 { |
| 315 downloadable.redirectURL = url; | 319 downloadable.redirectURL = url; |
| 316 this._download(downloadable, redirects + 1); | 320 this._download(downloadable, redirects + 1); |
| 317 } | 321 } |
| 318 }.bind(this)); | 322 }.bind(this)); |
| 319 }.bind(this), false); | 323 }.bind(this), false); |
| 320 | 324 |
| 321 request.send(null); | 325 if (this.generateRequestData) |
| 326 { | |
| 327 Promise.resolve(this.generateRequestData(downloadable)) | |
| 328 .then(data => { | |
| 329 request.setRequestHeader("Content-Type", "application/json"); | |
| 330 request.send(JSON.stringify(data)); | |
| 331 }); | |
| 332 } | |
| 333 else | |
| 334 request.send(null); | |
| 322 | 335 |
| 323 this._downloading[downloadable.url] = true; | 336 this._downloading[downloadable.url] = true; |
| 324 if (this.onDownloadStarted) | 337 if (this.onDownloadStarted) |
| 325 this.onDownloadStarted(downloadable); | 338 this.onDownloadStarted(downloadable); |
| 326 }, | 339 }, |
| 327 | 340 |
| 328 /** | 341 /** |
| 329 * Produces a soft and a hard expiration interval for a given supplied | 342 * Produces a soft and a hard expiration interval for a given supplied |
| 330 * expiration interval. | 343 * expiration interval. |
| 331 * @return {Array} soft and hard expiration interval | 344 * @return {Array} soft and hard expiration interval |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 * @type Integer | 406 * @type Integer |
| 394 */ | 407 */ |
| 395 hardExpiration: 0, | 408 hardExpiration: 0, |
| 396 | 409 |
| 397 /** | 410 /** |
| 398 * Number indicating how often the object was downloaded. | 411 * Number indicating how often the object was downloaded. |
| 399 * @type Integer | 412 * @type Integer |
| 400 */ | 413 */ |
| 401 downloadCount: 0, | 414 downloadCount: 0, |
| 402 }; | 415 }; |
| LEFT | RIGHT |