Bug 908260, support 450 error for windows parental controls in new download api, r=paolo

This commit is contained in:
Neil Deakin 2013-09-26 10:58:21 -04:00
parent 7828a4c34f
commit 020f0a214f
3 changed files with 82 additions and 6 deletions

View File

@ -408,12 +408,12 @@ Download.prototype = {
}
}
// Disallow download if parental controls service restricts it.
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
throw new DownloadError({ becauseBlockedByParentalControls: true });
}
try {
// Disallow download if parental controls service restricts it.
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
throw new DownloadError({ becauseBlockedByParentalControls: true });
}
// Execute the actual download through the saver object.
yield this.saver.execute(DS_setProgressBytes.bind(this),
DS_setProperties.bind(this));
@ -430,6 +430,15 @@ Download.prototype = {
throw new DownloadError({ message: "Download canceled." });
}
// An HTTP 450 error code is used by Windows to indicate that a uri is
// blocked by parental controls. This will prevent the download from
// occuring, so an error needs to be raised. This is not performed
// during the parental controls check above as it requires the request
// to start.
if (this._blockedByParentalControls) {
ex = new DownloadError({ becauseBlockedByParentalControls: true });
}
// Update the download error, unless a new attempt already started. The
// change in the status property is notified in the finally block.
if (this._currentAttempt == currentAttempt || !this._currentAttempt) {
@ -472,7 +481,7 @@ Download.prototype = {
// Notify the new download state before returning.
this._notifyChange();
return this._currentAttempt;
return currentAttempt;
},
/*
@ -1331,6 +1340,31 @@ DownloadSaver.prototype = {
targetUri);
},
/**
* Return true if the request's response has been blocked by Windows parental
* controls with an HTTP 450 error code.
*
* @param aRequest
* nsIRequest object
* @return True if the response is blocked.
*/
isResponseParentalBlocked: function(aRequest)
{
// If the HTTP status is 450, then Windows Parental Controls have
// blocked this download.
if (aRequest instanceof Ci.nsIHttpChannel &&
aRequest.responseStatus == 450) {
// Cancel the request, but set a flag on the download that can be
// retrieved later when handling the cancellation so that the proper
// blocked by parental controls error can be thrown.
this.download._blockedByParentalControls = true;
aRequest.cancel(Cr.NS_BINDING_ABORTED);
return true;
}
return false;
},
/**
* Returns a static representation of the current object state.
*
@ -1528,6 +1562,10 @@ DownloadCopySaver.prototype = {
onStartRequest: function (aRequest, aContext) {
backgroundFileSaver.onStartRequest(aRequest, aContext);
if (this.isResponseParentalBlocked(aRequest)) {
return;
}
aSetPropertiesFn({ contentType: channel.contentType });
// Ensure we report the value of "Content-Length", if available,
@ -1799,6 +1837,10 @@ DownloadLegacySaver.prototype = {
ex.result == Cr.NS_ERROR_NOT_RESUMABLE) { }
}
if (this.isResponseParentalBlocked(aRequest)) {
return;
}
// For legacy downloads, we must update the referrer at this time.
if (aRequest instanceof Ci.nsIHttpChannel && aRequest.referrer) {
this.download.source.referrer = aRequest.referrer.spec;

View File

@ -1355,6 +1355,7 @@ add_task(function test_blocked_parental_controls()
do_throw("The download should have blocked.");
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
do_check_true(ex.becauseBlockedByParentalControls);
do_check_true(download.error.becauseBlockedByParentalControls);
}
// Now that the download stopped, the target file should not exist.
@ -1363,6 +1364,32 @@ add_task(function test_blocked_parental_controls()
cleanup();
});
/**
* Test a download that will be blocked by Windows parental controls by
* resulting in an HTTP status code of 450.
*/
add_task(function test_blocked_parental_controls_httpstatus450()
{
let download;
try {
if (!gUseLegacySaver) {
download = yield promiseNewDownload(httpUrl("parentalblocked.zip"));
yield download.start();
}
else {
download = yield promiseStartLegacyDownload(httpUrl("parentalblocked.zip"));
yield promiseDownloadStopped(download);
}
do_throw("The download should have blocked.");
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
do_check_true(ex.becauseBlockedByParentalControls);
do_check_true(download.error.becauseBlockedByParentalControls);
do_check_true(download.stopped);
}
do_check_false(yield OS.File.exists(download.target.path));
});
/**
* download.showContainingDirectory() action
*/

View File

@ -773,6 +773,13 @@ add_task(function test_common_initialize()
TEST_DATA_SHORT_GZIP_ENCODED_SECOND.length);
});
// This URL will emulate being blocked by Windows Parental controls
gHttpServer.registerPathHandler("/parentalblocked.zip",
function (aRequest, aResponse) {
aResponse.setStatusLine(aRequest.httpVersion, 450,
"Blocked by Windows Parental Controls");
});
// Disable integration with the host application requiring profile access.
DownloadIntegration.dontLoadList = true;
DownloadIntegration.dontLoadObservers = true;