Bug 226890 - Thunderbird doesn't handle news URIs properly, part 8: Only initialize m_nntpServer once. r=Standard8
authorJoshua Cranmer <Pidgeot18@gmail.com>
Fri, 31 Dec 2010 20:21:23 -0500
changeset 8059 b3944d5783fc
parent 8058 8e5dde6eb307
child 8060 7f1d82e03723
push id6200
push userPidgeot18@gmail.com
push date2011-07-05 21:41 +0000
treeherdercomm-central@7f1d82e03723 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs226890
Bug 226890 - Thunderbird doesn't handle news URIs properly, part 8: Only initialize m_nntpServer once. r=Standard8
mailnews/news/src/nsNNTPProtocol.cpp
mailnews/news/src/nsNNTPProtocol.h
mailnews/news/src/nsNntpIncomingServer.cpp
--- a/mailnews/news/src/nsNNTPProtocol.cpp
+++ b/mailnews/news/src/nsNNTPProtocol.cpp
@@ -298,18 +298,20 @@ NS_IMPL_ADDREF_INHERITED(nsNNTPProtocol,
 NS_IMPL_RELEASE_INHERITED(nsNNTPProtocol, nsMsgProtocol)
 
 NS_INTERFACE_MAP_BEGIN(nsNNTPProtocol)
   NS_INTERFACE_MAP_ENTRY(nsINNTPProtocol)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsICacheListener)
 NS_INTERFACE_MAP_END_INHERITING(nsMsgProtocol)
 
-nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
-: nsMsgProtocol(aURL)
+nsNNTPProtocol::nsNNTPProtocol(nsINntpIncomingServer *aServer, nsIURI *aURL,
+                               nsIMsgWindow *aMsgWindow)
+: nsMsgProtocol(aURL),
+  m_nntpServer(aServer)
 {
   if (!NNTP)
     NNTP = PR_NewLogModule("NNTP");
 
   m_ProxyServer = nsnull;
   m_lineStreamBuffer = nsnull;
   m_responseText = nsnull;
   m_dataBuf = nsnull;
@@ -369,40 +371,17 @@ NS_IMETHODIMP nsNNTPProtocol::Initialize
 {
   nsresult rv = NS_OK;
 
   if (aMsgWindow) {
     m_msgWindow = aMsgWindow;
   }
   nsMsgProtocol::InitFromURI(aURL);
 
-  nsCAutoString userPass;
-  rv = m_url->GetUserPass(userPass);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCAutoString hostName;
-  rv = m_url->GetAsciiHost(hostName);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCString unescapedUserPass;
-  MsgUnescapeString(userPass, 0, unescapedUserPass);
-
-  // find the server
-  nsCOMPtr<nsIMsgIncomingServer> server;
-  rv = accountManager->FindServer(unescapedUserPass, hostName, NS_LITERAL_CSTRING("nntp"),
-    getter_AddRefs(server));
-  NS_ENSURE_SUCCESS(rv, NS_MSG_INVALID_OR_MISSING_SERVER);
-  if (!server) return NS_MSG_INVALID_OR_MISSING_SERVER;
-
-  m_nntpServer = do_QueryInterface(server, &rv);
-  NS_ENSURE_SUCCESS(rv, NS_MSG_INVALID_OR_MISSING_SERVER);
-  if (!m_nntpServer) return NS_MSG_INVALID_OR_MISSING_SERVER;
+  nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_nntpServer);
 
   rv = m_nntpServer->GetMaxArticles(&m_maxArticles);
   NS_ENSURE_SUCCESS(rv,rv);
 
   PRInt32 socketType;
   rv = server->GetSocketType(&socketType);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -483,26 +462,28 @@ NS_IMETHODIMP nsNNTPProtocol::Initialize
     nsCOMPtr<nsIInterfaceRequestor> ir;
     if (socketType != nsMsgSocketType::plain && aMsgWindow)
     {
       nsCOMPtr<nsIDocShell> docShell;
       aMsgWindow->GetRootDocShell(getter_AddRefs(docShell));
       ir = do_QueryInterface(docShell);
     }
 
-    PR_LOG(NNTP,PR_LOG_ALWAYS,("(%p) opening connection to %s on port %d",this, hostName.get(), port));
     // call base class to set up the transport
 
     PRInt32 port = 0;
     nsCString hostName;
     m_url->GetPort(&port);
 
     rv = server->GetRealHostName(hostName);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    PR_LOG(NNTP, PR_LOG_ALWAYS, ("(%p) opening connection to %s on port %d",
+      this, hostName.get(), port));
+
     nsCOMPtr<nsIProxyInfo> proxyInfo;
     rv = MsgExamineForProxy("nntp", hostName.get(), port, getter_AddRefs(proxyInfo));
     if (NS_FAILED(rv)) proxyInfo = nsnull;
 
     rv = OpenNetworkSocketWithInfo(hostName.get(), port,
            (socketType == nsMsgSocketType::SSL) ? "ssl" : nsnull,
            proxyInfo, ir);
 
@@ -1257,16 +1238,19 @@ nsNNTPProtocol::ParseURL(nsIURI *aURL, n
     nsresult rv;
     nsCOMPtr <nsIMsgFolder> folder;
     nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv,rv);
 
     nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(m_runningURL, &rv);
     NS_ENSURE_SUCCESS(rv,rv);
 
+    nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(msgUrl, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     nsCString spec;
     rv = msgUrl->GetOriginalSpec(getter_Copies(spec));
     NS_ENSURE_SUCCESS(rv,rv);
 
     // if the original spec is non empty, use it to determine m_newsFolder and m_key
     if (!spec.IsEmpty()) {
         PR_LOG(NNTP,PR_LOG_ALWAYS,("(%p) original message spec = %s",this,spec.get()));
 
@@ -1297,76 +1281,38 @@ nsNNTPProtocol::ParseURL(nsIURI *aURL, n
 
   NS_ASSERTION(aMessageID.IsEmpty() || aMessageID != aGroup, "something not null");
 
   // If we are cancelling, we've got our message id, m_key, and m_newsFolder.
   // Bail out now to prevent messing those up.
   if (m_newsAction == nsINntpUrl::ActionCancelArticle)
     return NS_OK;
 
-  nsCAutoString serverURI;
-
-  if (!aMessageID.IsEmpty())
-  {
-    // if this is a message id, use the pre path (the server) for the folder uri.
-    rv = aURL->GetPrePath(serverURI);
-    NS_ENSURE_SUCCESS(rv,rv);
-  }
-  else if (!aGroup.IsEmpty())
+  rv = m_runningURL->GetKey(&m_key);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Check if the key is in the local cache.
+  // It's possible that we're have a server/group/key combo that doesn't exist
+  // (think nntp://server/group/key), so not having the folder isn't a bad
+  // thing.
+  if (m_key != nsMsgKey_None)
   {
-    if (aGroup.Find("*") >= 0) {
-      rv = aURL->GetPrePath(serverURI);
-      NS_ENSURE_SUCCESS(rv,rv);
-    }
-    else {
-      // let if fall through.  we'll set m_newsFolder later.
-    }
-  }
-
-  if (!serverURI.IsEmpty()) {
-    // if we get here, we, we are either doing:
-    // news://host/message-id or news://host/*
-    // (but not news://host/message-id?cancel)
-    // for authentication, we set m_newsFolder to be the server's folder.
-    // while we are here, we set m_nntpServer.
-
-    if (!aMessageID.IsEmpty())
-    { // for news://host/message-id decompose complete url
-      nsCAutoString urlSpec;
-      m_url->GetAsciiSpec(urlSpec);
-      rv = nntpService->DecomposeNewsURI(urlSpec.get(), getter_AddRefs(folder), &m_key);
-    }
-    if (aMessageID.IsEmpty() || NS_FAILED(rv))
-    { // for news://host/* decompose only server uri
-      rv = nntpService->DecomposeNewsURI(serverURI.get(), getter_AddRefs(folder), &m_key);
-      NS_ENSURE_SUCCESS(rv,rv);
-    }
-
-
-    if (m_key != nsMsgKey_None)
+    rv = mailnewsUrl->GetFolder(getter_AddRefs(folder));
+    m_newsFolder = do_QueryInterface(folder);
+
+    if (NS_SUCCEEDED(rv) && m_newsFolder)
     {
-      // check if message is in local cache
       PRBool useLocalCache = PR_FALSE;
       rv = folder->HasMsgOffline(m_key, &useLocalCache);
       NS_ENSURE_SUCCESS(rv,rv);
 
       // set message is in local cache
-      nsCOMPtr <nsIMsgMailNewsUrl> newsURL = do_QueryInterface(m_url);
-      rv = newsURL->SetMsgIsInLocalCache(useLocalCache);
+      rv = mailnewsUrl->SetMsgIsInLocalCache(useLocalCache);
       NS_ENSURE_SUCCESS(rv,rv);
     }
-
-    // since we are reading a message in this folder, we can set m_newsFolder
-    m_newsFolder = do_QueryInterface(folder, &rv);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    rv = m_newsFolder->GetNntpServer(getter_AddRefs(m_nntpServer));
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    m_currentGroup.Truncate();
   }
 
   return NS_OK;
 }
 /*
  * Writes the data contained in dataBuffer into the current output stream. It also informs
  * the transport layer that this data is now available for transmission.
  * Returns a positive number for success, 0 for failure (not all the bytes were written to the
--- a/mailnews/news/src/nsNNTPProtocol.h
+++ b/mailnews/news/src/nsNNTPProtocol.h
@@ -156,19 +156,20 @@ class nsNNTPProtocol : public nsINNTPPro
 public:
   NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSINNTPPROTOCOL
     NS_DECL_NSICACHELISTENER
 
     // nsITimerCallback interfaces
     NS_DECL_NSITIMERCALLBACK
 
-    // Creating a protocol instance requires the URL
-    // need to call Initialize after we do a new of nsNNTPProtocol
-    nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow);
+  // Creating a protocol instance requires the URL
+  // need to call Initialize after we do a new of nsNNTPProtocol
+  nsNNTPProtocol(nsINntpIncomingServer *aServer, nsIURI *aURL,
+                 nsIMsgWindow *aMsgWindow);
   virtual ~nsNNTPProtocol();
 
   // stop binding is a "notification" informing us that the stream associated with aURL is going away.
   NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports * aCtxt, nsresult aStatus);
 
   char * m_ProxyServer;    /* proxy server hostname */
 
   NS_IMETHOD Cancel(nsresult status);  // handle stop button
--- a/mailnews/news/src/nsNntpIncomingServer.cpp
+++ b/mailnews/news/src/nsNntpIncomingServer.cpp
@@ -507,17 +507,17 @@ nsNntpIncomingServer::ConnectionTimeOut(
 nsresult
 nsNntpIncomingServer::CreateProtocolInstance(nsINNTPProtocol ** aNntpConnection, nsIURI *url,
                                              nsIMsgWindow *aMsgWindow)
 {
   // create a new connection and add it to the connection cache
   // we may need to flag the protocol connection as busy so we don't get
   // a race
   // condition where someone else goes through this code
-  nsNNTPProtocol * protocolInstance = new nsNNTPProtocol(url, aMsgWindow);
+  nsNNTPProtocol *protocolInstance = new nsNNTPProtocol(this, url, aMsgWindow);
   if (!protocolInstance)
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsresult rv = protocolInstance->QueryInterface(NS_GET_IID(nsINNTPProtocol), (void **) aNntpConnection);
   // take the protocol instance and add it to the connectionCache
   if (NS_SUCCEEDED(rv) && *aNntpConnection)
     mConnectionCache.AppendObject(*aNntpConnection);
   return rv;