| Index: lib/downloader.js | 
| =================================================================== | 
| --- a/lib/downloader.js | 
| +++ b/lib/downloader.js | 
| @@ -115,6 +115,18 @@ | 
| onDownloadError: null, | 
|  | 
| /** | 
| +   * Callback to be triggered for POST request data generation. | 
| +   * @type Function | 
| +   */ | 
| +  generateRequestData: null, | 
| + | 
| +  /** | 
| +   * List of valid responses. | 
| +   * @type Array | 
| +   */ | 
| +  validResponses: [200], | 
| + | 
| +  /** | 
| * Checks whether anything needs downloading. | 
| */ | 
| _doCheck: function() | 
| @@ -250,7 +262,7 @@ | 
| { | 
| request = new XMLHttpRequest(); | 
| request.mozBackgroundRequest = true; | 
| -      request.open("GET", downloadUrl); | 
| +      request.open(this.generateRequestData ? "POST" : "GET", downloadUrl); | 
| } | 
| catch (e) | 
| { | 
| @@ -290,7 +302,7 @@ | 
| delete this._downloading[downloadable.url]; | 
|  | 
| // Status will be 0 for non-HTTP requests | 
| -      if (request.status && request.status != 200) | 
| +      if (request.status && this.validResponses.indexOf(request.status) == -1) | 
| { | 
| errorCallback("synchronize_connection_error"); | 
| return; | 
| @@ -310,7 +322,16 @@ | 
| }.bind(this)); | 
| }.bind(this), false); | 
|  | 
| -    request.send(null); | 
| +    if (this.generateRequestData) | 
| +    { | 
| +      Promise.resolve(this.generateRequestData(downloadable)) | 
| +        .then(data => { | 
| +          request.setRequestHeader("Content-Type", "application/json"); | 
| +          request.send(JSON.stringify(data)); | 
| +        }); | 
| +    } | 
| +    else | 
| +      request.send(null); | 
|  | 
| this._downloading[downloadable.url] = true; | 
| if (this.onDownloadStarted) | 
|  |