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

📄 liteproxyserverview.cpp

📁 代理服务器是怎样操作和运行的,希望能提供一种参考和学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// LiteProxyServerView.cpp : implementation of the CLiteProxyServerView class
//

#include "stdafx.h"
#include "LiteProxyServer.h"

#include "LiteProxyServerDoc.h"
#include "LiteProxyServerView.h"
#include "request.h"
#include "Listener.h"
#include "Iphlpapi.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CPtrList gptrArryTempListeners;

/////////////////////////////////////////////////////////////////////////////
// CLiteProxyServerView

IMPLEMENT_DYNCREATE(CLiteProxyServerView, CListView)

BEGIN_MESSAGE_MAP(CLiteProxyServerView, CListView)
	//{{AFX_MSG_MAP(CLiteProxyServerView)
	ON_WM_CREATE()
	ON_COMMAND(ID_FILE_NEW, OnFileNew)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLiteProxyServerView construction/destruction

CLiteProxyServerView::CLiteProxyServerView()
{
	m_pListener = NULL;
}

CLiteProxyServerView::~CLiteProxyServerView()
{
	// shutdown all listeners
	delete m_pListener;

	for(POSITION pos = gptrArryTempListeners.GetHeadPosition(); pos;)
	{
		try
		{
			Listener* pListener = (Listener*)gptrArryTempListeners.GetNext(pos);
			delete pListener;
		}
		catch(...)
		{
		}
	}
}

