nsCOMPtr<nsIStreamListener> contentStreamListener; if (contentListener) {      if (contentListener != m_contentListener) {   nsLoadFlags loadFlags = 0; aChannel->GetLoadFlags(&loadFlags); loadFlags |= nsIChannel::LOAD_RETARGETED_DOCUMENT_URI; aChannel->SetLoadFlags(loadFlags); }  const char* contentTypeToUse; if (desiredContentType) contentTypeToUse = desiredContentType.get(); else contentTypeToUse = contentType.get();  PRBool bAbortProcess = PR_FALSE; rv = contentListener->DoContent(contentTypeToUse, mIsContentPreferred, request, getter_AddRefs(contentStreamListener), &bAbortProcess);       if (NS_FAILED(rv) || bAbortProcess) { return rv; } }  if (!contentStreamListener) {      nsCOMPtr<nsIExternalHelperAppService> helperAppService = do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv); if (helperAppService) { rv = helperAppService->DoContent(contentType.get(), request, m_originalContext, getter_AddRefs(contentStreamListener)); if (NS_SUCCEEDED(rv) && contentStreamListener) { m_targetStreamListener = contentStreamListener; return NS_OK; }
nsCOMPtr<nsIExternalHelperAppService> helperAppService = do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv); if (helperAppService) { rv = helperAppService->DoContent(mTargetType.get(), request, m_originalContext, getter_AddRefs(m_targetStreamListener)); if (NS_FAILED(rv)) { m_targetStreamListener = nsnull;
nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports * aCtxt){  nsresult rv;  nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);  if (!aChannel) {      return NS_ERROR_FAILURE;  }  nsCAutoString contentType;  rv = aChannel->GetContentType(contentType);  if (NS_FAILED(rv)) return rv;  // go to the uri dispatcher and give them our stuff...  nsCOMPtr<nsIURILoader> uriLoader;  uriLoader = do_GetService(NS_URI_LOADER_CONTRACTID, &rv);  if (NS_FAILED(rv)) {    return rv;  }  // Check whether the data should be forced to be handled externally.  This  // could happen because the Content-Disposition header is set so, or, in the  // future, because the user has specified external handling for the MIME  // type.  PRBool forceExternalHandling = PR_FALSE;  nsCAutoString disposition;  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));  if (httpChannel)  {    rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"),                                        disposition);  }  else  {    nsCOMPtr<nsIMultiPartChannel> multipartChannel(do_QueryInterface(request));    if (multipartChannel)    {      rv = multipartChannel->GetContentDisposition(disposition);    }  }  if (NS_SUCCEEDED(rv) && !disposition.IsEmpty())  {    nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);    if (NS_SUCCEEDED(rv))    {      nsAutoString dispToken;      // Get the disposition type      rv = mimehdrpar->GetParameter(disposition, "", NS_LITERAL_CSTRING(""),                                     PR_FALSE, nsnull, dispToken);      // RFC 2183, section 2.8 says that an unknown disposition      // value should be treated as "attachment"      if (NS_FAILED(rv) ||           (!dispToken.EqualsIgnoreCase("inline") &&          // Broken sites just send          // Content-Disposition: filename="file"          // without a disposition token... screen those out.           !dispToken.EqualsIgnoreCase("filename", 8)))        // We have a content-disposition of "attachment" or unknown        forceExternalHandling = PR_TRUE;    }  }      // We're going to try to find a contentListener that can handle our data  nsCOMPtr<nsIURIContentListener> contentListener;  // The type or data the contentListener wants.  nsXPIDLCString desiredContentType;  if (!forceExternalHandling)  {    //    // First step:  See if any nsIURIContentListener prefers to handle this    //              content type, passing m_contentListener as the first    //              listener to try.    //    PRBool abortDispatch = PR_FALSE;    rv = uriLoader->DispatchContent(contentType.get(),                                    mIsContentPreferred,                                     request, aCtxt,                                     m_contentListener,                                     m_originalContext,                                    getter_Copies(desiredContentType),                                     getter_AddRefs(contentListener),                                    &abortDispatch);      // if the uri loader says to abort the dispatch then someone    // else must have stepped in and taken over for us...so stop..    if (abortDispatch) return NS_OK;  }  //  // Second step:  If no listener prefers this type, see if any stream  //               decoders exist to transform this content type into  //               some other.  //  // We always want to do this, since even content being forced to  // be handled externally may need decoding (eg via the unknown  // content decoder).  // Don't do this if the server sent us a MIME type of "*/*" because they saw  // it in our Accept header and got confused.  // XXXbz have to be careful here; may end up in some sort of bizarre infinite  // decoding loop.  NS_NAMED_LITERAL_CSTRING(anyType, "*/*");  if (!contentListener && contentType != anyType)  {    ConvertData(request, contentType, anyType);        if (m_targetStreamListener) {      // We found a converter for this MIME type.  We'll just pump data into it      // and let the downstream nsDocumentOpenInfo handle things.      return NS_OK;    }  }  // Step 3:  //  // Now we try to get an actual downstream nsIStreamListener to give data to.  nsCOMPtr<nsIStreamListener> contentStreamListener;  if (contentListener)  {    // We need to first figure out if we are retargeting the load    // to a content listener that is different from the one that    // originated the request....if so, set    // LOAD_RETARGETED_DOCUMENT_URI on the channel.        if (contentListener != m_contentListener)    {      // we must be retargeting...so set an appropriate flag on      // the channel      nsLoadFlags loadFlags = 0;      aChannel->GetLoadFlags(&loadFlags);      loadFlags |= nsIChannel::LOAD_RETARGETED_DOCUMENT_URI;      aChannel->SetLoadFlags(loadFlags);    }    const char* contentTypeToUse;    if (desiredContentType)      contentTypeToUse = desiredContentType.get();    else      contentTypeToUse = contentType.get();    PRBool bAbortProcess = PR_FALSE;         rv = contentListener->DoContent(contentTypeToUse,                                    mIsContentPreferred,                                    request,                                    getter_AddRefs(contentStreamListener),                                    &bAbortProcess);    // Do not continue loading if nsIURIContentListener::DoContent(...)    // fails - It means that an unexpected error occurred...    //    // If bAbortProcess is TRUE then the listener is doing all the work from    // here...we are done!!!    if (NS_FAILED(rv) || bAbortProcess) {      return rv;    }  }  if (!contentStreamListener)  {    // Step 4:    //    // All attempts to dispatch this content have failed.  Just pass it off to    // the helper app service.    nsCOMPtr<nsIExternalHelperAppService> helperAppService =      do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv);    if (helperAppService)    {      rv = helperAppService->DoContent(contentType.get(),                                       request,                                       m_originalContext,                                       getter_AddRefs(contentStreamListener));      if (NS_SUCCEEDED(rv) && contentStreamListener) {        m_targetStreamListener = contentStreamListener;        return NS_OK;      }    }  }        if (!contentStreamListener) {    // Something failed somewhere.... Otherwise the helper app service would    // have taken over by now.    NS_ASSERTION(NS_FAILED(rv),                 "There is no way we should be successful at this point");    return rv;  }  if (desiredContentType.IsEmpty() ||      contentType == desiredContentType ||      contentType == anyType) {    // All set.  Just use this contentStreamListener    m_targetStreamListener = contentStreamListener;    return NS_OK;  }  // Now we have to convert.  Set m_contentListener to contentListener so that  // the downstream nsDocumentOpenInfo will try that listener first (since  // this contentListener expressed interest in handling the decoded version  // of this data).  m_contentListener = contentListener;    // OK, now bounce the data over to contentStreamListener.  rv = ConvertData(request, contentType, desiredContentType);  // Reinitialize our content listener in case this is a multipart stream --  // we wouldn't want to hand over a different part of the stream to the same  // content listener as wanted this part.  m_contentListener = do_GetInterface(m_originalContext);    return rv;}