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

📄 warsvrprotocolhttp.cpp

📁 ftpserver very good sample
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"#if WAR_RFC2068#include "WarSvrProtocolHttp.h"   // class implemented#ifndef WAR_LOG_H#   include "WarLog.h"#endif#ifndef WAR_AUTO_LOCK_H#   include "WarAutoLock.h"#endif#ifndef WAR_SVR_ENGINE_H#   include "WarSvrEngine.h"#endif#ifndef WAR_TIMER_H#   include "WarTimer.h"#endif#ifndef WAR_PERFMON_DEF_H#   include "WarPerfmonDef.h"#endif#ifndef WAR_USER_AUTH_IMPERSONATE_H#   include "WarUserAuthImpersonate.h"#endif#ifndef WAR_ATOI_H#   include "WarAtoi.h"#endif#ifndef WAR_FSYS_H#	include "WarFsys.h"#endif#ifndef WAR_AP_BASE64_H#	include "ap_base64.h"#endif#define AUTO_LOCK WarAutoLock MyLock(mSvrLock);using namespace std;/////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarSvrProtocolHttp::WarSvrProtocolHttp(        war_socket_io_ptr_t& companionPtr,        WarSvrDefinition& svrDefinion) :WarSvrProtocol(companionPtr, svrDefinion){	mProtocolType = PROT_HTTP;    mReply.mpProtocol = this;    Reset();	AddLogIdentifierTag("HTTPD");}//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarSvrProtocolHttp::Abort(const WarError& reason)        throw(WarException){    CloseConnection(reason);}void WarSvrProtocolHttp::CloseConnection(const WarError& reason)         throw(WarException){    if (IsOpen())    {        Close();    }    Logout();    GetEngine().UnregisterSession(*this);    WarThrow(reason, NULL);}void WarSvrProtocolHttp::Reset(){	AUTO_LOCK;	Logout();    mReply.Reset();    mHaveEndOfHeader = false;    if (!mInputBuffer.IsEmpty())        mInputBuffer.Reset();    mExpectedContentBytes = 0;    mReceivedContentBytes = 0;	mRelayInput = false;	WarTransferSocket::Reset();	// See if we have pending input	if (!mQueuedInput.IsEmpty() || !mInputBuffer.IsEmpty())	{		WarLog net_log(WARLOG_NETWORK, "WarSvrProtocolHttp::Reset()", this);		if (net_log)		{			size_t bytes = mInputBuffer.GetLength();			if (mQueuedInput)				bytes += mQueuedInput->GetBytesUsed();			net_log << "I found some queued input. ("				<< bytes				<< " bytes). "				"I will call PreprocessInput() with this data, just as "				"if it came fresh from the net."				<< war_endl;		}				war_transfer_buffer_ptr_t tmp_ptr = mQueuedInput;		mQueuedInput = NULL;		PreprocessInput(tmp_ptr);	}}//============================= CALLBACK   ===================================void WarSvrProtocolHttp::OnClientConnect(){    AUTO_LOCK    // Update internal variables    // and start receiving commands from the user    try    {        WarSvrProtocol::OnClientConnect();    }    catch(WarException& ex)    {        switch(ex.LocalError())        {        case WAR_ERR_IP_IS_DENIED:            mReply << HSM_BAD_IP << HTTPR_FORBIDDEN;            break;        case WAR_ERR_ACCESS_DENIED:            mReply << HSM_ACCESS_DENIED << HTTPR_FORBIDDEN;            break;        default:            mReply << HSM_GENERIC_FAIL << HTTPR_INTERNAL_SERVER_ERROR;            break;        }        CloseConnection(ex); // Throws     }    WarUrl my_url;    my_url.Create("http://", NULL, NULL,         GetLocalAddress().GetPort(), NULL, "/");    mRequestHeader.Reset();    mRequestHeader.SetDefaultUrl(my_url);}void WarSvrProtocolHttp::OnReceived(const WarError& status,         war_transfer_buffer_ptr_t& buffer){	WarSvrProtocol::OnReceived(status, buffer);	if (status)	{		try		{			if (WAR_NETERR_HARD_CLOSE == status.LocalError())			{				WarLog http_log(WARLOG_DEBUG_HTTP, "WarSvrProtocolHttp::OnReceived()", this);								http_log << "Connection closed by the remote host." 					<< status					<< war_endl;			}			else			{				// Error!				WarLog warn_log(WARLOG_WARNINGS, "WarSvrProtocolHttp::OnReceived()", this);								warn_log << "Error while receiving data. Closing connection." 					<< status					<< war_endl;			}		}		catch(WarException)		{		}		CloseConnection(status); // throws	}	if (mRelayInput)	{		mQueuedInput = buffer;	}	else	{		PreprocessInput(buffer);	}}void WarSvrProtocolHttp::PreprocessInput(war_transfer_buffer_ptr_t& buffer){	if (buffer.IsEmpty())	{		try		{			// Connection closed!			WarLog http_log(WARLOG_DEBUG_HTTP, "WarSvrProtocolHttp::PreprocessInput()", this);			if (http_log)			{				http_log << "Connection closed by remote client" 					<< war_endl;				return;			}		}		catch(WarException ex)		{		}		CloseConnection(WarError()); // throws 		return;	}    try    {        ProcessInput(buffer);				if (IsOpen() && mIoInBufferPtr)		{			mIoInBufferPtr->Reset();			RecvWithCallback(mIoInBufferPtr);		}    }    catch(WarException& ex)    {        // Exception during input. This will normally indicate         // an error-situation where we should give a short        // explanation and close the connection.        // Exceptions are when we negotiate authentication        // credentials.        switch(ex.LocalError())        {        case WAR_HTERR_HEADER_TOO_LONG:            GetReply() << HSM_HEADER_TOO_LONG                 << HTTPR_INTERNAL_SERVER_ERROR;            CloseConnection(ex);            return;        case WAR_ERR_NOT_IMPLEMENTED:            GetReply() << HSM_NOT_IMPLEMENTED                 << HTTPR_NOT_IMPLEMENTED;            CloseConnection(ex);            return;		default:			GetReply() << ex.Explain()                 << HTTPR_INTERNAL_SERVER_ERROR;			CloseConnection(ex);        }    }}void WarSvrProtocolHttp::OnSent(const WarError& status,         war_transfer_buffer_ptr_t& buffer){}void WarSvrProtocolHttp::OnValidateHeaderLength(size_t currLen)throw(WarException){    size_t max_len;    if (currLen > (max_len = (size_t)GetIntOption("http_MAXHDRLEN")))    {        WarLog security_log(WARLOG_SECURITY, "WarSvrProtocolHttp::OnValidateHeaderLength()", this);        security_log << "HTTP header length exeeds the limit of "            << max_len            << "bytes defined by http_MAXHDRLEN option. "            "This may indicate a breakin attempt from a hostile host."            << war_endl;        WarThrow(WarError(WAR_HTERR_HEADER_TOO_LONG), NULL);    }}//============================= ACCESS     ===================================//============================= INQUIRY    ===================================/////////////////////////////// PROTECTED  ///////////////////////////////////WarSvrProtocolHttp::~WarSvrProtocolHttp(void){}void WarSvrProtocolHttp::ProcessInput(war_transfer_buffer_ptr_t& buffer){	AUTO_LOCK;	if (!buffer.IsEmpty())		mInputBuffer.PushData(buffer->GetBuffer(), buffer->GetBytesUsed());again:    if (!mHaveEndOfHeader)    {			// Scan for end of header marker		war_ccstr_t p = mInputBuffer.GetStartOfBuffer();        war_ccstr_t pp = mInputBuffer.GetEndOfBuffer() -3;        while(p < pp)        {            if ((p[0] == '\r')                && (p[1] == '\n')                && (p[2] == '\r')                && (p[3] == '\n'))            {                mHaveEndOfHeader = true;                size_t header_len = (p - mInputBuffer.GetStartOfBuffer()) + 4;                // Check if the header-length is too large                OnValidateHeaderLength(header_len);                // Process header                mRequestHeader << mInputBuffer.PopData(header_len);                mReply.GetHeader().SetHttpVersion(mRequestHeader.GetHttpVersion());				WarLog http_log(WARLOG_DEBUG_HTTP, "WarSvrProtocolHttp::ProcessInput()", this);				if (http_log)				{					WarCollector<char> headers;					mRequestHeader.GetNativeHeaders(headers);										http_log << "Request headers: "						<< headers						<< war_endl;				}                // Load properties for the virtual host, if present                LoadVirtual(mRequestHeader.GetUrl());                // Verify IP Access                VerifyRemoteIpAddress();                // Attempt to log on                VerfiyHttpAuth();				// Set CWD to /				SetCwd("/");                // Check if method is allowed                VerifyHttpRequest();                // Process headers                try                {                    mExpectedContentBytes = WarAtoi<contentlen_t>(                        mRequestHeader.GetHeaderValue("Content-Length").c_str());                }                catch(WarException)                {                }                goto process_content;            }            else                ++p;        }        // Check if the header-length is too large        OnValidateHeaderLength(mInputBuffer.GetLength());        if (!mHaveEndOfHeader)            return; // Need more input    }process_content:        mReceivedContentBytes += mInputBuffer.GetLength();        if (mExpectedContentBytes >= mReceivedContentBytes)    {        // The request is complete		WarError caught_err;		war_ccstr_t data = NULL;		size_t num_bytes_in_request_header = mInputBuffer.GetLength();		if (0 != num_bytes_in_request_header) 			data = mInputBuffer.PopData(mExpectedContentBytes);		prot_cmd_prp_t prepare_cmd(this); // Allocates and deallocates resources		        try        {            switch(mRequestHeader.GetMethod())            {            case HM_GET:                OnGetRequest(data, mExpectedContentBytes);                break;            case HM_OPTIONS:                OnOptionsRequest(data, mExpectedContentBytes);                break;            case HM_HEAD:                OnHeadRequest(data, mExpectedContentBytes);                break;            case HM_POST:                OnPostRequest(data, mExpectedContentBytes);                break;            case HM_PUT:                OnPutRequest(data, mExpectedContentBytes);                break;            case HM_DELETE:                OnDeleteRequest(data, mExpectedContentBytes);                break;            case HM_TRACE:                OnTraceRequest(data, mExpectedContentBytes);                break;            default:                OnInvalidRequest(data, mExpectedContentBytes);            }        }        catch(WarException &ex)        {            switch(ex.LocalError())            {			case WAR_BYPASS_DEFAULT_PRC:				// Async IO operation in progress. We will be				// called again when it completes.				{					WarLog net_log(WARLOG_NETWORK, "WarSvrProtocolHttp::ProcessInput()", this);					if (net_log)					{						net_log << "Caught WAR_BYPASS_DEFAULT_PRC. "							"I will not continue to process input "							"until I'm called again. "							<< war_endl;					}										// Send reply					GetReply() << HSM_NOT_IMPLEMENTED << HTTPR_NOT_IMPLEMENTED;				}				return;			case WAR_ERR_NOT_IMPLEMENTED:

⌨️ 快捷键说明

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