In regards to stopping a nsIRequest before completion and determining
when a nsIRequest is complete

Thanks to everyone in advance!

I am using a xul:browser and attaching a nsIWebProgressListener to it.
I am trying to accomplish two things:
1. Determine when a request is complete (when a document is completely
load with all css/js/imgs).
2. Stop a request from completing, specifically URLs with files that
issue the download prompt.

In regards to my first issue, because the aStateFlags argument is set
with (STATE_IS_* | STATE_STOP) in
nsIWebProgressListener.onStateChange() and is called multiple times it
is impossible to determine when a request is 100% complete and there
are no more state changes. How is this accomplished?

What I am trying to accomplish specifically with the second issue that
I am having is terminating a request when a certain "content-type"
header value is found. For instance if a "application/pdf" content
type is found, if the request is terminated then the download prompt
(which from my understanding is not part of the nsIDownloadManager) is
never displayed - this is the exact behavior I am trying to
accomplish.

Here is the nsIWebProgressListener code I am currently working with:

//setup progress listener
var progressListener = {
stateIsRequest:false,
methodCalled:"",
WebProgress:"",
Request:"",
Flag:"",
Status:"",
Location:"",
CurSelfProgress:"",
MaxSelfProgress:"",
CurTotalProgress:"",
MaxTotalProgress:"",
Message:"",
State:"",
QueryInterface : function(aIID) {
if(aIID.equals(Components.interfaces.nsIWebProgres sListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakR eference) ||
aIID.equals(Components.interfaces.nsISupports)){
return this;
}
else{
throw Components.results.NS_NOINTERFACE;
}
},
onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
this.methodCalled = "onStateChange";
this.WebProgress = aWebProgress;
this.Request = aRequest;
this.Flag = aFlag;
this.Status = aStatus;
this.Location = "";
this.CurSelfProgress = "";
this.MaxSelfProgress = "";
this.CurTotalProgress = "";
this.MaxTotalProgress = "";
this.Message = "";
this.State = "";
this.CaptureHeaders(aRequest);
},

