⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 warsvrprotocol.cpp

📁 ftpserver very good sample
💻 CPP
字号:
#include "StdAfx.h"#include "WarSvrProtocol.h"   // class implemented#ifndef WAR_AUTO_LOCK_H#   include "WarAutoLock.h"#endif#ifndef WAR_SVR_ENGINE_H#   include "WarSvrEngine.h"#endif#ifndef WAR_OS_H#   include "WarOs.h"#endif#ifndef WAR_SVR_PROTOCOL_FTP_H#   include "WarSvrProtocolFtp.h" // requiered FTP RFC's#endif#ifndef WAR_UNICODE_H#   include "WarUnicode.h"#endif#ifndef WAR_LOG_H#   include "WarLog.h"#endif#ifndef WAR_FSYS_H#   include "WarFsys.h"#endif#ifndef WAR_PERFMON_DEF_H#   include "WarPerfmonDef.h"#endif#define AUTO_LOCK WarAutoLock MyLock(mSvrLock);using namespace std;/////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarSvrProtocol::WarSvrProtocol(war_socket_io_ptr_t& companionPtr,                               WarSvrDefinition& svrDefinion) :WarTransferSocket(companionPtr),WarPluginSupport<WarSvrProtocol>("WarSvrProtocol"),mProtocolType(PROT_INVALID),mConnectionState(PRELOGIN),mrSvrDefinition(svrDefinion),mIsLoggedIn(false){}// WarSvrProtocolWarSvrProtocol::~WarSvrProtocol(){    Logout();}// ~WarSvrProtocol//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarSvrProtocol::OnClientConnect(){    SetCurrentState(WAR_SCKSTATE_CONNECTED);    WAR_RUN_PLUGINS(WarSvrProtocol, OnClientConnect, (this));    VerifyRemoteIpAddress();    // Start receiving data    if (mIoInBufferPtr.IsEmpty())        mIoInBufferPtr = new WarTransferBuffer(IO_BUFFER_LEN);    //SetCwd();    if (!GetBoolOption("svr_NOHOSTLOOKUP"))    {        try        {            mLocalAddress.Resolv(true);        }        catch(WarException)        {        }    }    RecvWithCallback(mIoInBufferPtr);}void WarSvrProtocol::Send(const std::string& from){    IoQueueOut((war_ccstr_t)from.c_str(), from.size());};void WarSvrProtocol::Send(const war_ccstr_t from, size_t length){    IoQueueOut(from, length);}void WarSvrProtocol::FlushOut(){    IoFlushOut();}void WarSvrProtocol::SetConnectionState(ConnectionStatesE newState){    WarLog debug_log(WARLOG_DEBUG, "WarSvrProtocol::SetConnectionState()");        static const char *state_names[STATE_INVALID +1] =     {        {"PRELOGIN"},        {"IDLE"},        {"GETFILE"},        {"PUTFILE"},        {"QUITTING"},        {"STATE_INVALID"}    };    assert(newState >= 0);    assert(newState <= STATE_INVALID);    assert(mConnectionState >= 0);    assert(mConnectionState <= STATE_INVALID);    if (debug_log)    {        debug_log << "Changing connection state from "            << state_names[mConnectionState]            << " to "            << state_names[newState]            << war_endl;    }            AUTO_LOCK    mConnectionState = newState;}war_svrfile_ptr_t WarSvrProtocol::OpenFile(const WarSvrPath& filePath,         const war_uint32_t openFlags)        throw(WarException){    war_uint32_t my_flags = openFlags;    if (!(openFlags & WarFileEnums::F_TEXT)        && WarOs::GetOs().IsNt())        my_flags |= WarFileEnums::F_CALLBACK;            filePath.VerifyHost(GetRemoteAddress().GetInAddr());    filePath.VerifyPermissions(openFlags);    war_svrfile_ptr_t file_ptr = new WarSvrFile;    file_ptr->Open(filePath, my_flags);    return file_ptr;}// Resolve, convert 8-bit characters to unicode if we use unicode.void WarSvrProtocol::ResolvPath(war_ccstr_t filePath,                                 WarSvrPath& resolvedPath) const                                throw(WarException){    war_svrpath_t my_path;    if (!my_path.IsSlash(*filePath))        my_path << GetCwd().GetAlias().GetPath() << WAR_SLASH;	DoResolvPath(filePath, my_path);		ResolvPath(my_path, resolvedPath);}// Resolve - no character conversionvoid WarSvrProtocol::ResolvPath(const war_svrpath_t& fromPath,								WarSvrPath& resolvedPath) const								throw(WarException) {	war_svrpath_t my_path;	if (!fromPath.IsFirstChSlash())        my_path << GetCwd().GetAlias().GetPath() << WAR_SLASH;	my_path << fromPath.GetPath();	my_path.Normalize();    my_path.Deparse();    resolvedPath = mProperties.ResolvPath(my_path);    resolvedPath.Normalize();}void WarSvrProtocol::ResolvPath(war_ccstr_t filePath,                                 bool useSecondPath)                                throw(WarException){    WarSvrPath& ruse_path = useSecondPath ? mCurrentFile2 : mCurrentFile;    ResolvPath(filePath, ruse_path);}void WarSvrProtocol::SetCwd(war_ccstr_t newCwd)throw(WarException){	    if ((newCwd == NULL) || !*newCwd)    {        string my_home = GetOption("user_HOME");        if (my_home.empty())            my_home= "/";        SetCwd(my_home.c_str());        return;    }    WarPath<char,WarSlash> new_cwd;    if (!new_cwd.IsSlash(*newCwd))        new_cwd = mCwd.GetAlias().GetPath();    while(new_cwd.IsSlash(*newCwd))        ++newCwd;        new_cwd << WAR_SLASH << newCwd;    // Check if the path exist    WarSvrPath resolved_cwd;    ResolvPath(new_cwd.GetPath(), resolved_cwd);    // Access check before physical test. Else, all kinds    // of funny DoS atacks can be launched.    resolved_cwd.VerifyHost(GetRemoteAddress().GetInAddr());    resolved_cwd.VerifyChdir();    war_stat_t my_stat;    try    {        WarFsysStat(resolved_cwd.GetUrl(), my_stat);    }    catch(WarException& ex)    {        WarLog warn_log(WARLOG_WARNINGS, "WarSvrProtocol::SetCwd()");        warn_log << "Error: Can not change directory to "            << resolved_cwd.GetUrl()            << ex            << war_endl;                throw ex;    }    if ((my_stat.st_mode & S_IFDIR) != S_IFDIR)        WarThrow(WarError(WAR_FERR_NOT_A_DIRECTORY), NULL);    // Accept and set the new path    mCwd = resolved_cwd;}void WarSvrProtocol::Logout(){    AUTO_LOCK;	if (!mIsLoggedIn)        return;     // WAR_ERR_PLUGIN_DONE is not supported here    WAR_PLUGINS_BEGINPRC(WarSvrProtocol, OnLogout, (this))    WAR_PLUGIN_ENDPRC();     // Kill references    mAuthDataPtr = NULL;    mAuthPtr = NULL;    //mIoOutBufferPtr = NULL;    //mIoInBufferPtr = NULL;    mIsLoggedIn = false;    WAR_PERFMON_DEC(WAR_PRFSVR_USERS_ONLINE);}WarSvrEnums::WarLoginResultE WarSvrProtocol::Login(        war_ccstr_t virtualHost,         war_ccstr_t userName,         war_ccstr_t userPasswd)        throw(WarException){    war_auth_ptr_t auth_module_ptr;    war_authdata_ptr_t session_data_ptr;    string user_name = userName ? userName : "";    string virtual_host = virtualHost ? virtualHost : "";        WarCollector<char> user_passwd(WarCollector<char>::SM_ERASE);    user_passwd = userPasswd ? userPasswd : "";    if (GetProtocolType() == PROT_FTP)    {        string anon_names = GetOption("ftpd_ANONUSERS");        for(char *p = strtok(&anon_names[0], "; "); p; p = strtok(NULL, "; "))        {            if (strcmp(p, userName) == 0)            {                user_name = "";                break;            }        }    }    WarLoginResultE login_result = LF_INVALID;    // WAR_ERR_PLUGIN_DONE is not supported here    WAR_PLUGINS_BEGINPRC(WarSvrProtocol, OnLoginPreAuth,         (this, virtualHost, userName, userPasswd,        user_name, user_passwd, virtual_host))    WAR_PLUGIN_ENDPRC();    login_result = GetAuth().Login(        *this,        virtual_host.c_str(),         user_name.empty() ? NULL : user_name.c_str(),        user_passwd.GetValue().c_str(),        auth_module_ptr,        session_data_ptr);    // WAR_ERR_PLUGIN_DONE is not supported here    WAR_PLUGINS_BEGINPRC(WarSvrProtocol, OnLoginPostAuth,         (this, virtualHost, userName, userPasswd,        user_name, user_passwd, virtual_host,        login_result, auth_module_ptr, session_data_ptr))    WAR_PLUGIN_ENDPRC();    if (login_result == LF_OK)    {        assert(auth_module_ptr.IsEmpty() == false);        assert(session_data_ptr.IsEmpty() == false);        mAuthPtr = auth_module_ptr;        mAuthDataPtr = session_data_ptr;        mAuthDataPtr->MergeProperties(mProperties);        mLoginVirtualHost = virtualHost ? virtualHost : "";        mLoginName = userName ? userName : "";        mUserFancyName = mLoginName;        if (mUserFancyName.empty())        {            if (mAuthDataPtr->IsAnonymous())                mUserFancyName = "anonymous";            else                mUserFancyName = "***UNKNOWN***";        }        if (mAuthDataPtr->IsPwdEmail())        {            mUserFancyName += '[';            mUserFancyName += userPasswd ? userPasswd : "";            mUserFancyName += ']';        }        mUserFancyName += '!';        mUserFancyName += GetRemoteAddress().Explain();        WAR_PERFMON_INC(WAR_PRFSVR_USERS_ONLINE);        mIsLoggedIn = true;    }    return login_result;}void WarSvrProtocol::AddToSessionFiles(const WarSvrPath& filePath) {    if ((filePath.GetPerms() & SHARED_UPLOAD) != SHARED_UPLOAD)        return; // Not a shared upload path    if (mOwnFiles.size() < (size_t)GetIntOption("svr_MAXOWNUPLOADFILES"))        mOwnFiles.insert(filePath);}void WarSvrProtocol::DeleteFromSessionFiles(const WarSvrPath& filePath){    ownfiles_t::iterator P = mOwnFiles.find(filePath);    if (P != mOwnFiles.end())        mOwnFiles.erase(P);}void WarSvrProtocol::VerifyRemoteIpAddress() const throw(WarException){    // Check IP access-list    if (!GetProperties().mIpAccessList.IsAllowed(        GetRemoteAddress().GetInAddr()))    {        WarLog db_log(WARLOG_DEBUG, "WarSvrProtocol::VerifyRemoteIpAddress()");        if (db_log)        {            db_log << "The remote IP address "                << GetRemoteAddress().Explain()                << " is banned in the current IP access-list. "                "Access is denied."                << war_endl;        }        WarThrow(WarError(WAR_ERR_IP_IS_DENIED), NULL);    }}//============================= ACCESS     ===================================WarSvrEngine& WarSvrProtocol::GetEngine() constthrow(WarException){    return WarSvrEngine::GetEngine();}WarUserEngine& WarSvrProtocol::GetAuth()      throw(WarException){    return GetSvrDefinition().GetAuth();}const WarUserEngine& WarSvrProtocol::GetAuth() const    throw(WarException){    return GetSvrDefinition().GetAuth();}WarSvrProtocol::ConnectionStatesE WarSvrProtocol::GetConnectionState() {    AUTO_LOCK    return mConnectionState;}//============================= INQUIRY    ===================================bool WarSvrProtocol::IsFileOwnedBySession(const WarSvrPath& filePath) const{    return mOwnFiles.find(filePath) != mOwnFiles.end();}bool WarSvrProtocol::IsAllowed(const struct in_addr& hostAddr) const{    return mProperties.mIpAccessList.IsAllowed(hostAddr);}const std::string WarSvrProtocol::GetSiteName() const{    return GetSvrDefinition().GetSiteName();}const std::string WarSvrProtocol::GetNativeSiteName() const{    return GetSvrDefinition().GetNativeSiteName();}/////////////////////////////// PROTECTED  ///////////////////////////////////void WarSvrProtocol::OnSent(const WarError& status,                             war_transfer_buffer_ptr_t& buffer){    WarSocket::OnSent(status, buffer);    AUTO_LOCK    if (mIoOutBufferPtr.IsEmpty())    {        mIoOutBufferPtr = buffer; // Keep the old buffer.        mIoOutBufferPtr->Reset();    }}void WarSvrProtocol::OnReceived(const WarError& status,         war_transfer_buffer_ptr_t& buffer){    WarSocket::OnReceived(status, buffer);}void WarSvrProtocol::DoResolvPath(war_ccstr_t filePath,         war_svrpath_t& path) const        throw(WarException){	path << filePath;}void WarSvrProtocol::PreProtocolCommand() throw(WarException){	WarThreadSpesificData *ptls = WarGetTsd();	if (NULL == ptls)		WarThrow(WarError(WAR_THREADERR_NO_TSD), NULL);	ptls->mpSvrProtocol = this;}void WarSvrProtocol::PostProtocolCommand() throw(WarException){	WarThreadSpesificData *ptls = WarGetTsd();	if (NULL == ptls)		WarThrow(WarError(WAR_THREADERR_NO_TSD), NULL);	ptls->mpSvrProtocol = NULL;}/////////////////////////////// PRIVATE    ///////////////////////////////////void WarSvrProtocol::IoQueueOut(war_ccstr_t buffer, size_t length){    size_t bytes_to_go = length;    war_ccstr_t send_buf = buffer;    while(bytes_to_go)    {           IoAllocateOutputBuffer();        if (bytes_to_go < mIoOutBufferPtr->GetFreeCapacity())        {            mIoOutBufferPtr->CopyToBuffer(send_buf, bytes_to_go);            break;        }        else        {            if (mIoOutBufferPtr->GetFreeCapacity() > 0)            {                size_t batch_bytes = WarMin(bytes_to_go,                     mIoOutBufferPtr->GetFreeCapacity());                                mIoOutBufferPtr->CopyToBuffer(                    send_buf, bytes_to_go);                send_buf += bytes_to_go;                bytes_to_go -= batch_bytes;            }            IoFlushOut();        }    }}void WarSvrProtocol::IoAllocateOutputBuffer(){    AUTO_LOCK    if (mIoOutBufferPtr.IsEmpty())        mIoOutBufferPtr = new WarTransferBuffer(IO_BUFFER_LEN);}void WarSvrProtocol::IoFlushOut(){	AUTO_LOCK;	    if (!mIoOutBufferPtr.IsEmpty()         && mIoOutBufferPtr->GetBytesUsed() > 0)    {		if (GetTransferMode() == TM_FAST)		{			QueueOutputData(mIoOutBufferPtr);		}		else		{			SendWithCallback(mIoOutBufferPtr);		}		mIoOutBufferPtr = NULL;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -