#define AFX_INET_SERVICE_FTP INTERNET_SERVICE_FTP
#define AFX_INET_SERVICE_HTTP INTERNET_SERVICE_HTTP
#define AFX_INET_SERVICE_GOPHER INTERNET_SERVICE_GOPHER
#define AFX_INET_SERVICE_UNK 0x1000
#define AFX_INET_SERVICE_FILE (AFX_INET_SERVICE_UNK+1)
#define AFX_INET_SERVICE_MAILTO (AFX_INET_SERVICE_UNK+2)
#define AFX_INET_SERVICE_MID (AFX_INET_SERVICE_UNK+3)
#define AFX_INET_SERVICE_CID (AFX_INET_SERVICE_UNK+4)
#define AFX_INET_SERVICE_NEWS (AFX_INET_SERVICE_UNK+5)
#define AFX_INET_SERVICE_NNTP (AFX_INET_SERVICE_UNK+6)
#define AFX_INET_SERVICE_PROSPERO (AFX_INET_SERVICE_UNK+7)
#define AFX_INET_SERVICE_TELNET (AFX_INET_SERVICE_UNK+8)
#define AFX_INET_SERVICE_WAIS (AFX_INET_SERVICE_UNK+9)
#define AFX_INET_SERVICE_AFS (AFX_INET_SERVICE_UNK+10)
#define AFX_INET_SERVICE_HTTPS (AFX_INET_SERVICE_UNK+11)
// Global Functions
BOOL ParseURLWorker(LPCTSTR pstrURL,
LPURL_COMPONENTS lpComponents, DWORD& dwServiceType,
INTERNET_PORT& nPort, DWORD dwFlags)
{
// this function will return bogus stuff if lpComponents
// isn't set up to copy the components
assert(lpComponents != NULL && pstrURL != NULL);
if (lpComponents == NULL || pstrURL == NULL)
return FALSE;
assert(lpComponents->dwHostNameLength == 0 ||
lpComponents->lpszHostName != NULL);
assert(lpComponents->dwUrlPathLength == 0 ||
lpComponents->lpszUrlPath != NULL);
assert(lpComponents->dwUserNameLength == 0 ||
lpComponents->lpszUserName != NULL);
assert(lpComponents->dwPasswordLength == 0 ||
lpComponents->lpszPassword != NULL);
//ASSERT(AfxIsValidAddress(lpComponents, sizeof(URL_COMPONENTS), TRUE));
LPTSTR pstrCanonicalizedURL;
TCHAR szCanonicalizedURL[INTERNET_MAX_URL_LENGTH];
DWORD dwNeededLength = INTERNET_MAX_URL_LENGTH;
BOOL bRetVal;
BOOL bMustFree = FALSE;
// Decoding is done in InternetCrackUrl/UrlUnescape
// so we don't need the ICU_DECODE flag here.
DWORD dwCanonicalizeFlags = dwFlags &
(ICU_NO_ENCODE | ICU_NO_META |
ICU_ENCODE_SPACES_ONLY | ICU_BROWSER_MODE);
DWORD dwCrackFlags = 0;
BOOL bUnescape = FALSE;
if((dwFlags & (ICU_ESCAPE | ICU_DECODE)) && (lpComponents->dwUrlPathLength != 0) )
{
// We use only the ICU_ESCAPE flag for decoding even if
// ICU_DECODE is passed.
// Also, if ICU_BROWSER_MODE is passed we do the unescaping
// manually because InternetCrackUrl doesn't do
// Browser mode unescaping
if (dwFlags & ICU_BROWSER_MODE)
bUnescape = TRUE;
else
dwCrackFlags |= ICU_ESCAPE;
}
bRetVal = InternetCanonicalizeUrl(pstrURL, szCanonicalizedURL,
&dwNeededLength, dwCanonicalizeFlags);
if (!bRetVal)
{
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
pstrCanonicalizedURL = new TCHAR[dwNeededLength];
if (pstrCanonicalizedURL == NULL)
return FALSE;
bMustFree = TRUE;
bRetVal = InternetCanonicalizeUrl(pstrURL, pstrCanonicalizedURL,
&dwNeededLength, dwCanonicalizeFlags);
if (!bRetVal)
{
delete [] pstrCanonicalizedURL;
return FALSE;
}
}
else
pstrCanonicalizedURL = szCanonicalizedURL;
// now that it's safely canonicalized, crack it
bRetVal = InternetCrackUrl(pstrCanonicalizedURL, 0,
dwCrackFlags, lpComponents);
if(bUnescape)
{
if((UrlUnescape(lpComponents->lpszUrlPath,NULL,NULL,URL_UNESCAPE_INPLACE | URL_DONT_UNESCAPE_EXTRA_INFO)))
{
if (bMustFree)
delete [] pstrCanonicalizedURL;
return FALSE;
}
lpComponents->dwUrlPathLength = lstrlen(lpComponents->lpszUrlPath);
}
if (bMustFree)
delete [] pstrCanonicalizedURL;
// convert to MFC-style service ID
if (!bRetVal)
dwServiceType = AFX_INET_SERVICE_UNK;
else
{
nPort = lpComponents->nPort;
switch (lpComponents->nScheme)
{
case INTERNET_SCHEME_FTP:
dwServiceType = AFX_INET_SERVICE_FTP;
break;
case INTERNET_SCHEME_GOPHER:
dwServiceType = AFX_INET_SERVICE_GOPHER;
break;
case INTERNET_SCHEME_HTTP:
dwServiceType = AFX_INET_SERVICE_HTTP;
break;
case INTERNET_SCHEME_HTTPS:
dwServiceType = AFX_INET_SERVICE_HTTPS;
break;
case INTERNET_SCHEME_FILE:
dwServiceType = AFX_INET_SERVICE_FILE;
break;
case INTERNET_SCHEME_NEWS:
dwServiceType = AFX_INET_SERVICE_NNTP;
break;
case INTERNET_SCHEME_MAILTO:
dwServiceType = AFX_INET_SERVICE_MAILTO;
break;
default:
dwServiceType = AFX_INET_SERVICE_UNK;
}
}
return bRetVal;
}
BOOL ParseURL(LPCTSTR pstrURL, DWORD& dwServiceType,
string& strServer, string& strObject, INTERNET_PORT& nPort)
{
dwServiceType = AFX_INET_SERVICE_UNK;
assert(pstrURL != NULL);
if (pstrURL == NULL)
return FALSE;
URL_COMPONENTS urlComponents;
memset(&urlComponents, 0, sizeof(URL_COMPONENTS));
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
urlComponents.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
urlComponents.lpszHostName = new char[INTERNET_MAX_URL_LENGTH+1];
urlComponents.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
urlComponents.lpszUrlPath = new char[INTERNET_MAX_URL_LENGTH+1];
BOOL bRetVal = ParseURLWorker(pstrURL, &urlComponents,
dwServiceType, nPort, ICU_BROWSER_MODE);
strServer = urlComponents.lpszHostName;
strObject = urlComponents.lpszUrlPath;
delete urlComponents.lpszHostName;
delete urlComponents.lpszUrlPath;
return bRetVal;
}
BOOL HttpQueryStatusCode(HINTERNET hRequest, DWORD& dwStatusCode)
{
CHAR szBuffer[80];
DWORD dwLen = _countof(szBuffer);
BOOL bRet;
bRet = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE,
szBuffer, &dwLen, NULL);
if (bRet)
dwStatusCode = (DWORD)atol(szBuffer);
return bRet;
}
set dict;
string cookies;
dict.insert("Max-Age");
dict.insert("expires");
dict.insert("domain");
dict.insert("path");
dict.insert("secure");
dict.insert("HttpOnly");
string HttpGet(LPCTSTR url, const string& queryString)
{
string result;
DWORD dwVersion = GetVersion();
stringstream agent;
agent << "Mozilla/4.0 (System " << (int)LOBYTE(LOWORD(dwVersion)) << ".";
agent << (int)HIBYTE(LOWORD(dwVersion)) << "." << (int)HIWORD(dwVersion) << "; Fyter HTTP Module)";
stringstream req;
//req << "Accept: */*/r/n";//Range: bytes=%u-/r/n
req << "Accept-Language:zh-cn/r/n";
if( !cookies.empty() )
req << "Cookie:" + cookies + "/r/n";
req << "Content-Type:application/x-www-form-urlencoded/r/n/r/n";
string finalURL = url;
finalURL += queryString;
string host;
string obj;
DWORD type;
INTERNET_PORT port;
if( !ParseURL(finalURL.c_str(), type, host, obj, port) )
goto close;
HINTERNET hInternet = InternetOpen(agent.str().c_str(),
INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
HINTERNET hSession = InternetConnect(hInternet, host.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
LPSTR szAccept[] = {"text/*" , NULL};
HINTERNET hRequest = HttpOpenRequest(hSession, "GET", obj.c_str(),
NULL, NULL, (LPCSTR*)szAccept, INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD, 0);
HttpSendRequest(hRequest, req.str().c_str(), -1, NULL, 0);
LPSTR lpszData; // 数据缓冲
DWORD dwSize; // 缓冲尺寸
DWORD dwDownloaded; // 下载的长度
DWORD status = 0;
if(!HttpQueryStatusCode(hRequest, status))
goto close;
if( status < 200 || status >= 300)
goto close;
char value[1000];
DWORD valueLen = sizeof(value);
if(HttpQueryInfo(hRequest, HTTP_QUERY_SET_COOKIE, value, &valueLen, 0))
{
stringstream ss(value);
string sub;
cookies.clear();
while(getline(ss,sub,';'))
{
stringstream ss2(sub);
string sub2;
getline(ss2,sub2,'=');
sub2.erase(0, sub2.find_first_not_of(" /t/n/r"));
sub2.erase(sub2.find_last_not_of(" /t/n/r")+1);
if(dict.find(sub2) == dict.end())
{
cookies = sub + ";";
}
}
}
// 接收数据循环
while(1)
{
if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0) || dwSize == 0 )
{
break;
}
else
{
lpszData = new char[dwSize+1];
if(!InternetReadFile(hRequest,(LPVOID)lpszData,dwSize,&dwDownloaded))
{
delete[] lpszData;
break;
}
else
{
//lpszData[dwDownloaded]='/0';
result.insert(result.size() , lpszData, dwDownloaded);
delete[] lpszData;
if (dwDownloaded == 0)
break;
}
}
}
close:
InternetCloseHandle(hRequest);
InternetCloseHandle(hSession);
InternetCloseHandle(hInternet);
return result;
}
string HttpPost(LPCTSTR url, const string& postContent)
{
string result;
DWORD dwVersion = GetVersion();
stringstream agent;
agent << "Mozilla/4.0 (System " << (int)LOBYTE(LOWORD(dwVersion)) << ".";
agent << (int)HIBYTE(LOWORD(dwVersion)) << "." << (int)HIWORD(dwVersion) << "; Fyter HTTP Module)";
stringstream req;
req << "Accept-Language:zh-cn/r/n";
if( !cookies.empty() )
req << "Cookie:" + cookies + "/r/n";
req << "Content-Type:application/x-www-form-urlencoded/r/n";
req << "Content-Length: " << postContent.length() << "/r/n/r/n";
string host;
string obj;
DWORD type;
INTERNET_PORT port;
if( !ParseURL(url, type, host, obj, port) )
goto close;
HINTERNET hInternet = InternetOpen(agent.str().c_str(), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
HINTERNET hSession = InternetConnect(hInternet, host.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
char* szAccept[] = {"text/xml" , NULL};
HINTERNET hRequest = HttpOpenRequest(hSession, "POST", obj.c_str(), NULL, NULL, (LPCSTR*)szAccept, 0, 0);
HttpSendRequest(hRequest, req.str().c_str(), -1, (LPVOID)postContent.c_str(), postContent.length());
LPSTR lpszData; // 数据缓冲
DWORD dwSize; // 缓冲尺寸
DWORD dwDownloaded; // 下载的长度
DWORD status = 0;
if(!HttpQueryStatusCode(hRequest, status))
goto close;
if( status < 200 || status >= 300)
goto close;
char value[1000];
DWORD valueLen = sizeof(value);
if(HttpQueryInfo(hRequest, HTTP_QUERY_SET_COOKIE, value, &valueLen, 0))
{
stringstream ss(value);
string sub;
cookies.clear();
while(getline(ss,sub,';'))
{
stringstream ss2(sub);
string sub2;
getline(ss2,sub2,'=');
sub2.erase(0, sub2.find_first_not_of(" /t/n/r"));
sub2.erase(sub2.find_last_not_of(" /t/n/r")+1);
if(dict.find(sub2) == dict.end())
{
cookies = sub + ";";
}
}
}
// 接收数据循环
while(1)
{
if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0) || dwSize == 0 )
{
break;
}
else
{
lpszData = new char[dwSize+1];
if(!InternetReadFile(hRequest,(LPVOID)lpszData,dwSize,&dwDownloaded))
{
delete[] lpszData;
break;
}
else
{
result.insert(result.size() , lpszData, dwDownloaded);
delete[] lpszData;
if (dwDownloaded == 0)
break; } } } close: InternetCloseHandle(hRequest); InternetCloseHandle(hSession); InternetCloseHandle(hInternet);
return result; }