home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2003 June
/
PCWorld_2003-06_cd.bin
/
KOMUNIK
/
MIRRORIT
/
SRC
/
DOWNLOADDLG.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-10
|
10KB
|
439 lines
// DownLoadDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MirrorIt.h"
#include "Session.h"
#include "URL.h"
#include "HTTPSocket.h"
#include "DownLoadDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define RETRIEVE_DOCUMENT (1)
#define RETRIEVE_FILE (0)
#define RETRIEVE_ERROR (-1)
#define RETRIEVE_UNKNOWN (-2)
#define RETRIEVE_ABORT (-3)
#define STORE_ERROR (-4)
#define STORE_SKIP (-5)
#define NO_STOREERROR (-6)
/////////////////////////////////////////////////////////////////////////////
// CDownLoadDlg dialog
CDownLoadDlg::CDownLoadDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDownLoadDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDownLoadDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_bAbort = FALSE;
m_numFiles = 0;
m_numBytes = 0;
m_bMinimized = FALSE;
}
void CDownLoadDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDownLoadDlg)
DDX_Control(pDX, IDC_PROGRESS, m_Progress);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDownLoadDlg, CDialog)
//{{AFX_MSG_MAP(CDownLoadDlg)
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDownLoadDlg message handlers
int CDownLoadDlg::LoadSessions(CPtrArray & sessions)
{
Create(IDD_DOWNLOAD);
CString caption;
caption.LoadString(IDS_MIRRORINGDIALOG);
SetWindowText(caption);
ModifyStyleEx(0, WS_EX_APPWINDOW);
ShowWindow(SW_SHOW);
CRect rc;
CAnimateCtrl m_AnimateCtrl;
CWnd* pFrame = GetDlgItem(IDC_ANIMFRAME);
pFrame->GetClientRect(&rc);
m_AnimateCtrl.Create(WS_CHILD | WS_VISIBLE | ACS_TRANSPARENT | ACS_AUTOPLAY,
rc, pFrame, IDC_ANIMATE);
m_AnimateCtrl.Open(IDR_AVI); //"C:\\TEMP\\1\\1.AVI");
InvalidateRect(&rc);
UpdateWindow();
for (int i = 0; i < sessions.GetSize(); i++)
{
if (m_bAbort) break;
BOOL b = LoadSession(*(CSession *)sessions.GetAt(i));
((CMirrorItApp *)AfxGetApp()) -> theLogFile.Close();
if (b)
{
break;
}
}
return 1;
}
void CDownLoadDlg::OnCancel()
{
m_bAbort = TRUE;
}
int CDownLoadDlg::WaitFor(BOOL * wait)
{
BOOL bDoingBackgroundProcessing = TRUE;
while ( bDoingBackgroundProcessing )
{
MSG msg;
Sleep(1);
while ( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if ( !AfxGetApp() -> PumpMessage( ) )
{
bDoingBackgroundProcessing = FALSE;
::PostQuitMessage( 0 );
return 1;
}
}
// let MFC do its idle processing
LONG lIdle = 0;
while ( AfxGetApp()->OnIdle(lIdle++ ) )
;
if (*wait) break;
if (m_bAbort) return 1;
}
return 0;
}
int CDownLoadDlg::ProcessMessages()
{
MSG msg;
Sleep(1);
while ( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if ( !AfxGetApp() -> PumpMessage( ) )
{
::PostQuitMessage( 0 );
return 1;
}
}
// let MFC do its idle processing
LONG lIdle = 0;
while ( AfxGetApp()->OnIdle(lIdle++ ) )
;
if (m_bAbort) return 1;
return 0;
}
int CDownLoadDlg::LoadSession(CSession & session)
{
CStringList links;
CString basestr = session.m_BaseURL, strurl;
CURL base(basestr);
if (base.scheme.IsEmpty())
{
basestr = "http://" + basestr;
}
else
if (base.scheme.Compare("http") != 0)
{
return 0;
}
CURL base2(basestr);
if (base2.path.IsEmpty())
{
base2.path = "/";
base2.build(basestr);
}
int currentlevel = 0, c = 1;
CreateDirectoryTree(session.m_Directory);
CreateLog(session, links);
links.AddHead(basestr);
while (links.GetCount())
{
int i;
strurl = links.GetHead();
links.RemoveHead();
CURL url(strurl);
if (url.urltype != URL_INVALID && !visitedlinks.Find(strurl))
{
CString temp;
temp.Format(IDS_DOWNLOADINFO, m_numFiles, m_numBytes);
visitedlinks.AddTail(strurl);
SetDlgItemText(IDC_URL, strurl);
SetDlgItemText(IDC_DOWNLOADINFO, temp);
m_Progress.SetPos(0);
if (ProcessMessages()) break;
i = RetrieveDocument(strurl, url, session, links);
if (i == RETRIEVE_ABORT) break;
if (i == RETRIEVE_ERROR) continue;
m_numFiles++;
}
if (session.m_BNumberOfFiles && m_numFiles >= (int)session.m_NumberOfFiles)
break;
if (session.m_BNumberOfKBytes && m_numBytes >= (int)session.m_NumberOfBytes)
break;
c--;
if (c <= 0)
{
currentlevel++;
c = links.GetCount();
if (session.m_BNumberOfLevels && currentlevel >= (int)session.m_NumberOfLevels)
break;
}
}
return links.GetCount();
}
int CDownLoadDlg::RetrieveDocument(CString surl, CURL & url, CSession & session, CStringList & links)
{
CString line, temp;
CString getpath, getserver;
CHTTPSocket sock;
UINT getport = 80;
m_bAbort = FALSE;
if (m_bMinimized)
SetWindowText(surl);
url.fragment.Empty();
url.relbuild(temp);
getpath = temp;
getserver = url.net_loc;
if (session.m_BProxy && !sock.inserverlist(url.net_loc, session.m_NoProxy))
{
getport = session.m_ProxyPort;
getpath = surl;
getserver = session.m_ProxyServer;
}
line = "GET " + getpath + " HTTP/1.0\r\n";
if (session.m_ModifiedSince)
{
line += "If-Modified-Since: " + sock.FormatTime(session.m_TModifiedSince) + "\r\n";
}
if (!session.m_Password.IsEmpty() || !session.m_UserName.IsEmpty())
{
line += "Authorization: Basic " + sock.mimeencode(session.m_UserName + ":" + session.m_Password) + "\r\n";
}
// line += "User-Agent: MirrorIt/1.0.0\r\n";
// line += "User-Agent: Mozilla/4.03 [en] (X11; I; Linux.2.0.32.i486)\r\n";
// line += "User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)\r\n";
// line += "User-Agent: Mozilla/5.0 (compatible; MSIE 5.0b2; Windows 98)\r\n";
// line += "Referer: http://server.eroticportal.com/6/\r\n";
line += "Accept: */*\r\n";
line += "\r\n";
// sock.AddLog(line);
sock.basenet_loc = url.net_loc;
sock.base = surl;
sock.links = &links;
sock.session = &session;
sock.m_numBytes = &m_numBytes;
sock.m_progress = &m_Progress;
CString filename = sock.getfilename(surl);
sock.m_filename = session.m_Directory + filename;
// sock.AddLog(surl); //get file
sock.Create();
if (!sock.Connect((LPCSTR)getserver, getport))
{
if (sock.GetLastError() != WSAEWOULDBLOCK)
{
return RETRIEVE_ERROR;
}
else
{
sock.AsyncSelect(FD_CONNECT);
if (WaitFor(&sock.m_bConnect)) return RETRIEVE_ABORT;
if (redirection(sock, session, links) != NO_STOREERROR) return 0;
if (sock.m_bError) return STORE_ERROR;
}
}
sock.SendRequest(line);
sock.AsyncSelect(FD_WRITE | FD_CLOSE);
if (WaitFor(&sock.m_bSent))
{
return RETRIEVE_ABORT;
}
else
{
// sock.AddLog("Before answer");
sock.m_recv = TRUE;
sock.AsyncSelect(FD_READ | FD_CLOSE);
if (WaitFor(&sock.m_bClose))
return RETRIEVE_ERROR;
// sock.AddLog("After answer");
if (sock.m_iCode != 200)
{
CString errorstr;
errorstr.Format("%03d", sock.m_iCode);
if (sock.m_iCode >= 300 && sock.m_iCode <= 302)
sock.AddLog(errorstr, surl + "\r\n" + sock.location);
else
{
/* CString key;
CString val;
POSITION pos = sock.m_Header.GetStartPosition();
while (pos != NULL)
{
sock.m_Header.GetNextAssoc(pos, key, val);
line += "\r\n" + key + ": " + val;
}
*/
sock.AddLog(errorstr, surl + "\r\n\r\n" + line);
}
// errorstr.Format("Error: %d", sock.m_iCode);
// sock.AddLog(errorstr);
}
else
{
sock.AddLog("200", surl);
}
if (sock.m_iCode == 400 || sock.m_iCode == 503)
{
visitedlinks.RemoveTail();
links.AddTail(surl);
m_numFiles--;
}
if (redirection(sock, session, links) != NO_STOREERROR) return 0;
if (sock.m_bError) return STORE_ERROR;
}
return RETRIEVE_DOCUMENT;
}
BOOL CDownLoadDlg::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
int CDownLoadDlg::redirection(CHTTPSocket & sock, CSession & session, CStringList & links)
{
if (sock.m_bRedirect && (
(sock.m_iCode == 300 && session.m_Multiple) ||
(sock.m_iCode == 301 && session.m_Permanent) ||
(sock.m_iCode == 302 && session.m_Temporary)))
{
CString surl(sock.location);
CURL url(sock.location);
return RetrieveDocument(surl, url, session, links);
}
return NO_STOREERROR;
}
void CDownLoadDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
m_bMinimized = nType == SIZE_MINIMIZED;
if (!m_bMinimized)
{
CString caption;
caption.LoadString(IDS_MIRRORINGDIALOG);
SetWindowText(caption);
}
}
void CDownLoadDlg::CreateLog(CSession & session, CStringList & links)
{
CStdioFile & log = ((CMirrorItApp *)AfxGetApp()) -> theLogFile;
CString logname = session.m_Directory + "MirrorIt.log";
if (log.Open(logname, CFile::modeReadWrite | CFile::typeText))
{
int ret = AfxMessageBox(IDS_CONTINUELOG, MB_YESNO);
if (ret == IDYES)
{
CString line;
while (log.ReadString(line))
{
CString type = line.Left(3),
url = line.Mid(4);
int code = atoi(type);
if (type == "ADD")
{
links.AddTail(url);
}
else
if (code == 200)
{
visitedlinks.AddTail(url);
POSITION p = links.Find(url);
if (p)
links.RemoveAt(p);
}
if (code >= 300 && code <= 302)
{
visitedlinks.AddTail(url);
POSITION p = links.Find(url);
if (p)
links.RemoveAt(p);
if ((code == 300 && session.m_Multiple) ||
(code == 301 && session.m_Permanent) ||
(code == 302 && session.m_Temporary))
{
log.ReadString(line);
links.AddTail(line.Mid(4));
}
}
}
return;
}
else
{
log.Close();
}
if (ret == IDCANCEL)
{
m_bAbort = true;
return;
}
}
log.Open(logname, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
}