home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2003 June
/
PCWorld_2003-06_cd.bin
/
KOMUNIK
/
MIRRORIT
/
SRC
/
HTTPSOCKET.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-06
|
29KB
|
1,394 lines
// HTTPSocket.cpp : implementation file
//
#include "stdafx.h"
#include "MirrorIt.h"
#include "Session.h"
#include "HTTPSocket.h"
#include "URL.h"
#include <stdio.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const unsigned long crc_table[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
#define DO1(buf) crc = CRC32(crc, *buf++)
#define DO2(buf) DO1(buf); DO1(buf)
#define DO4(buf) DO2(buf); DO2(buf)
#define DO8(buf) DO4(buf); DO4(buf)
unsigned long crc32(unsigned long crc, const unsigned char *buf, int len)
{
if (!buf)
{
return 0L;
}
crc = crc ^ 0xffffffffL;
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL;
}
/////////////////////////////////////////////////////////////////////////////
// CHTTPSocket
CHTTPSocket::CHTTPSocket()
{
m_Header.RemoveAll();
m_sBlockRemain.Empty();
htmltemp.RemoveAll();
links = NULL;
m_bFirstLine = TRUE;
m_bConnect = FALSE;
m_bSent = FALSE;
m_bClose = FALSE;
m_bInHeader = TRUE;
m_buf.SetSize(1024);
m_request.Empty();
m_requestindex = 0;
m_progress = NULL;
m_bDocument = FALSE;
m_filestatus = 0;
m_bError = FALSE;
m_bFileInited = FALSE;
m_bRedirect = FALSE;
m_iCode = 0;
m_recv = FALSE;
}
CHTTPSocket::~CHTTPSocket()
{
if (m_filestatus == 1)
{
m_File.Write(htmltemp.GetData(), htmltemp.GetSize());
}
if (m_filestatus > 0)
{
CString filename = m_File.GetFilePath();
m_File.Close();
if (m_filestatus == 2)
{
DeleteFile((LPCSTR)filename);
}
}
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CHTTPSocket, CAsyncSocket)
//{{AFX_MSG_MAP(CHTTPSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CHTTPSocket member functions
void CHTTPSocket::OnClose(int nErrorCode)
{
m_bClose = TRUE;
CAsyncSocket::OnClose(nErrorCode);
}
void CHTTPSocket::OnConnect(int nErrorCode)
{
m_bConnect = TRUE;
CAsyncSocket::OnConnect(nErrorCode);
}
void CHTTPSocket::OnReceive(int nErrorCode)
{
/* if (!m_recv)
{
AddLog("nem kellett volna csomagot kapni");
}*/
//AsyncSelect(0);
int nBytes = Receive(m_buf.GetData(), m_buf.GetSize());
if (nBytes != SOCKET_ERROR)
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!
// m_bDocument = (m_filename.Find(".htm") != -1);
if (m_bInHeader)
{
int headersize = ProcessHeader(nBytes);
if (headersize < nBytes)
{
m_bInHeader = FALSE;
OutputData(m_buf.GetData() + headersize, nBytes - headersize);
}
}
else
{
OutputData(m_buf.GetData(), nBytes);
/* BYTE sep = '|';
OutputData(&sep, 1);*/
}
}
else
nBytes = GetLastError();
//AsyncSelect(FD_WRITE | FD_CLOSE);
}
void CHTTPSocket::OnSend(int nErrorCode)
{
if (m_requestindex < m_request.GetLength())
{
int nBytes = Send((LPCSTR)m_request + m_requestindex, max(0, m_request.GetLength() - m_requestindex));
if (nBytes != SOCKET_ERROR)
{
m_requestindex += nBytes;
}
else
{
nBytes = GetLastError();
}
}
m_bSent = m_requestindex >= m_request.GetLength();
}
void CHTTPSocket::SendRequest(CString request)
{
if (!m_progress)
{
m_progress -> SetRange(0, 100);
}
m_iCode = -1;
// m_bFirstLine = TRUE;
m_bProgress = FALSE;
m_request = request;
m_requestindex = 0;
}
int CHTTPSocket::ProcessHeader(int size)
{
if (!m_bInHeader)
{
// AddLog("vege a headernek, mit keresek itt");
return 0;
}
int i = 0;
BOOL eob = FALSE;
CString current = m_sBlockRemain;
m_sBlockRemain.Empty();
while (i < size)
{
eob = TRUE;
while (i < size && eob)
{
unsigned char ch = (unsigned char)(m_buf.GetAt(i));
switch (ch)
{
case '\r':
break;
case '\n':
eob = FALSE;
break;
default:
current += ch;
}
i++;
}
// if (!m_bInHeader)
// {
// AddLog("valami baj van ...");
// }
// AddLog("|" + current + "|");
if (current.IsEmpty())
{
m_bInHeader = FALSE;
// AddLog("---------------------------------");
return i;
}
else
if (!eob)
{
int colon = current.Find(':');
if (m_bFirstLine)
{
m_bFirstLine = FALSE;
int space = current.Find(' ');
if (space != -1)
{
current = current.Mid(space + 1);
space = current.Find(' ');
if (space != -1)
{
current = current.Left(space);
}
m_iCode = atoi((LPCSTR) current);
if (m_iCode != 200)
{
if (m_iCode >= 300 || m_iCode <= 302)
{
m_bRedirect = TRUE;
}
else
{
m_bError = TRUE;
}
}
}
}
else
if (colon != -1)
{
CString name = current.Left(colon);
CString value = current.Mid(colon + 1);
name.MakeLower();
value.TrimLeft();
if (!name.Compare("content-length"))
{
if (m_progress)
{
m_progress -> SetRange(0, atoi((LPCSTR) value));
m_bProgress = TRUE;
}
}
else
if (!name.Compare("location"))
{
location = value;
}
else
if (!name.Compare("content-type"))
{
m_bDocument = !value.Compare("text/html");
}
m_Header.SetAt(name, value);
// AfxMessageBox(name + ":" + value, MB_APPLMODAL | MB_OK);
}
current.Empty();
}
}
m_sBlockRemain = current;
// AddLog("............");
return (size + 1);
}
void CHTTPSocket::StatusRead(int size)
{
if (m_bProgress)
{
m_progress -> OffsetPos(size);
}
*m_numBytes += size;
}
int CHTTPSocket::OutputData(BYTE * odata, int len)
{
if (m_bError)
{
return 1;
}
if (m_bRedirect)
{
return 1;
}
if (!m_bFileInited)
{
m_bFileInited = TRUE;
if (!initfile())
{
m_bError = TRUE;
return 1;
}
}
StatusRead(len);
if (m_bDocument)
{
int i = htmltemp.GetSize();
//parse HTML file
htmltemp.SetSize(i + len);
BYTE *data = htmltemp.GetData();
BYTE *data2 = data;
memcpy(data + i, odata, len);
len += i;
BYTE *s1 = data, *end = data + len, *s2,
*start = data, *tagend;
while (s1 < end)
{
if (*s1 == '<')
{
start = s1++;
int intag = 1, quot = 0; // 1 = ", 2 = '
while (s1 < end && intag)
{
if (*s1 == '>' && quot == 0)
{
intag = 0;
break;
}
else
if (*s1 == '\"')
{
if (quot == 0)
{
quot = 1;
}
else
if (quot == 1)
{
quot = 0;
}
}
else
if (*s1 == '\'')
{
if (quot == 0)
{
quot = 2;
}
else
if (quot == 2)
{
quot = 0;
}
}
s1++;
}
if (!intag)
{
tagend = s1;
CString tagname, tagparam, tagvalue;
s1 = start + 1;
#define NEXTCHAR while (s1 < tagend && (*s1 == ' ' || *s1 == '\t' || *s1 == '\n' || *s1 == '\r')) s1++
#define NOTBLANKCHAR(s1) (*s1 != ' ' && *s1 != '\t' && *s1 != '\n' && *s1 != '\r')
NEXTCHAR;
if (s1 < tagend)
{
while (s1 < tagend && NOTBLANKCHAR(s1))
{
tagname += *(s1 ++);
}
}
tagname.MakeLower();
if (!tagname.Compare("!--"))
{
start = tagend + 1;
continue;
}
start = tagend + 1;
while (s1 < tagend)
{
tagparam.Empty();
tagvalue.Empty();
NEXTCHAR;
while (s1 < tagend && NOTBLANKCHAR(s1) && *s1 != '=')
{
tagparam += *(s1 ++);
}
tagparam.MakeLower();
if (s1 < tagend && *s1 == '=')
{
s2 = ++s1;
NEXTCHAR;
if (s1 < tagend)
{
char delim = ' ';
if (*s1 == '\"')
{
delim = '\"';
s1++;
}
else
if (*s1 == '\'')
{
delim = '\'';
s1++;
}
while (s1 < tagend)
{
if (delim == ' ' && (*s1 == ' ' || *s1 == '\t' ||
*s1 == '\r' || *s1 == '\n' ||
*s1 == '\'' || *s1 == '\"'))
{
break;
}
else
if (delim == *s1)
{
s1++;
break;
}
else
{
tagvalue += *s1;
s1++;
}
}
unescape(tagvalue);
if (!tagname.Compare("base") && !tagparam.Compare("href"))
{
base = tagvalue;
}
else
if (tagLink(tagname, tagparam))
{
CString exp = expandedURL(tagvalue, base);
int hash = exp.Find('#');
if (hash != -1)
{
exp = exp.Left(hash);
}
int x1, x2 = exp.GetLength();
CString exp2;
for (x1 = 0; x1 < x2; x1++)
{
char c = exp[x1];
if (c != '\r' && c != '\n')
exp2 += c;
}
exp = exp2;
if (!links -> Find(exp))
{
CURL exptemp(exp);
if (!exptemp.scheme.Compare("http"))
{
if (exptemp.path.IsEmpty())
{
exptemp.path = "/";
exptemp.build(exp);
}
exptemp.fragment.Empty();
switch (session -> m_Mirror)
{
case 0: if (islocal(exp))
{
if (!inserverlist(exptemp.net_loc, session -> m_Exclude))
{
links -> AddTail(exp);
AddLog("ADD", exp);
}
if (session -> m_LocalURLs)
{
int i = s2 - data;
m_File.Write(data, i);
len -= i;
data = s2;
i = s1 - s2;
len -= i;
data = s1;
CString temp = makelocal(exp, base);
if (delim != ' ')
{
temp = delim + temp + delim;
}
m_File.Write((LPCSTR)temp, temp.GetLength());
}
}
break;
case 1: if (!inserverlist(exptemp.net_loc, session -> m_Exclude) &&
exptemp.net_loc == session -> url.net_loc)
{
links -> AddTail(exp);
AddLog("ADD", exp);
}
break;
case 2: if (!inserverlist(exptemp.net_loc, session -> m_Exclude) &&
domain(exptemp.net_loc) == domain(session -> url.net_loc))
{
links -> AddTail(exp);
AddLog("ADD", exp);
}
break;
case 3: if (!inserverlist(exptemp.net_loc, session -> m_Exclude))
{
links -> AddTail(exp);
AddLog("ADD", exp);
}
break;
}
}
}
}
}
}
}
}
}
else
{
s1++;
}
}
i = end - start;
m_File.Write(data, len - i);
memcpy(data2, start, i);
htmltemp.SetSize(i);
}
else
{
m_File.Write(odata, len);
}
return 1;
}
BOOL CHTTPSocket::tagLink(CString name, CString param)
{
return (name == "a" && param == "href") ||
(name == "area" && param == "href") ||
(name == "img" && param == "src") ||
(name == "body" && param == "background") ||
(name == "script" && param == "src") ||
(name == "frame" && param == "src") ||
(name == "layer" && param == "src") ||
(name == "embed" && param == "src") ||
(name == "link" && param == "src");
}
CString CHTTPSocket::expandedURL(CString rel, CString base)
{
CString expanded(base);
CURL urel(rel);
CURL ubase(base);
CURL *uexpanded = urel.expand(&ubase);
uexpanded -> build(expanded);
delete uexpanded;
return expanded;
}
CString CHTTPSocket::getfilename(CString url)
{
CURL uurl(url);
CURL ubase(session -> m_BaseURL);
if (session -> m_FullName || uurl.net_loc.Compare(ubase.net_loc) != 0)
{
CString temp = uurl.path;
return convertname((uurl.net_loc) + temp);
}
CString purl = getpath(uurl.path);
CString pbase = getpath(ubase.path);
CString purlstart = purl.Left(pbase.GetLength());
CString res;
if (!pbase.Compare(purlstart))
{
res = convertname(purl.Mid(pbase.GetLength()) + getname(uurl.path));
}
else
{
res = convertname(purl);
}
if (session -> m_LongFileName == 1)
{
res = convert83(res);
}
else
if (session -> m_LongFileName == 2)
{
res = convert83c(res);
}
return res;
}
CString CHTTPSocket::getpath(CString str)
{
CString result;
int i = str.GetLength() - 1;
while (i > 0 && str[i] != '/' && str[i] != '\\') i--;
if (i)
{
result = str.Left(i + 1);
}
if (result.IsEmpty())
{
result = "/";
}
return result;
}
CString CHTTPSocket::getname(CString str)
{
CString result;
int i = str.GetLength() - 1;
while (i > 0 && str[i] != '/' && str[i] != '\\') i--;
if (i)
{
result = str.Mid(i + 1);
}
else
{
result = str;
}
if (result.IsEmpty())
{
return "index.html";
}
else
{
return result;
}
}
int CHTTPSocket::gethex(char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
else
if (c >= 'a' && c <= 'f')
{
return c - 'a' + 10;
}
else
if (c >= 'A' && c <= 'F')
{
return c - 'A' + 10;
}
else
{
return 0;
}
}
CString CHTTPSocket::convertname(CString str)
{
for (int i = 0; i < str.GetLength(); i++)
{
if (str[i] == '%')
{
char c1, c2;
if (i < str.GetLength() - 2)
{
c1 = str[i + 1];
}
else
{
c1 = 0;
}
if (i < str.GetLength() - 3)
{
c2 = str[i + 2];
}
else
{
c2 = 0;
}
strDelete(str, i, 2);
c1 = (gethex(c1) << 4) + gethex(c2);
if (c1 == '/' || c1 == '\\')
{
c1 = '_';
}
str.SetAt(i, c1);
}
}
if (str[str.GetLength() - 1] == '/')
{
str += "index.html";
}
if (str[0] == '/')
{
str = str.Mid(1);
}
for (i = 0; i < str.GetLength(); i++)
{
if (str[i] == '/')
{
str.SetAt(i, '\\');
}
else
if (strchr("<>:\"|?*", str[i]) || str[i] < 32)
{
str.SetAt(i, '_');
}
}
return str;
}
CString CHTTPSocket::strDelete(CString& str, int start, int count)
{
str = str.Left(start) + str.Mid(start + count);
return str;
}
CString CHTTPSocket::convert83frag(CString str)
{
CString ext, name;
if (str[0] == '.')
{
str = str.Mid(1); //dos alatt nem lehet pont a kezdokarakter
}
for (int i = str.GetLength() - 1; i >= 0 && str[i] != '.'; i--);
if (i >= 0)
{
ext = shorten(str.Mid(i + 1), 3);
name = shorten(str.Left(i), 8);
}
else //nincs kiterjesztes
{
name = shorten(str, 8);
}
if (ext.IsEmpty())
{
return name;
}
else
{
return name + "." + ext;
}
}
CString CHTTPSocket::convert83(CString str)
{
CString temp, result;
for (int i = 0; i < str.GetLength(); i++)
{
if (str[i] == '/' || str[i] == '\\')
{
result += convert83frag(temp) + "/";
temp.Empty();
}
else
{
temp += str[i];
}
}
return result + convert83frag(temp);
}
CString CHTTPSocket::shorten(CString str, int max)
{
for (int i = 0; i < str.GetLength(); i++)
{
if (strchr("+,;=[]. ", str[i]))
{
str.SetAt(i, '_');
}
}
while (str.GetLength() > max)
{
i = str.Find('_');
if (i < 0)
{
break;
}
else
{
strDelete(str, i, 1);
}
}
for (i = str.GetLength() - 1; i >= 0 && str[i] >= '0' && str[i] <= '9'; i--);
while (str.GetLength() > max)
{
strDelete(str, i--, 1);
if (i < 0)
{
i = 0;
}
}
return str;
}
CString CHTTPSocket::makelocal(CString url, CString sbase)
{
CString purl = getpath(url);
CString pbase = getpath(sbase);
CString local, diff;
for (int i = 0; i < purl.GetLength() && i < pbase.GetLength() && purl[i] == pbase[i]; i++);
diff = pbase.Mid(i);
url = url.Mid(i);
for (int j = 0; j < diff.GetLength(); j++)
{
if (diff[j] == '/')
{
local += "../";
}
}
return local + url;
}
int CHTTPSocket::initfile()
{
for (int i = 0; i < m_filename.GetLength(); i++)
{
if (m_filename[i] == '/')
{
m_filename.SetAt(i, '\\');
}
}
CString directory = m_filename.Left(m_filename.ReverseFind('\\'));
if (directory.IsEmpty())
{
directory = "C:\\";
}
else
if (directory[directory.GetLength() - 1] != '\\')
{
directory += '\\';
}
if (!CreateDirectoryTree(directory))
{
return 0;
}
else
{
return m_File.Open(m_filename, CFile :: modeCreate | CFile :: modeWrite | CFile::shareDenyWrite);
}
}
int CHTTPSocket::islocal(CString url)
{
CURL uurl(url);
CString purl = getpath(uurl.path);
CString pbase = getpath(session -> url.path);
CString temp = purl.Left(pbase.GetLength());
return uurl.net_loc == basenet_loc &&
temp == pbase;
}
CString CHTTPSocket::shortenc(CString str, int max)
{
for (int i = 0; i < str.GetLength(); i++)
{
if (strchr("+,;=[]. ", str[i]))
{
str.SetAt(i,'_');
}
}
if (str.GetLength() <= max)
{
return str;
}
unsigned long l = crc32(0, (const unsigned char *)(LPCSTR) str, str.GetLength());
char buf[9];
sprintf(buf, "%08lx", l);
return buf;
}
CString CHTTPSocket::convert83fragc(CString str)
{
CString ext, name;
if (str[0] == '.')
{
str = str.Mid(1); //dos alatt nem lehet pont a kezdokarakter
}
for (int i = str.GetLength() - 1; i >= 0 && str[i] != '.'; i--);
if (i >= 0)
{
ext = shorten(str.Mid(i + 1), 3);
name = shortenc(str.Left(i), 8);
}
else //nincs kiterjesztes
{
name = shortenc(str, 8);
}
if (ext.IsEmpty())
{
return name;
}
else
{
return name + "." + ext;
}
}
CString CHTTPSocket::convert83c(CString str)
{
CString temp, result;
for (int i = 0; i < str.GetLength(); i++)
{
if (str[i] == '/' || str[i] == '\\')
{
result += convert83fragc(temp) + "/";
temp.Empty();
}
else
{
temp += str[i];
}
}
return result + convert83fragc(temp);
}
CTime CHTTPSocket::RFC1123(CString str)
{
CString wkday[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
CString mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char sday[4], smonth[4];
int year, month, day, hour, min, sec;
if (sscanf((LPCSTR)str, "%3s, %2d %3s %4d %2d:%2d:%2d GMT",
sday, &day, smonth, &year, &hour, &min, &sec) != 7)
{
return CTime :: GetCurrentTime();
}
for (int i = 0; i < 7; i++)
{
if (!wkday[i].Compare(sday))
{
break;
}
}
if (i >= 7)
{
return CTime :: GetCurrentTime();
}
for (i = 0; i < 12; i++)
{
if (!mon[i].Compare(smonth))
{
break;
}
}
if (i >= 12)
{
return CTime :: GetCurrentTime();
}
month = i + 1;
CTime temp(year, month, day, hour, min, sec);
return ValidTime(temp);
}
CTime CHTTPSocket::RFC850(CString str)
{
CString weekday[7] = {"Sunday,", "Monday,", "Tuesday,", "Wednesday,", "Thursday,",
"Friday,", "Saturday,"};
CString mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char sday[12], smonth[4];
int year, month, day, hour, min, sec;
if (sscanf((LPCSTR)str, "%s %2d-%3s-%2d %2d:%2d:%2d GMT",
sday, &day, smonth, &year, &hour, &min, &sec) != 7)
{
return CTime :: GetCurrentTime();
}
for (int i = 0; i < 7; i++)
{
if (!weekday[i].Compare(sday))
{
break;
}
}
if (i >= 7)
{
return CTime :: GetCurrentTime();
}
for (i = 0; i < 12; i++)
{
if (!mon[i].Compare(smonth))
{
break;
}
}
if (i >= 12)
{
return CTime :: GetCurrentTime();
}
month = i + 1;
if (year < 70)
{
year += 2000;
}
else
{
year += 1900;
}
CTime temp(year, month, day, hour, min, sec);
return ValidTime(temp);
}
CTime CHTTPSocket::asc(CString str)
{
CString wkday[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
CString mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char sday[4], smonth[4];
int year, month, day, hour, min, sec;
if (sscanf((LPCSTR)str, "%3s %3s %2d %02d:%02d:%02d %4d",
sday, smonth, &day, &hour, &min, &sec, &year) != 7)
{
return CTime :: GetCurrentTime();
}
for (int i = 0; i < 7; i++)
{
if (!wkday[i].Compare(sday))
{
break;
}
}
if (i >= 7)
{
return CTime :: GetCurrentTime();
}
for (i = 0; i < 12; i++)
{
if (!mon[i].Compare(smonth))
{
break;
}
}
if (i >= 12)
{
return CTime :: GetCurrentTime();
}
month = i + 1;
CTime temp(year, month, day, hour, min, sec);
return ValidTime(temp);
}
CTime CHTTPSocket::ValidTime(CTime time)
{
if (time.GetYear() >= 1980 &&
time.GetMonth() >= 1 && time.GetMonth() <= 12 &&
time.GetDay() >= 1 && time.GetDay() <= 31 &&
time.GetHour() >= 0 && time.GetHour() < 24 &&
time.GetMinute() >= 0 && time.GetMinute() < 60 &&
time.GetSecond() >= 0 && time.GetSecond() < 60)
{
return time;
}
else
{
return CTime :: GetCurrentTime();
}
}
CString CHTTPSocket::FormatTime(CTime time)
{
return time.Format("%a, %d %b %Y %H:%M:%S GMT");
}
BOOL CHTTPSocket::inserverlist(CString server, CString list)
{
CString temp;
int i = 0;
while (i < list.GetLength())
{
if (list[i] == ';')
{
temp.TrimLeft();
temp.TrimRight();
if (regularCompare(server, temp))
{
return TRUE;
}
temp = "";
}
else
{
temp += list[i];
}
i++;
}
temp.TrimLeft();
temp.TrimRight();
return regularCompare(server, temp);
}
BOOL CHTTPSocket::regularCompare(LPCSTR str, LPCSTR mask)
{
while (*str && *mask)
{
if (*mask == '?')
{
str++;
mask++;
}
else
if (*mask == '*')
{
int b = 0;
while (*mask == '*') mask++;
while (*str && !b)
{
str++;
if (regularCompare(str, mask))
{
b = 1;
}
}
if (!b)
{
break;
}
}
else
if (*str == *mask)
{
str++;
mask++;
}
else
{
return 0;
}
}
return *str == *mask;
}
CString CHTTPSocket::mimeencode(CString str)
{
const char table[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
unsigned char c1, c2, c3, e1, e2, e3, e4;
int i = 0, c = str.GetLength();
CString res;
while (i < c)
{
c1 = str[i];
if (i + 1 < c)
{
c2 = str[i + 1];
}
else
{
c2 = 0;
}
if (i + 2 < c)
{
c3 = str[i + 2];
}
else
{
c3 = 0;
}
e1 = c1 >> 2; //111111 112222 222233 333333
e2 = ((c1 & 0x03) << 4) + (c2 >> 4);
e3 = ((c2 & 0x0f) << 2) + (c3 >> 6);
e4 = c3 & 0x3f;
res = res + table[e1] + table[e2];
if (i + 1 < c)
{
res += table[e3];
}
else
{
res += '=';
}
if (i + 2 < c)
{
res += table[e4];
}
else
{
res += '=';
}
i += 3;
}
return res;
}
void CHTTPSocket::AddDump(CString str)
{
str += "\r\n";
// ((CMirrorItApp *)AfxGetApp()) -> theDumpFile.Write((LPCSTR)str, str.GetLength());
}
void CHTTPSocket::AddLog(CString type, CString str)
{
CString temp;
int i = str.GetLength(), j = 0;
while (j < i)
{
switch(str[j])
{
case '\r': break;
case '\n': temp += "\n";
if (j < i - 1)
temp = type + "-" + temp;
else
temp = type + " " + temp;
((CMirrorItApp *)AfxGetApp()) -> theLogFile.WriteString(temp);
temp.Empty();
break;
default: temp += str[j];
break;
}
j++;
}
if (temp.IsEmpty()) return;
temp = type + " " + temp + "\n";
((CMirrorItApp *)AfxGetApp()) -> theLogFile.WriteString(temp);
}
int CreateDirectoryTree(CString dir)
{
int UNC = dir.GetLength() > 2 && dir[0] == '\\' && dir[1] == '\\';
int j;
CString temp;
if (UNC)
{
for (j = 2; j < dir.GetLength() && dir[j] != '\\'; j++);
temp = dir.Left(++j);
}
else
{
temp = dir.Left(3);
j = 3;
}
for (int i = j; i < dir.GetLength(); i++)
{
if (dir[i] == '\\')
{
int j = CreateDirectory2(temp);
if (!j) return 0;
temp += '\\';
}
else
{
temp += dir[i];
}
}
if (!temp.IsEmpty() && temp[temp.GetLength() - 1] != '\\')
{
return CreateDirectory2(temp);
}
else
{
return 1;
}
}
int CreateDirectory2(CString dir)
{
WIN32_FIND_DATA fd;
HANDLE fh = FindFirstFile((LPCSTR)dir, &fd);
if (fh == INVALID_HANDLE_VALUE)
{
return CreateDirectory((LPCSTR)dir, NULL);
}
FindClose(fh);
return 1;
}
CString CHTTPSocket::domain(CString str)
{
int i = str.ReverseFind('.');
if (i == -1) return str;
CString last = str.Mid(i);
str = str.Left(i);
i = str.ReverseFind('.');
if (i != -1) str = str.Mid(i + 1);
return str + last;
}
void CHTTPSocket::unescape(CString & str)
{
ReplaceStr(str, "&", "%26");
}
void CHTTPSocket::ReplaceStr(CString & str, CString from, CString to)
{
int i;
while ((i = str.Find(from)) != -1)
{
str = str.Left(i) + to + str.Mid(i + from.GetLength());
}
}