BOOL CLiteProxyServerView::PreCreateWindow(CREATESTRUCT& cs)
{
	cs.style |= LVS_REPORT | LVS_SHOWSELALWAYS;

	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CLiteProxyServerView drawing

void CLiteProxyServerView::OnDraw(CDC* pDC)
{
	CLiteProxyServerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

void CLiteProxyServerView::OnInitialUpdate()
{
	CListView::OnInitialUpdate();
	
	GetNetworkParams();
}

/////////////////////////////////////////////////////////////////////////////
// CLiteProxyServerView diagnostics

#ifdef _DEBUG
void CLiteProxyServerView::AssertValid() const
{
	CListView::AssertValid();
}

void CLiteProxyServerView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CLiteProxyServerDoc* CLiteProxyServerView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLiteProxyServerDoc)));
	return (CLiteProxyServerDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLiteProxyServerView message handlers

CLiteProxyServerView *gpView;

int CLiteProxyServerView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CListView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	gpView = this;

	m_pList = &GetListCtrl();
	ListView_SetExtendedListViewStyle(m_pList->m_hWnd, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	m_pList->InsertColumn(0, "Serial", LVCFMT_LEFT, 60, -1);
	m_pList->InsertColumn(1, "Date", LVCFMT_CENTER, 105, -1);
	m_pList->InsertColumn(2, "Name", LVCFMT_LEFT, 100, -1);
	m_pList->InsertColumn(3, "Request", LVCFMT_LEFT, 160, -1);
	m_pList->InsertColumn(4, "Received", LVCFMT_RIGHT, 60, -1);
	m_pList->InsertColumn(5, "Sent", LVCFMT_RIGHT, 55, -1);
	m_pList->InsertColumn(6, "Content-Length", LVCFMT_RIGHT, 65, -1);
	m_pList->InsertColumn(7, "Status", LVCFMT_LEFT, 110, -1);
	m_pList->InsertColumn(8, "Time (ms)", LVCFMT_RIGHT, 60, -1);

	CBitmap bitmap;
	bitmap.LoadBitmap(IDB_LIST);
	m_imageList.Create(16, 15, ILC_COLOR24, 11, 0);
	m_imageList.Add(&bitmap, (CBitmap*)NULL);
	m_pList->SetImageList(&m_imageList, 1);

	return 0;
}

struct TwoWayStruct
{
	TwoWayStruct(SOCKET Server, SOCKET Client, bool bNormal, Request* p)
	{
		SockServer = Server;
		SockClient = Client;
		bSockNormal = bNormal;
		pRequest = p;
	}
	~TwoWayStruct()
	{
		if(bSockNormal)
		{
			shutdown(SockClient, 2);
			closesocket(SockClient);
			if(SockServer)
			{
				shutdown(SockServer, 2);
				closesocket(SockServer);
			}
		}
		if(--pRequest->nRefCount == 0)
		{
			gpView->UpdateLog(pRequest->nLogID, 8, Commas(::GetTickCount()-pRequest->nTime));
			delete pRequest;
		}
	}

	SOCKET SockServer;
	SOCKET SockClient;
	bool bSockNormal;
	Request* pRequest;
};

#define ERROR_INVALIDIP			0
#define ERROR_BLOCKEDIP			1
#define ERROR_BLOCKEDFUNCTION	2
#define ERROR_BLOCKEDSIZE		3
#define ERROR_BLOCKEDEXTENSION	4
#define ERROR_BLOCKEDURLWORD	5
#define ERROR_BLOCKEDSITE		6

void SendError(SOCKET sock, int nErrorCode, CString strInfo)
{
	CString str = "HTTP/1.0 200 OK\r\n\r\n<title>Proxy server alert</title><Body><br>";
	switch(nErrorCode)
	{
	case ERROR_INVALIDIP:
		str += "None registered IP ("+strInfo+")";
		break;
	case ERROR_BLOCKEDIP:
		str += "You ("+strInfo+") are blocked.";
		break;
	case ERROR_BLOCKEDFUNCTION:
		str += "The function ("+strInfo+") is not authorized to you.";
		break;
	case ERROR_BLOCKEDSIZE:
		str += "Your request exceeded maximum allowed size ("+strInfo+").";
		break;
	case ERROR_BLOCKEDEXTENSION:
		str += "Request extension ("+strInfo+") is not authorized to you.";
		break;
	case ERROR_BLOCKEDURLWORD:
		str += "Request url includes restricted words ("+strInfo+"), if u want to view it any way,";
		break;
	case ERROR_BLOCKEDSITE:
		str += strInfo+"<br>If you want to view it any way,";
		break;
	}
	str += "<br>Please, Contact the network administrator.</Body>";
	send(sock, str, str.GetLength(), 0);
}

CCriticalSection cs;

CString Time2String(CTime &time)
{
	CString str = "If-Modified-Since: "+time.FormatGmt("%A").Left(3)+time.FormatGmt(", %d ")+time.FormatGmt("%B").Left(3)+time.Format(" %Y %H:%M:%S")+" GMT";
	return str;
}

CString strMonthes = "janfebmaraprmayjunjulaugsepoctnovdec";
CTime String2Time(CString str)
{
	if(str.GetLength() != 29)
		return CTime(0);
	str.MakeLower();

	return CTime(atoi(str.Mid(12)), (strMonthes.Find(str.Mid(8,3))+1)/3+1, atoi(str.Mid(5)), atoi(str.Mid(17)), atoi(str.Mid(20)), atoi(str.Mid(23)));
}

int RequestSend(Request* pRequest, SOCKET s, char* buf, int len)
{
	return send(s, buf, len, 0);
}

int RequestRecv(Request* pRequest, SOCKET s, char* buf, int len)
{
	int nBytes = recv(s, buf, len, 0);
	if(nBytes > 0)
		buf[nBytes] = 0;
	else
		buf[0] = 0;
	return nBytes;
}

UINT TwoWayThread(void* lpv)
{
	TwoWayStruct* pTWS = (TwoWayStruct*)lpv;
	try
	{
		int nLogID = pTWS->pRequest->nLogID;
		if(pTWS->bSockNormal)
			theApp.m_nInProgress++;
		int nBytes = 0, nTotal = 0;
		char by[10240] = "";
		bool bUpdateLog = true;

		while(true)
		{
			nBytes = 10240;
			// retrieve from server
			if(pTWS->SockServer)
				// normal proxy step
				nBytes = recv(pTWS->SockServer, by, 10240, 0);
			if(nBytes <= 0)
				break;

			gpView->UpdateLog(nLogID, pTWS->bSockNormal ? 4 : 5, nTotal += nBytes);	
		
			if(pTWS->pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_FTP)
			{
				bool bPasv = false, bPort = false;
				if(pTWS->bSockNormal)
				{
					// some clients don't send "anonymous" for anonymous connections
					if(memicmp(by, "USER ", 5) == 0 && nBytes == 7)
						memcpy(by+5, "anonymous\r\n", 11), nBytes+= 9;
					// check for PASV mode
					bPasv = memcmp(by, "227 ", 4) == 0;
				}
				else
					// check for PORT mode
					bPort = memicmp(by, "PORT ", 5) == 0;
				if(bPasv || bPort)
				{
					CString str = CString(by, nBytes), strSend;
					int n[7] = { str.Find(bPasv?'(':' '), str.Find(',', n[0]), str.Find(',', n[1]+1), str.Find(',', n[2]+1), str.Find(',', n[3]+1), str.Find(',', n[4]+1), str.Find(bPasv?')':'\r', n[5]) };
					CString strNewIP = gpView->m_strArrayIP[bPasv?gpView->m_strArrayIP.GetSize()-1:0];
					strNewIP.Replace('.', ',');
					// PASV: replace the server listener IP with LAN IP
					// PORT: replace the client listener IP with WAN IP
					strSend.Format("%s%s%s", str.Left(n[0]+1), strNewIP, str.Mid(n[4]));
					// copy command to its packet after replacment
					memcpy(by, strSend, nBytes = strSend.GetLength());

					Listener* pListener = new Listener;
					gptrArryTempListeners.AddTail(pListener);
					pListener->nPort = atoi(str.Mid(n[4]+1, n[5]-n[4]-1))*256+atoi(str.Mid(n[5]+1, n[6]-n[5]-1));
					pListener->nNextServerPort = pListener->nPort;
					// adjust the listener next proxy to the command listener
					pListener->strNextServerIP = str.Mid(n[0]+1, n[4]-n[0]-1);
					pListener->strNextServerIP.Replace(',', '.');
					pListener->nAppProtocol = Listener::ApplicationProtocol::TYPE_FTP_PASV+bPort;
					pListener->StartListen();
				}
			}
			// normal proxy step
			if(pTWS->SockClient && send(pTWS->SockClient, by, nBytes, 0) == SOCKET_ERROR)
			{
				if(pTWS->bSockNormal)
				{
					gpView->UpdateLog(nLogID, 7, CString(pTWS->pRequest->pFileCache?(pTWS->pRequest->bRequestServer ? "Online Proxy Cache " : "Offline Proxy Cache "):"")+"Canceled");
					bUpdateLog = false;
				}
				break;
			}
		}
		if(pTWS->bSockNormal)
		{
			theApp.m_nReceivedBytes += nTotal;
			pTWS->pRequest->nReceived += nTotal;
		}
		else
		{
			theApp.m_nSentBytes += nTotal;
			pTWS->pRequest->nSent += nTotal;
		}
		if(pTWS->bSockNormal && bUpdateLog == true)		
		{
			if(nTotal == SOCKET_ERROR)
				gpView->UpdateLog(nLogID, 7, "Failed");
			else
				gpView->UpdateLog(nLogID, 7, "Success");
		}
	}
	catch(...)
	{
	}
	if(pTWS->bSockNormal)
		theApp.m_nInProgress--;
	delete pTWS;		

	return 0;
}

bool ConnectHost(SOCKET &s, Request* pRequest)
{
	if(pRequest->nLogID == -1)
	{

⌨️ 快捷键说明

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