fix pop3 download of multiple msgs when quarantinging turned off and leave on server turned on, bug 713611, r=standard8
authorDavid Bienvenu <bienvenu@nventure.com>
Wed, 04 Jan 2012 13:30:29 -0800
changeset 10345 34489081da88f9d9a0c6cf0974ddc3862212b9f5
parent 10344 9eda40ffb503df34edc91891b7d22d4bf90a667c
child 10346 3e9df5c471859ff7cefc5b15581a217fdf5f5374
push id402
push userbugzilla@standard8.plus.com
push dateTue, 13 Mar 2012 21:17:18 +0000
treeherdercomm-beta@d080a8ebf16a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs713611
fix pop3 download of multiple msgs when quarantinging turned off and leave on server turned on, bug 713611, r=standard8
mailnews/local/src/nsMsgBrkMBoxStore.cpp
mailnews/local/test/unit/test_bug457168.js
mailnews/local/test/unit/test_pop3GetNewMail.js
mailnews/local/test/unit/test_pop3Password.js
mailnews/local/test/unit/test_pop3Password2.js
mailnews/local/test/unit/xpcshell.ini
mailnews/test/fakeserver/pop3d.js
--- a/mailnews/local/src/nsMsgBrkMBoxStore.cpp
+++ b/mailnews/local/src/nsMsgBrkMBoxStore.cpp
@@ -701,59 +701,64 @@ nsMsgBrkMBoxStore::GetNewMsgOutputStream
   *aReusable = true;
   nsCOMPtr<nsILocalFile> mboxFile;
   aFolder->GetFilePath(getter_AddRefs(mboxFile));
   nsCOMPtr<nsIMsgDatabase> db;
   aFolder->GetMsgDatabase(getter_AddRefs(db));
   if (!db && !*aNewMsgHdr)
     NS_WARNING("no db, and no message header");
   bool exists;
-  PRInt64 mboxSize = 0;
   mboxFile->Exists(&exists);
   if (!exists)
     mboxFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
