|
沙发
楼主 |
发表于 2016-3-27 23:24:39
|
只看该作者
- --------pop3验证底层实现-------
- nsPop3IncomingServer.cpp
- NS_IMETHODIMP nsPop3IncomingServer::VerifyLogon(nsIUrlListener *aUrlListener,nsIMsgWindow *aMsgWindow, nsIURI **aURL)
- {
- nsresult rv;
- nsCOMPtr<nsIPop3Service> pop3Service = do_GetService(kCPop3ServiceCID, &rv);
- NS_ENSURE_SUCCESS(rv,rv);
- return pop3Service->VerifyLogon(this, aUrlListener, aMsgWindow, aURL);
- }
- nsPop3Service.cpp
- NS_IMETHODIMP nsPop3Service::VerifyLogon(nsIMsgIncomingServer *aServer,...
- {
- //根据pop3收信服务器的前端设置(用户名[进行编码防止含有 / % @]、主机名、端口)构造url
- char *urlSpec = PR_smprintf("pop3://%s@%s:%d/?verifyLogon", escapedUsername.get(), popHost.get(), popPort);
- ////pop3://13342978053@pop3.139.com:110/?verifyLogon
- //构造url接口智能指针 nsIURI
- nsCOMPtr<nsIURI> url; //参考下面 url构建做了什么
- rv = BuildPop3Url(urlSpec, nullptr, popServer, aUrlListener, getter_AddRefs(url), aMsgWindow);
- //运行url
- rv = RunPopUrl(aServer, url);
- }
- RunPopUrl
- {
- 1.获取pop收信服务器配置的用户名
- nsresult rv = aServer->GetRealUsername(userName);
- 2.判断收信服务是否在忙
- rv = aServer->GetServerBusy(&serverBusy); //参考下面 服务是否在忙做了什么
- a.忙,弹出提示
- nsCOMPtr<nsIMsgMailNewsUrl> url = do_QueryInterface(aUrlToRun);
- if (url)
- AlertServerBusy(url);
- b.不忙进行如下执行
- nsRefPtr<nsPop3Protocol> protocol = new nsPop3Protocol(aUrlToRun); //参看下面的关于nsPop3Protocol类
- //设置用户名
- protocol->SetUsername(userName.get());
- //加载url //参看下面的关于nsPop3Protocol类中加载Url
- rv = protocol->LoadUrl(aUrlToRun);
- //设置收取邮件数
- protocol->SetNumForRETR(aNumForRETR);
- }
- ****url构建做了什么*************
- url中有一个指向pop3sink的指针m_pop3Sink
- nsresult nsPop3Service::BuildPop3Url()
- {
- nsPop3Sink *pop3Sink = new nsPop3Sink(); //nsIPop3Sink
- pop3Sink->SetPopServer(server);
- pop3Sink->SetFolder(inbox);
- //创建pop3Url
- nsCOMPtr<nsIPop3URL> pop3Url = do_CreateInstance(kPop3UrlCID, &rv);
- pop3Url->SetPop3Sink(pop3Sink); //m_pop3Sink = aPop3Sink;
- nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(pop3Url);
- //前端传入的侦听器在这里注册
- mailnewsurl->RegisterListener(aUrlListener);
- {
- nsMsgMailNewsUrl::RegisterListener mUrlListeners.AppendElement(aUrlListener);
- nsMsgMailNewsUrl.cpp文件中使用 NOTIFY_URL_LISTENERS(propertyfunc_, params_) 发出侦听通知
- }
- ****************
- ****服务是否在忙做了什么******
- NS_IMETHODIMP nsMsgIncomingServer::GetServerBusy(bool * aServerBusy)
- {
- NS_ENSURE_ARG_POINTER(aServerBusy);
- *aServerBusy = m_serverBusy;
- return NS_OK;
- }
- //主要看什么时候设置了忙状态
- NS_IMETHODIMP nsMsgIncomingServer::SetServerBusy(bool aServerBusy)
- {
- m_serverBusy = aServerBusy;
- return NS_OK;
- }
- ***************************
- ************关于nsPop3Protocol类******nsPop3Protocol.cpp
- class nsPop3Protocol : public nsMsgProtocol,
- public nsIPop3Protocol,
- public nsIMsgAsyncPromptListener
- { ...}
- nsresult nsPop3Protocol:oadUrl(nsIURI* aURL..)
- {
- //1.初始化url 完成功能
- *a.日志初始化 b.创建pop3连接数据结构 m_pop3ConData c.设置关于下载的其它参数初始值 d.从url中获取状态信息m_statusFeedback
- *e.从url中获取收信服务器,及其相关参数m_socketType authMethod 用于连接设置 f.记录此url于m_url变量 g.预留接收弹出窗口方法 ir
- *h.初始化代理信息详细参考下面代理信息 usePAC=false i.过滤器列表应用 可优化点,以提高性能? j.连接类型设置 connectionType = "ssl";
- *k.打开网络Socket 参考 打开网络Socket l.创建命令输出流 参考 创建命令输出流 m.初始化后端访问的语言资源方法 mLocalBundle
- nsresult rv = Initialize(aURL);
- //2.记录url
- m_url = do_QueryInterface(aURL);
- //3.参考 检测端口安全
- rv = NS_CheckPortSafety(port, "pop");
- //4.获取url的Query段mQuery,用来判决进行的查询操作上面url最后传入的字符串参数 参考 获取url的Query段
- nsCAutoString queryPart;
- rv = url->GetQuery(queryPart); //如: "verifyLogon"
- //5.根据上面的返回设置连接结构中对应的标志值
- m_pop3ConData->only_check_for_new_mail = (PL_strcasestr(queryPart.get(), "check") != nullptr);
- m_pop3ConData->verify_logon = (PL_strcasestr(queryPart.get(), "verifyLogon") != nullptr);
- m_pop3ConData->get_url = (PL_strcasestr(queryPart.get(), "gurl") != nullptr);
- //6.非登录情况下执行
- if (!m_pop3ConData->verify_logon)
- {
- m_pop3Server->GetLeaveMessagesOnServer(&m_pop3ConData->leave_on_server); // 会根据不同的邮件夹的设置获取
- m_pop3Server->GetHeadersOnly(&m_pop3ConData->headers_only); //根据收信服务器的设置获取
- //关于消息大小的限制,并设置相关变量的值
- server->GetLimitOfflineMessageSize(&limitMessageSize); ----"limit_offline_message_size"
- m_pop3ConData->size_limit = (max_size) ? max_size * 1024 : 50 * 1024;
- //关于在服务器上留取邮件数量的设置
- m_pop3Server->GetDeleteByAgeFromServer(&deleteByAgeFromServer); //根据收信服务器的设置获取
- deleteByAgeFromServer
- ;
- if (deleteByAgeFromServer)
- m_pop3Server->GetNumDaysToLeaveOnServer(&numDaysToLeaveOnServer); //根据收信服务器的设置获取
- numDaysToLeaveOnServer
- }
- //7.记录sink // UIDL stuff UIDL的东西???
- nsCOMPtr<nsIPop3URL> pop3Url = do_QueryInterface(m_url);
- if (pop3Url)
- pop3Url->GetPop3Sink(getter_AddRefs(m_nsIPop3Sink));
- //8.关于邮件目录的设置
- nsCOMPtr<nsIFile> mailDirectory;
- //根据收信服务获取邮件目录 详细参考 收信服务获取本地目录
- rv = server->GetLocalPath(getter_AddRefs(mailDirectory)); 如创建的子目录名为“pop3.139.com”
- 9.设置服务器为忙
- server->SetServerBusy(true); // the server is now busy
- 10.非登录状态下设置Pop3UidlHost链表结构 维护每个账号的哈希表?
- if (!m_pop3ConData->verify_logon)
- m_pop3ConData->uidlinfo = net_pop3_load_state(hostName.get(), userName.get(), mailDirectory);
- 11. 设置为无新邮件状态
- m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_NoMail;
- 12.邮件删除逻辑处理 _____
- if (m_pop3ConData->uidlinfo && numDaysToLeaveOnServer > 0)
- ....
- 13.uidl逻辑处理___
- const char* uidl = PL_strcasestr(queryPart.get(), "uidl=");
- .....
- 14.连接状态设置
- m_pop3ConData->next_state = POP3_START_CONNECT;
- m_pop3ConData->next_state_after_response = POP3_FINISH_CONNECT;
- 15.运行当前url
- m_pop3Server->SetRunningProtocol(this);
- return nsMsgProtocol:oadUrl(aURL);
- }
- ******************
- ***** 收信服务获取本地目录*****
- nsMsgIncomingServer.cpp
- nsMsgIncomingServer::GetLocalPath(nsIFile **aLocalPath)
- {
- rv = GetFileValue("directory-rel", "directory", aLocalPath);
- //根据当前收信服务器的相关信息创建对应目录
- nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
- rv = getProtocolInfo(getter_AddRefs(protocolInfo));
- nsCOMPtr<nsIFile> localPath;
- rv = protocolInfo->GetDefaultLocalPath(getter_AddRefs(localPath));
- localPath->Create(nsIFile:IRECTORY_TYPE, 0755);
- }
- *****************************
- ***代理信息********
- PAC可能是代理访问控制的意思
- nsProtocolProxyService.cpp
- nsProtocolProxyService::Resolve(nsIURI *uri, uint32_t flags,
- pop://pop3.139.com:110 ----代理url含有的相关信息
- DIRECT 直接
- class nsProxyInfo MOZ_FINAL : public nsIProxyInfo
- **********************
- *******打开网络Socket *********
- rv = OpenNetworkSocketWithInfo(hostName.get(), port, connectionType, proxyInfo, ir);
- {
- //1. 获取 SocketTransportService
- nsCOMPtr<nsISocketTransportService> socketService (do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID));
- //2.创建Transport 详细参见创建Transport
- nsCOMPtr<nsISocketTransport> strans;
- rv = socketService->CreateTransport(&connectionType, connectionType != nullptr,
- nsDependentCString(aHostName),
- aGetPort, aProxyInfo,
- getter_AddRefs(strans));
- //3.设置安全回调,即指向上面的ir用于后端弹出窗口
- strans->SetSecurityCallbacks(callbacks);
- //4.创建循环引用,可能用来防止线程阻塞??? 是在主线程吗?线程ID是哪个?
- // creates cyclic reference!
- nsCOMPtr<nsIThread> currentThread(do_GetCurrentThread());
- strans->SetEventSink(this, currentThread);
- //5.记录当前传输连接
- m_transport = strans;
- //6.获取tcp连接超时设置,并进行相关设置
- prefBranch->GetIntPref("mailnews.tcptimeout", &gSocketTimeout);
- strans->SetTimeout(nsISocketTransport::TIMEOUT_CONNECT, gSocketTimeout + 60);
- strans->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, gSocketTimeout);
- //7.设置QoS
- (Quality of Service) "服务质量" 详细参看下面 关于Qos的获取
- uint8_t qos;
- rv = GetQoSBits(&qos);
- if (NS_SUCCEEDED(rv))
- strans->SetQoSBits(qos);
- //8.设置传输状态 详见下面 设置传输状态
- return SetupTransportState();
- }
- ****************************
- ***创建Transport*************
- .\mozilla\netwerk\base\src\nsSocketTransportService2.cpp
- nsSocketTransportService::CreateTransport(const char **types,
- {
- nsSocketTransport *trans = new nsSocketTransport();
- nsresult rv = trans->Init(types, typeCount, host, port, proxyInfo);
- }
- ***************************
- *******关于Qos的获取*************
- nsCAutoString prefName("mail.");
- prefName.Append(protocol);
- prefName.Append(".qos");
- nsresult rv;
- nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv,rv);
- int32_t val;
- rv = prefBranch->GetIntPref(prefName.get(), &val);
- NS_ENSURE_SUCCESS(rv, rv);
- *****************************************
- ************设置传输状态*************
- if (!m_socketIsOpen && m_transport)
- // open buffered, blocking output stream 输出流m_outputStream 用于发送数据 nsMsgProtocol::SendData m_outputStream->Write(dataBuffer, PL_strlen(dataBuffer), &writeCount);
- rv = m_transport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(m_outputStream));
- ****************************
- *********创建命令输出流***************
- m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, true);
- ************************************
- ***********检测端口安全*********************
- NS_CheckPortSafety(int32_t port,
- const char *scheme,
- nsIIOService *ioService = nullptr)
- {
- nsresult rv;
- nsCOMPtr<nsIIOService> grip;
- rv = net_EnsureIOService(&ioService, grip);
- if (ioService) {
- bool allow;
- rv = ioService->AllowPort(port, scheme, &allow);
- if (NS_SUCCEEDED(rv) && !allow) {
- NS_WARNING("port blocked");
- rv = NS_ERROR_PORT_ACCESS_NOT_ALLOWED;
- }
- }
- return rv;
- }
- *******************************************
- *****获取url的Query段*************
- const nsDependentCSubstring Query() { return Segment(mQuery); }
- // url parts (relative to mSpec)
- URLSegment mScheme;
- URLSegment mAuthority;
- URLSegment mUsername;
- URLSegment mPassword;
- URLSegment mHost;
- URLSegment mPath;
- URLSegment mFilepath;
- URLSegment mDirectory;
- URLSegment mBasename;
- URLSegment mExtension;
- URLSegment mQuery;
- URLSegment mRef;
- ********************************
复制代码 |
|