onLocationChange : function(aWebProgress, aRequest, aLocation) {
this.methodCalled = "onLocationChange";
this.WebProgress = aWebProgress;
this.Request = aRequest;
this.Flag = "";
this.Status = "";
this.Location = aLocation;
this.CurSelfProgress = "";
this.MaxSelfProgress = "";
this.CurTotalProgress = "";
this.MaxTotalProgress = "";
this.Message = "";
this.State = "";
this.CaptureHeaders(aRequest);
},
onProgressChange : function(aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
aMaxTotalProgress){
this.methodCalled = "onProgressChange";
this.WebProgress = aWebProgress;
this.Request = aRequest;
this.Flag = "";
this.Status = "";
this.Location = "";
this.CurSelfProgress = aCurSelfProgress;
this.MaxSelfProgress = aMaxSelfProgress;
this.CurTotalProgress = aCurTotalProgress;
this.MaxTotalProgress = aMaxTotalProgress;
this.Message = "";
this.State = "";
this.CaptureHeaders(aRequest);
},
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
{
this.methodCalled = "onStatusChange";
this.WebProgress = aWebProgress;
this.Request = aRequest;
this.Flag = "";
this.Status = aStatus;
this.Location = "";
this.CurSelfProgress = "";
this.MaxSelfProgress = "";
this.CurTotalProgress = "";
this.MaxTotalProgress = "";
this.Message = aMessage;
this.State = "";
this.CaptureHeaders(aRequest);
},
onSecurityChange : function(aWebProgress, aRequest, aState){
this.methodCalled = "onSecurityChange";
this.WebProgress = aWebProgress;
this.Request = aRequest;
this.Flag = "";
this.Status = "";
this.Location = "";
this.CurSelfProgress = "";
this.MaxSelfProgress = "";
this.CurTotalProgress = "";
this.MaxTotalProgress = "";
this.Message = "";
this.State = aState;
this.CaptureHeaders(aRequest);
},
onLinkIconAvailable : function(a){},
CaptureHeaders : function(ThisRequest){
try{
//specify response headers to get
var ResponseHeaders = new Array();
ResponseHeaders.push("status");
ResponseHeaders.push("data");
ResponseHeaders.push("server");
ResponseHeaders.push("content-language");
ResponseHeaders.push("content-encoding");
ResponseHeaders.push("content-length");
ResponseHeaders.push("expires");
ResponseHeaders.push("cache-control");
ResponseHeaders.push("keep-alive");
ResponseHeaders.push("status");
ResponseHeaders.push("connection");
ResponseHeaders.push("content-type");
ResponseHeaders.push("set-cookie");

//specify request headers to get
var RequestHeaders = new Array();
RequestHeaders.push("host");
RequestHeaders.push("user-agent");
RequestHeaders.push("accept");
RequestHeaders.push("accept-language");
RequestHeaders.push("accept-encoding");
RequestHeaders.push("accept-charset");
RequestHeaders.push("keep-alive");
RequestHeaders.push("connection");
RequestHeaders.push("cookie");
RequestHeaders.push("cache-control");

//get browser
var CurrentBrowser = document.getElementById("current_browser");
//var CurrentURL = CurrentBrowser.current_url;
//var CurrentURL = ThisRequest.nsIHttpChannel.originalURI.spec;

if(ThisRequest.nsIHttpChannel != undefined){
var CurrentURL = ThisRequest.nsIHttpChannel.originalURI.spec;
//is this the first time headers were created for this browser?
if(CurrentBrowser.headers instanceof Object){
//have we collected headers for this url before
if(CurrentBrowser.headers[CurrentURL] instanceof Object){
//do nothing
}
else{
CurrentBrowser.headers[CurrentURL] = new Object();
CurrentBrowser.headers[CurrentURL].request = new Object();
CurrentBrowser.headers[CurrentURL].response = new Object()
}
}
else{
CurrentBrowser.headers = new Object();
CurrentBrowser.headers[CurrentURL] = new Object();
CurrentBrowser.headers[CurrentURL].request = new Object();
CurrentBrowser.headers[CurrentURL].response = new Object()
}

//load up headers
//add response headers
for(i = 0; i < ResponseHeaders.length; i++){
try{
if(ResponseHeaders[i] == "status"){

CurrentBrowser.headers[CurrentURL].response[ResponseHeaders[i]] =
ThisRequest.nsIHttpChannel.responseStatus;
}
else{

CurrentBrowser.headers[CurrentURL].response[ResponseHeaders[i]] =
ThisRequest.nsIHttpChannel.getResponseHeader(Respo nseHeaders[i]);
}
}
catch(e){}
}

//add request headers
for(i = 0; i < RequestHeaders.length; i++){
try{
CurrentBrowser.headers[CurrentURL].request[RequestHeaders[i]]
= ThisRequest.nsIHttpChannel.getRequestHeader(Reques tHeaders[i]);
}
catch(e){}
}
//end load up headers

/*
Completed flag - STATE_IS_REQUEST:65552
Completed flag - STATE_IS_DOCUMENT:131088
Completed flag - STATE_IS_NETWORK:262160
Completed flag - STATE_IS_WINDOW:524304

//CurrentBrowser.webNavigation.nsIWebNavigation.stop (1);
//CurrentBrowser.webNavigation.nsIWebNavigation.stop (2);
//CurrentBrowser.webNavigation.nsIWebNavigation.stop (3);
//CurrentBrowser.stop();
//ThisRequest.cancel(2152398850);
//ThisRequest.cancel(Components.results.NS_OK);
//ThisRequest.suspend();
*/

//setup nonload rules
if(CurrentBrowser.headers[CurrentURL].response["content-type"]
== "application/zip"){
MyExtension.WriteToDebug("Cancelled Request: "+ CurrentURL);

//try multiple ways to terminate the request
if(ThisRequest.nsIHttpChannel.loadGroup.activeCoun t > 0){

ThisRequest.nsIHttpChannel.loadGroup.removeRequest (ThisRequest,
ThisRequest, Components.results.NS_BINDING_ABORTED);
}

CurrentBrowser.webNavigation.nsIWebNavigation.stop (1);
CurrentBrowser.webNavigation.nsIWebNavigation.stop (2);
CurrentBrowser.webNavigation.nsIWebNavigation.stop (3);
CurrentBrowser.stop();
ThisRequest.cancel(Components.results.NS_OK);
//end try multiple ways to terminate the request

//after request is terminated execute onNONload
CurrentBrowser.OnNonLoad(CurrentURL);
}
//setup nonload rules
else if(CurrentBrowser.headers[CurrentURL].response["content-
type"] == "application/pdf"){
MyExtension.WriteToDebug("Cancelled Request: "+ CurrentURL);

//try multiple ways to terminate the request
if(ThisRequest.nsIHttpChannel.loadGroup.activeCoun t > 0){

ThisRequest.nsIHttpChannel.loadGroup.removeRequest (ThisRequest,
ThisRequest, Components.results.NS_BINDING_ABORTED);
}

CurrentBrowser.webNavigation.nsIWebNavigation.stop (1);
CurrentBrowser.webNavigation.nsIWebNavigation.stop (2);
CurrentBrowser.webNavigation.nsIWebNavigation.stop (3);
CurrentBrowser.stop();
ThisRequest.cancel(Components.results.NS_OK);
//end try multiple ways to terminate the request

//after request is terminated execute onNONload
CurrentBrowser.OnNonLoad(CurrentURL);
}
//determine if finished loading
else if(this.Flag == 65552 || this.Flag == 131088 || this.Flag
== 262160 || this.Flag == 524304){
MyExtension.WriteToDebug("Request Completed!");
MyExtension.WriteToDebug("pending:"+ ThisRequest.isPending()
+"
name:"+ ThisRequest.name +"
URL:"+ CurrentURL +"

>content-type:"+ CurrentBrowser.headers[CurrentURL].response["content-
type"]+"
status:"+
CurrentBrowser.headers[CurrentURL].response["status"]);
if(this.Flag ==
(Components.interfaces.nsIWebProgressListener.STAT E_IS_REQUEST |
Components.interfaces.nsIWebProgressListener.STATE _STOP)){
MyExtension.WriteToDebug("Completed flag - STATE_IS_REQUEST:"+
(Components.interfaces.nsIWebProgressListener.STAT E_IS_REQUEST |
Components.interfaces.nsIWebProgressListener.STATE _STOP));
}
if(this.Flag ==
(Components.interfaces.nsIWebProgressListener.STAT E_IS_DOCUMENT |
Components.interfaces.nsIWebProgressListener.STATE _STOP)){
MyExtension.WriteToDebug("Completed flag -
STATE_IS_DOCUMENT:"+
(Components.interfaces.nsIWebProgressListener.STAT E_IS_DOCUMENT |
Components.interfaces.nsIWebProgressListener.STATE _STOP));
}
if(this.Flag ==
(Components.interfaces.nsIWebProgressListener.STAT E_IS_NETWORK |
Components.interfaces.nsIWebProgressListener.STATE _STOP)){
MyExtension.WriteToDebug("Completed flag - STATE_IS_NETWORK:"+
(Components.interfaces.nsIWebProgressListener.STAT E_IS_NETWORK |
Components.interfaces.nsIWebProgressListener.STATE _STOP));
}
if(this.Flag ==
(Components.interfaces.nsIWebProgressListener.STAT E_IS_WINDOW |
Components.interfaces.nsIWebProgressListener.STATE _STOP)){
MyExtension.WriteToDebug("Completed flag - STATE_IS_WINDOW:"+
(Components.interfaces.nsIWebProgressListener.STAT E_IS_WINDOW |
Components.interfaces.nsIWebProgressListener.STATE _STOP));
}


//MyExtension.WriteToDebug("methodCalled:"+ this.methodCalled);
//MyExtension.WriteToDebug("WebProgress:"+ this.WebProgress);
//MyExtension.WriteToDebug("Request:"+ this.Request);
MyExtension.WriteToDebug("Flag:"+ this.Flag);
//MyExtension.WriteToDebug("Status:"+ this.Status);
//MyExtension.WriteToDebug("Location:"+ this.Location);
//MyExtension.WriteToDebug("CurSelfProgress:"+
this.CurSelfProgress);
//MyExtension.WriteToDebug("MaxSelfProgress:"+
this.MaxSelfProgress);
//MyExtension.WriteToDebug("CurTotalProgress:"+
this.CurTotalProgress);
//MyExtension.WriteToDebug("MaxTotalProgress:"+
this.MaxTotalProgress);
//MyExtension.WriteToDebug("Message:"+ this.Message);
//MyExtension.WriteToDebug("State:"+ this.State);
MyExtension.WriteToDebug("Load group count:"+
ThisRequest.nsIHttpChannel.loadGroup.activeCount);
MyExtension.WriteToDebug("WebProgress.isLoadingDocument:"+
this.WebProgress.isLoadingDocument);
MyExtension.WriteToDebug("WebProgress.DOMWindow:"+
this.WebProgress.DOMWindow);
//execute non load
//CurrentBrowser.OnNonLoad(CurrentURL);
}
}
}
catch(e){
MyExtension.WriteToDebug("Error Name:"+ e.name +" Message:"+
e.message);
}
}
};

//add progress listener
ThisBrowser.addProgressListener(progressListener);
//end setup progress listener


....just in case the code is to crazy to read in the post - here is a
link to a file:
http://samingrassia.com/_FILES/listener.js

https://developer.mozilla.org/en/nsIWebProgressListener


Thanks,

Sam