-  else
-    mboxFile->GetFileSize(&mboxSize);
+
+  nsCString URI;
+  aFolder->GetURI(URI);
+  nsresult rv;
+  nsCOMPtr<nsISeekableStream> seekable;
+  if (m_outputStreams.Get(URI, aResult))
+  {
+    seekable = do_QueryInterface(*aResult, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
+    if (NS_FAILED(rv))
+    {
+      m_outputStreams.Remove(URI);
+      NS_RELEASE(*aResult);
+    }
+  }
+  if (!*aResult)
+  {
+    rv = MsgNewBufferedFileOutputStream(aResult, mboxFile,
+                                        PR_WRONLY | PR_CREATE_FILE, 00600);
+    NS_ASSERTION(NS_SUCCEEDED(rv), "failed opening offline store for output");
+    if (NS_FAILED(rv))
+      printf("failed opening offline store for %s\n", URI.get());
+    NS_ENSURE_SUCCESS(rv, rv);
+    seekable = do_QueryInterface(*aResult, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
+    NS_ENSURE_SUCCESS(rv, rv);
+    m_outputStreams.Put(URI, *aResult);
+  }
+  PRInt64 filePos;
+  seekable->Tell(&filePos);
   if (db && !*aNewMsgHdr)
   {
     // if mbox is close to 4GB, auto-assign the msg key.
-    nsMsgKey key = mboxSize > 0xFFFFFF00 ? nsMsgKey_None : (nsMsgKey) mboxSize;
+    nsMsgKey key = filePos > 0xFFFFFF00 ? nsMsgKey_None : (nsMsgKey) filePos;
     db->CreateNewHdr(key, aNewMsgHdr);
   }
   if (*aNewMsgHdr)
   {
     char storeToken[100];
-    PR_snprintf(storeToken, sizeof(storeToken), "%lld", mboxSize);
-    (*aNewMsgHdr)->SetMessageOffset(mboxSize);
+    PR_snprintf(storeToken, sizeof(storeToken), "%lld", filePos);
+    (*aNewMsgHdr)->SetMessageOffset(filePos);
     (*aNewMsgHdr)->SetStringProperty("storeToken", storeToken);
   }
-  nsCString URI;
-  aFolder->GetURI(URI);
-  nsresult rv;
-  if (m_outputStreams.Get(URI, aResult))
-  {
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
-    if (NS_SUCCEEDED(rv))
-      return NS_OK;
-    m_outputStreams.Remove(URI);
-    NS_RELEASE(*aResult);
-  }
-  rv = MsgNewBufferedFileOutputStream(aResult, mboxFile,
-                                      PR_WRONLY | PR_CREATE_FILE, 00600);
-  NS_ASSERTION(NS_SUCCEEDED(rv), "failed opening offline store for output");
-  if (NS_FAILED(rv))
-    printf("failed opening offline store for %s\n", URI.get());
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
-  NS_ENSURE_SUCCESS(rv, rv);
-  m_outputStreams.Put(URI, *aResult);
   return rv;
 }
 
 NS_IMETHODIMP
 nsMsgBrkMBoxStore::DiscardNewMessage(nsIOutputStream *aOutputStream,
                                      nsIMsgDBHdr *aNewHdr)
 {
   NS_ENSURE_ARG_POINTER(aOutputStream);
--- a/mailnews/local/test/unit/test_bug457168.js
+++ b/mailnews/local/test/unit/test_bug457168.js
@@ -9,18 +9,17 @@ var daemon;
 var incomingServer;
 var pop3Service;
 var firstTest = true;
 var thisTest;
 
 var tests = [
   { title: "Get New Mail, One Message",
     messages: [ "message2.eml", "message2.eml", "message3.eml" ],
-    transaction: [ "AUTH", "CAPA", "AUTH PLAIN", "STAT", "LIST",
-                   "UIDL", "XTND XLST Message-Id",
+    transaction: [ "AUTH", "CAPA", "AUTH PLAIN", "STAT", "LIST", "UIDL",
                    "RETR 1", "DELE 1", "RETR 2", "DELE 2", "RETR 3", "DELE 3" ] }
 ];
 
 var urlListener =
 {
   OnStartRunningUrl: function (url) {
   },
   OnStopRunningUrl: function (url, result) {
--- a/mailnews/local/test/unit/test_pop3GetNewMail.js
+++ b/mailnews/local/test/unit/test_pop3GetNewMail.js
@@ -15,18 +15,17 @@ var tests = [
     messages: [],
     transaction: [ "AUTH", "CAPA", "AUTH PLAIN", "STAT" ] },
   { title: "Get New Mail, No Messages 2",
     messages: [],
     transaction: [ "CAPA", "AUTH PLAIN", "STAT" ] },
   { title: "Get New Mail, One Message",
     messages: ["message1.eml"],
     transaction: [ "CAPA", "AUTH PLAIN", "STAT", "LIST",
-                   "UIDL", "XTND XLST Message-Id",
-                   "RETR 1", "DELE 1" ] }
+                   "UIDL", "RETR 1", "DELE 1" ] }
 ];
 
 var urlListener =
 {
   OnStartRunningUrl: function (url) {
   },
   OnStopRunningUrl: function (url, result) {
     try {
--- a/mailnews/local/test/unit/test_pop3Password.js
+++ b/mailnews/local/test/unit/test_pop3Password.js
@@ -9,18 +9,17 @@ var incomingServer;
 var pop3Service;
 var firstTest = true;
 var thisTest;
 
 var tests = [
   { title: "Get New Mail, One Message",
     messages: ["message1.eml"],
     transaction: [ "AUTH", "CAPA", "AUTH PLAIN", "STAT", "LIST",
-                   "UIDL", "XTND XLST Message-Id",
-                   "RETR 1", "DELE 1" ] }
+                   "UIDL", "RETR 1", "DELE 1" ] }
 ];
 
 var urlListener =
 {
   OnStartRunningUrl: function (url) {
   },
   OnStopRunningUrl: function (url, result) {
     try {
--- a/mailnews/local/test/unit/test_pop3Password2.js
+++ b/mailnews/local/test/unit/test_pop3Password2.js
@@ -11,18 +11,17 @@ var incomingServer;
 var pop3Service;
 var firstTest = true;
 var thisTest;
 
 var tests = [
   { title: "Get New Mail, One Message",
     messages: ["message1.eml"],
     transaction: [ "AUTH", "CAPA", "AUTH PLAIN", "STAT", "LIST",
-                   "UIDL", "XTND XLST Message-Id",
-                   "RETR 1", "DELE 1" ] }
+                   "UIDL", "RETR 1", "DELE 1" ] }
 ];
 
 var urlListener =
 {
   OnStartRunningUrl: function (url) {
   },
   OnStopRunningUrl: function (url, result) {
     try {
--- a/mailnews/local/test/unit/xpcshell.ini
+++ b/mailnews/local/test/unit/xpcshell.ini
@@ -7,16 +7,17 @@ tail = tail_local.js
 [test_localSubFolders.js]
 [test_mailboxContentLength.js]
 [test_mailboxProtocol.js]
 [test_msgCopy.js]
 [test_msgIDParsing.js]
 [test_over2GBMailboxes.js]
 [test_over4GBMailboxes.js]
 [test_pop3AuthMethods.js]
+[test_pop3Download.js]
 [test_pop3Duplicates.js]
 [test_pop3GSSAPIFail.js]
 [test_pop3GetNewMail.js]
 [test_pop3Password.js]
 [test_pop3Password2.js]
 [test_pop3Password3.js]
 [test_pop3PasswordFailure.js]
 [test_pop3PasswordFailure2.js]
--- a/mailnews/test/fakeserver/pop3d.js
+++ b/mailnews/test/fakeserver/pop3d.js
@@ -1,16 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /**
  * Contributors:
  *   Ben Bucksch <ben.bucksch beonex.com> <http://business.beonex.com> (RFC 5034 Authentication)
  */
 /* This file implements test POP3 servers
  */
 
+// Since we don't really need to worry about peristence, we can just
+// use a UIDL counter.
+var gUIDLCount = 1;
+
 function readFile(fileName) {
   var file = do_get_file("data/" + fileName, true); // allow nonexistent
   // also allow files from general locations
   if (!file || !file.exists())
     file = do_get_file(fileName);
 
   // If these fail, there is a problem with the test
   do_check_neq(file, null);
@@ -63,16 +67,17 @@ pop3Daemon.prototype = {
       // otherwise it's an object as dictionary already
       else
         this._messages.push(element);
     }
     messages.forEach(addMessage, this);
 
     for (var i = 0; i < this._messages.length; ++i) {
       this._messages[i].size = this._messages[i].fileData.length;
+      this._messages[i].uidl = "UIDL" + gUIDLCount++;
       this._totalMessageSize += this._messages[i].size;
     }
   },
   getTotalMessages: function() {
     return this._messages.length;
   },
   getTotalMessageSize: function() {
     return this._totalMessageSize;
@@ -146,16 +151,26 @@ POP3_RFC1939_handler.prototype = {
 
     var result = "+OK " + this._daemon._messages.length + " messages\r\n";
     for (var i = 0; i < this._daemon._messages.length; ++i)
       result += (i + 1) + " " + this._daemon._messages[i].size + "\r\n";
 
     result += ".";
     return result;
   },
+  UIDL: function (args) {
+    if (this._state != kStateTransaction)
+      return "-ERR invalid state";
+    let result = "+OK\r\n";
+    for (let i = 0; i < this._daemon._messages.length; ++i)
+      result += (i + 1) + " " + this._daemon._messages[i].uidl + "\r\n";
+
+    result += ".";
+    return result;
+  },
   RETR: function (args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
 
     var result = "+OK " + this._daemon._messages[args - 1].size + "\r\n";
     result += this._daemon._messages[args - 1].fileData;
     result += ".";
     return result;
@@ -207,17 +222,17 @@ POP3_RFC1939_handler.prototype = {
  * Not yet implemented, but desired are: TOP, UIDL, ...
  */
 function POP3_RFC2449_handler(daemon) {
   POP3_RFC1939_handler.call(this, daemon);
 }
 POP3_RFC2449_handler.prototype = {
   __proto__ : POP3_RFC1939_handler.prototype, // inherit
 
-  kCapabilities: [], // the test may adapt this as necessary
+  kCapabilities: ["UIDL"], // the test may adapt this as necessary
 
   CAPA: function (args) {
     var capa = "+OK List of our wanna-be capabilities follows:\r\n";
     for (var i = 0; i < this.kCapabilities.length; i++)
       capa += this.kCapabilities[i] + "\r\n";
     if (this.capaAdditions)
       capa += this.capaAdditions();
     capa += "IMPLEMENTATION fakeserver\r\n" + ".";