request->SetLoadFlags(loadFlags);
nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports * aCtxt){  LOG(("[0x%p] nsDocumentOpenInfo::DispatchContent for type '%s'", this, mContentType.get()));  NS_PRECONDITION(!m_targetStreamListener,                  "Why do we already have a target stream listener?");    nsresult rv;  nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);  if (!aChannel) {    LOG_ERROR(("  Request is not a channel.  Bailing."));    return NS_ERROR_FAILURE;  }  NS_NAMED_LITERAL_CSTRING(anyType, "*/*");  if (mContentType.IsEmpty() || mContentType == anyType) {    rv = aChannel->GetContentType(mContentType);    if (NS_FAILED(rv)) return rv;    LOG(("  Got type from channel: '%s'", mContentType.get()));  }  // 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);    }  }  LOG(("  Disposition header: '%s'", disposition.get()));  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, "", EmptyCString(),                                     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.LowerCaseEqualsLiteral("inline") &&          // Broken sites just send          // Content-Disposition: filename="file"          // without a disposition token... screen those out.           !dispToken.EqualsIgnoreCase("filename", 8)) &&          // Also in use is Content-Disposition: name="file"           !dispToken.EqualsIgnoreCase("name", 4))        // We have a content-disposition of "attachment" or unknown        forceExternalHandling = PR_TRUE;    }  }  LOG(("  forceExternalHandling: %s", forceExternalHandling ? "yes" : "no"));      // 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 whether m_contentListener wants to handle this    // content type.    //    if (m_contentListener && TryContentListener(m_contentListener, aChannel)) {      LOG(("  Success!  Our default listener likes this type"));      // All done here      return NS_OK;    }    //    // Second step: See whether some other registered listener wants    // to handle this content type.    //    PRInt32 count = mURILoader->m_listeners.Count();    nsCOMPtr<nsIURIContentListener> listener;    for (PRInt32 i = 0; i < count; i++) {      listener = do_QueryReferent(mURILoader->m_listeners[i]);      if (listener) {        if (TryContentListener(listener, aChannel)) {          LOG(("  Found listener registered on the URILoader"));          return NS_OK;        }      } else {        // remove from the listener list, reset i and update count        mURILoader->m_listeners.RemoveObjectAt(i--);        --count;      }    }    //    // Third step: Try to find a content listener that has not yet had    // the chance to register, as it is contained in a not-yet-loaded    // module, but which has registered a contract ID.    //    nsCOMPtr<nsICategoryManager> catman =      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);    if (catman) {      nsXPIDLCString contractidString;      rv = catman->GetCategoryEntry(NS_CONTENT_LISTENER_CATEGORYMANAGER_ENTRY,                                    mContentType.get(),                                    getter_Copies(contractidString));      if (NS_SUCCEEDED(rv) && !contractidString.IsEmpty()) {        LOG(("  Listener contractid for '%s' is '%s'",             mContentType.get(), contractidString.get()));        listener = do_CreateInstance(contractidString);        LOG(("  Listener from category manager: 0x%p", listener.get()));                if (listener && TryContentListener(listener, aChannel)) {          LOG(("  Listener from category manager likes this type"));          return NS_OK;        }      }    }    //    // Fourth step: try to find an nsIContentHandler for our type.    //    nsCAutoString handlerContractID (NS_CONTENT_HANDLER_CONTRACTID_PREFIX);    handlerContractID += mContentType;    nsCOMPtr<nsIContentHandler> contentHandler =      do_CreateInstance(handlerContractID.get());    if (contentHandler) {      LOG(("  Content handler found"));      rv = contentHandler->HandleContent(mContentType.get(),                                         m_originalContext, request);      // XXXbz returning an error code to represent handling the      // content is just bizarre!      if (rv != NS_ERROR_WONT_HANDLE_CONTENT) {        if (NS_FAILED(rv)) {          // The content handler has unexpectedly failed.  Cancel the request          // just in case the handler didn't...          LOG(("  Content handler failed.  Aborting load"));          request->Cancel(rv);        }#ifdef PR_LOGGING        else {          LOG(("  Content handler taking over load"));        }#endif        return rv;      }    }  }  NS_ASSERTION(!m_targetStreamListener,               "If we found a listener, why are we not using it?");    //  // Fifth step:  If no listener prefers this type, see if any stream  //              converters 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.  if (mContentType != anyType) {    rv = ConvertData(request, m_contentListener, mContentType, anyType);    if (NS_FAILED(rv)) {      m_targetStreamListener = nsnull;    } else 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.      LOG(("  Converter taking over now"));      return NS_OK;    }  }        // Sixth step:  //  // 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) {    LOG(("  Passing load off to helper app service"));    rv = helperAppService->DoContent(mContentType,                                     request,                                     m_originalContext,                                     getter_AddRefs(m_targetStreamListener));    if (NS_FAILED(rv)) {      m_targetStreamListener = nsnull;    }  }        NS_ASSERTION(m_targetStreamListener || NS_FAILED(rv),               "There is no way we should be successful at this point without a m_targetStreamListener");  return rv;}