Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1902|回复: 4
打印 上一主题 下一主题

大附件邮件发送流程

[复制链接]

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
跳转到指定楼层
楼主
发表于 2016-4-21 00:01:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
  1. 正常发信流程://发送邮件
  2. MsgComposeCommands.js
  3. function GenericSendMessage_Ori(msgType,spicc)
  4. {
  5. gMsgCompose.SendMsg(msgType, getCurrentIdentity(),
  6.             getCurrentAccountKey(), msgWindow, progress);

  7. }nsMsgCompose.cpp
  8. NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity, const char *accountKey, nsIMsgWindow *aMsgWindow, nsIMsgProgress *progress)
  9. {
  10. //打开进度窗口
  11. mProgress->OpenProgressDialog(m_window, aMsgWindow,
  12.                                         "chrome://messenger/content/messengercompose/sendProgress.xul",
  13.                                         false, params);


  14. rv = _SendMsg(deliverMode, identity, accountKey, entityConversionDone);
  15. }

  16. nsresult nsMsgCompose::_SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity,
  17.                                 const char *accountKey, bool entityConversionDone)
  18. { // Create the listener for the send operation...
  19.       nsCOMPtr<nsIMsgComposeSendListener> composeSendListener = do_CreateInstance(NS_MSGCOMPOSESENDLISTENER_CONTRACTID);

  20. nsCOMPtr<nsIMsgSend>                      mMsgSend;           // for composition back end
  21. mMsgSend = do_CreateInstance(NS_MSGSEND_CONTRACTID);
  22. ...
  23. #define NS_MSGCOMPOSESENDLISTENER_CONTRACTID \   "@mozilla.org/messengercompose/composesendlistener;1"// Create the listener for the send operation...  创建发送监听
  24.       nsCOMPtr<nsIMsgComposeSendListener> composeSendListener = do_CreateInstance(NS_MSGCOMPOSESENDLISTENER_CONTRACTID);

  25. nsCOMPtr<nsIMsgSendListener> sendListener = do_QueryInterface(composeSendListener);   
  26. //对应的实现类 class nsMsgComposeSendListener : public nsIMsgComposeSendListener, public nsIMsgSendListener, public nsIMsgCopyServiceListener, public nsIWebProgressListener

  27.       rv = mMsgSend->CreateAndSendMessage(
  28.                     m_composeHTML ? m_editor.get() : nullptr,
  29.                     identity,
  30.                     accountKey,
  31.                     m_compFields,
  32.                     false,                           // bool                              digest_p,
  33.                     false,                           // bool                              dont_deliver_p,
  34.                     (nsMsgDeliverMode)deliverMode,      // nsMsgDeliverMode                  mode,
  35.                     nullptr,                             // nsIMsgDBHdr                       *msgToReplace,
  36.                     m_composeHTML?TEXT_HTML:TEXT_PLAIN, // const char                        *attachment1_type,
  37.                     bodyString,                         // const char                        *attachment1_body,
  38.                     bodyLength,                         // uint32_t                          attachment1_body_length,
  39.                     nullptr,                             // nsIArray  *attachments,
  40.                     nullptr,                             // nsIArray preloaded_attachments,
  41.                     m_window,                           // nsIDOMWindow                      *parentWindow;
  42.                     mProgress,                          // nsIMsgProgress                    *progress,
  43.                     sendListener,                       // listener
  44.                     mSmtpPassword.get(),
  45.                     mOriginalMsgURI,
  46.                     mType);


  47. }
  48. nsMsgSend.cpp
  49. nsMsgComposeAndSend::CreateAndSendMessage(..

  50. }
  51. nsMsgComposeAndSend::Init(
  52.               nsIMsgIdentity  *aUserIdentity,
  53. {
  54. return HackAttachments(attachments, preloaded_attachments);
  55. }
  56. nsMsgComposeAndSend::HackAttachments(nsIArray *attachments,
  57.                                      nsIArray *preloadedAttachments)
  58. {AddCompFieldLocalAttachments(); //本地文件处理

  59. if (m_attachment_count > 0){
  60. for (i = 0; i < m_attachment_count; i++) //循环处理附件
  61. {
  62. //正在附加 [附件名]
  63. nsresult status = m_attachments.SnarfAttachment(mCompFields);  //临时文件 nsmail.tmp
  64. }
  65. }
  66. return GatherMimeAttachments();
  67. }

  68. nsMsgComposeAndSend::AddCompFieldLocalAttachments()
  69. {
  70. //云传输判断
  71. // Just look for local file:// attachments and do the right thing. 是否本机上的文件判断
  72.         if (nsMsgIsLocalFile(url.get()))
  73.   {
  74. attachment->GetContentType(getter_Copies(m_attachments[newLoc].m_type));  获取文件类型 后缀等
  75. 文件类型不为空,m_attachments[newLoc].m_done = true;
  76. mimeFinder->GetTypeFromExtension(fileExt, type);     根据文件后缀重新获取mime支持的类型
  77. m_attachments[newLoc].m_type = type;  只有支持的类型 m_done才为ture.
  78.   }

  79. }
  80. nsExternalHelperAppService.cpp

  81. NS_IMETHODIMP nsExternalHelperAppService::GetTypeFromExtension(const nsACString& aFileExt, nsACString& aContentType)
  82. {
  83. }

  84. nsMsgComposeAndSend::GatherMimeAttachments()
  85. {
  86. //产生临时文件 nsemail.html  
  87. if (m_dont_deliver_p && mListener)
  88.   {
  89.     // Need to ditch the file spec here so that we don't delete the
  90.     // file, since in this case, the caller wants the file
  91.     //
  92.     mReturnFile = mTempFile;
  93.     mTempFile = nullptr;
  94.     if (!mReturnFile)
  95.       NotifyListenerOnStopSending(nullptr, NS_ERROR_OUT_OF_MEMORY, nullptr, nullptr);
  96.     else
  97.     {
  98.       NotifyListenerOnStopSending(nullptr, NS_OK, nullptr, mReturnFile);
  99.     }
  100.   }
  101.   else
  102.   {
  103.     status = DeliverMessage();
  104.     if (NS_SUCCEEDED(status))
  105.       shouldDeleteDeliveryState = false;
  106.   }

  107. }

  108. nsMsgSend.cpp
  109. nsMsgComposeAndSend:: DeliverMessage()
  110. {
  111. return SendToMagicFolder(m_deliver_mode);  //存草稿 模板调用这个过程,直接对相应邮件夹追加文件

  112. return DeliverFileAsMail(); //邮件发送调用这个
  113. }nsMsgComposeAndSend:: DeliverFileAsMail()
  114. {
  115. nsCOMPtr<nsISmtpService> smtpService(do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv));
  116.   if (NS_SUCCEEDED(rv) && smtpService)
  117.   {
  118. MsgDeliveryListener *deliveryListener = new MsgDeliveryListener(this, false);  //邮件发送时,创建用于回调的监听,已对已发送的邮件进行拷贝到已发送
  119. rv = smtpService->SendMailMessage(mTempFile, buf, mUserIdentity,
  120.                                       mSmtpPassword.get(), deliveryListener, msgStatus,
  121.                                       callbacks, mCompFields->GetDSN(),
  122.                                       getter_AddRefs(runningUrl),
  123.                                       getter_AddRefs(mRunningRequest));
  124. }
  125. }

  126. NS_IMETHODIMP MsgDeliveryListener::OnStopRunningUrl(nsIURI *url, nsresult aExitCode)
  127. {
  128. mMsgSend->SendDeliveryCallback(url, mIsNewsDelivery, aExitCode);
  129. }

  130. NS_IMETHODIMP nsMsgComposeAndSend::SendDeliveryCallback(nsIURI *aUrl, bool inIsNewsDelivery, nsresult aExitCode)
  131. {
  132. DeliverAsMailExit(aUrl, aExitCode);
  133. }

  134. nsMsgComposeAndSend::DeliverAsMailExit(nsIURI *aUrl, nsresult aExitCode)
  135. {
  136.   DoDeliveryExitProcessing(aUrl, aExitCode, false);
  137.   return NS_OK;
  138. }

  139. NS_IMETHODIMP
  140. nsMsgComposeAndSend::DeliverAsNewsExit(nsIURI *aUrl, nsresult aExitCode)
  141. {
  142.   DoDeliveryExitProcessing(aUrl, aExitCode, mSendMailAlso);
  143.   return NS_OK;
  144. }

  145. nsMsgComposeAndSend::DoDeliveryExitProcessing(nsIURI * aUri, nsresult aExitCode, bool aCheckForMail)
  146. {
  147. DoFcc();
  148. }

  149. nsresult nsMsgComposeAndSend::DoFcc() // Now, start the appropriate copy operation.
  150. {
  151. nsresult rv = MimeDoFCC(mTempFile,
  152.                           nsMsgDeliverNow,
  153.                           mCompFields->GetBcc(),
  154.                           mCompFields->GetFcc(),
  155.                           mCompFields->GetNewspostUrl());
  156. }

  157. ///////////////////////////特定邮件夹,还是正常发送后,追加到已发送 的具体调用过程//////
  158. nsMsgSend.cpp
  159. nsMsgComposeAndSend::MimeDoFCC(nsIFile          *input_file,..
  160. {
  161. status = StartMessageCopyOperation(mCopyFile, mode, turi);
  162. }
  163. nsMsgComposeAndSend::StartMessageCopyOperation(nsIFile          *aFile,...
  164. {
  165.   rv = mCopyObj->StartCopyOperation(mUserIdentity, aFile, mode,
  166.                                     this, m_folderName.get(), mMsgToReplace);

  167. }

  168. nsMsgCopy.cpp
  169. nsMsgCopy::StartCopyOperation(nsIMsgIdentity       *aUserIdentity,...
  170. {
  171.   rv = DoCopy(aFile, dstFolder, aMsgToReplace, isDraft, msgWindow, aMsgSendObj);
  172. }

  173. nsMsgCopy::DoCopy(nsIFile *aDiskFile, nsIMsgFolder *dstFolder,...
  174. {
  175. rv = copyService->CopyFileMessage(aDiskFile, dstFolder, aMsgToReplace,...
  176. }


  177. nsMsgCopyService.cpp
  178. nsMsgCopyService:: CopyFileMessage(nsIFile* file,...
  179. {
  180. copyRequest = new nsCopyRequest();
  181. rv = copyRequest->Init(nsCopyFileMessageType, fileSupport, dstFolder,...
  182. rv = DoCopy(copyRequest);
  183. }

  184. nsMsgCopyService:: DoCopy(nsCopyRequest* aRequest)
  185. {
  186. m_copyRequests.AppendElement(aRequest);
  187. LogCopyRequest(copyImmediately ? "DoCopy" : "QueueRequest", aRequest); if (copyImmediately)
  188.     return DoNextCopy();
  189. }

  190. void nsMsgCopyService:: LogCopyRequest(const char *logMsg, nsCopyRequest* aRequest)
  191. {
  192. PR_LOG(gCopyServiceLog, PR_LOG_ALWAYS,
  193.          ("request %lx %s - src %s dest %s numItems %d type=%d",
  194.          aRequest, logMsg, srcFolderUri.get(),
  195.          destFolderUri.get(), numMsgs, aRequest->m_requestType));

  196. //request 8930788 DoCopy - src  dest imap://hechengjin@imap.richinfo.cn/&XfJT0ZAB- numItems 0 type=1
  197. }
  198. nsMsgCopyService::DoNextCopy()
  199. {
  200. rv = copyRequest->m_dstFolder->CopyMessages
  201.                   (copySource->m_msgFolder, copySource->m_messageArray,...)

  202. rv = copyRequest->m_dstFolder->CopyFileMessage(...)
  203. }


  204. nsImapMailFolder.cpp
  205. nsImapMailFolder::CopyFileMessage(nsIFile* file,
  206. {
  207. rv = imapService->AppendMessageFromFile(file, this, messageId,...)
  208. }

  209. nsImapService.cpp
  210. NS_IMETHODIMP nsImapService::AppendMessageFromFile(nsIFile *aFile,..
  211. {if (inSelectedState)
  212.     urlSpec.Append("/appenddraftfromfile>");
  213. else
  214.     urlSpec.Append("/appendmsgfromfile>");
  215. ///// imap://hechengjin88@imap.126.com:143/appendmsgfromfile%3E/%26XfJT0ZAB-
  216. rv = GetImapConnectionAndLoadUrl(imapUrl, nullptr, aURL);
  217. }
  218. nsresult nsImapService::GetImapConnectionAndLoadUrl(nsIImapUrl *aImapUrl,
  219. {
  220. rv = aImapServer->GetImapConnectionAndLoadUrl(aImapUrl, aConsumer);
  221. }
  222. nsImapIncomingServer.cpp
  223. nsImapIncomingServer:: GetImapConnectionAndLoadUrl(nsIImapUrl* aImapUrl,..)
  224. {
  225. rv = aProtocol->LoadImapUrl(mailnewsurl, aConsumer);
  226. }
  227. nsImapProtocol.cpp
  228. NS_IMETHODIMP nsImapProtocol:: LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer)
  229. {
  230. rv = SetupWithUrl(aURL, aConsumer);
  231. }
  232. nsresult nsImapProtocol:: SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer) //设置队列中下个要运行的URL
  233. {
  234. m_runningUrl = do_QueryInterface(aURL, &rv);
  235. }


  236. // NOTE: Though we cleared m_nextUrlReadyToRun above, it may have been
  237.       //       set by LoadImapUrl, which runs on the main thread.  Because of this,
  238.       //       we must not try to clear m_nextUrlReadyToRun here.

  239. 即 LoadImapUrl 可以设置imap线程中处理的url
  240. nsImapProtocol::ImapThreadMainLoop()
  241. {if (readyToRun && m_runningUrl)
  242.     {
  243. ProcessCurrentURL()
  244. }
  245. }

  246. bool nsImapProtocol:: ProcessCurrentURL()
  247. {
  248. if (imapState == nsIImapUrl::nsImapAuthenticatedState)
  249.       ProcessAuthenticatedStateURL();
  250.     else   // must be a url that requires us to be in the selected state
  251.       ProcessSelectedStateURL();
  252. }
  253. void nsImapProtocol:: ProcessAuthenticatedStateURL()  //走这个
  254. {
  255. case nsIImapUrl::nsImapAppendMsgFromFile:
  256.       OnAppendMsgFromFile();
  257. }

  258. void nsImapProtocol:: OnAppendMsgFromFile()
  259. {
  260. UploadMessageFromFile(file, mailboxName, date, flagsToSet, keywords);
  261. }

  262. void nsImapProtocol:: UploadMessageFromFile (..)
  263. {
  264.   command.Append(" append \"");
  265. }







复制代码
回复

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
沙发
 楼主| 发表于 2016-4-21 00:01:36 | 只看该作者
sendProgress.xul
sendProgress.js

正在附加 [附件名]   Attaching %s...
正在传递邮件…
发送邮件失败
SetStatusMessage(nsDependentString(printfString));  4652   nsMsgComposeAndSend::MimeDoFCC(nsIFile     正在复制邮件到 草稿箱 邮件夹…

保存邮件到 草稿箱 时出错   

复制失败。


--点 取消
邮件正在发送中,您确定要取消发送该邮件   ---确认过程去掉,在确认的过程中邮件还在发送,直接不用确认,就停止发送


"C:\Documents and Settings\hecj\Local Settings\Temp\" *.eml
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
板凳
 楼主| 发表于 2016-4-21 00:01:52 | 只看该作者
static nsExtraMimeTypeEntry extraMimeEntries [] =
437 {
438 #if defined(VMS)
439   { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File" },
440 #elif defined(XP_MACOSX) // don't define .bin on the mac...use internet config to look that up...
441   { APPLICATION_OCTET_STREAM, "exe,com", "Binary File" },
442 #else
443   { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File" },
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
地板
 楼主| 发表于 2016-4-21 00:02:12 | 只看该作者
重复弹出附加 附件原因 (js的调用)




MsgComposeCommands.js

var gSendListener = {
onStopSending: function (aMsgID, aStatus, aMsg, aReturnFile) {
if (aStatus == 0x80004004) //取消发送不保存草稿,否则在大附件附加过程中点取消,会一直循环提示附加
        {
            //SaveAsDraft();

}}

function ComposeStartup(recycled, aParams)
{

gMsgCompose.addMsgSendListener(gSendListener);
}

function ComposeUnload()
{

if (gMsgCompose)
    gMsgCompose.removeMsgSendListener(gSendListener);


}
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
5#
 楼主| 发表于 2016-4-21 00:02:57 | 只看该作者
NS_IMETHODIMP nsMsgComposeSendListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
{
if (bCanceled)
        {
          progress->OnStatusChange(nullptr, nullptr, NS_OK, msg.get()); //正在取消…
        }
        
         msgSend->Abort();
}

nsresult nsMsgComposeSendListener::OnStopSending(const char *aMsgID, nsresult aStatus,
                                                 const PRUnichar *aMsg, nsIFile *returnFile)
{
}

nsresult nsMsgCompose::_SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity,
                                const char *accountKey, bool entityConversionDone)
{
if (mProgress)
      {
        nsCOMPtr<nsIWebProgressListener> progressListener = do_QueryInterface(composeSendListener);
        mProgress->RegisterListener(progressListener);
      }
}
nsMsgProgress.cpp
NS_IMETHODIMP nsMsgProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
{
}
NS_IMETHODIMP nsMsgProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
{
}

/* void RegisterListener (in nsIWebProgressListener listener); */
NS_IMETHODIMP nsMsgProgress::RegisterListener(nsIWebProgressListener * listener)
{
}
请确认您的邮件帐户设置是否正确,然后重试 \mailnews\compose\src\nsMsgSendReport.cpp
        if( currError != 2147500036 ) //手动取消附件附加的情况判断,这里不再提示 账号设置相关
        nsMsgDisplayMessageByString(prompt, currMessage.get(), dialogTitle.get());
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-5-4 15:58 , Processed in 0.063013 second(s), 21 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表