📄 liteproxyserverview.cpp
字号:
// 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 + -