#include "stdafx.h"
#include "HttpDownload.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HttpDownload::HttpDownload()
{
m_isSendMsg=FALSE;
}
HttpDownload::~HttpDownload()
{
}
UINT HttpDownload::Download(CString url,CString saveFile,DWORD fileSize,BOOL isForceGetFileLength,BOOL isForceDown)
{
CHAR szHead[]="Accept: */*/r/n/r/n";
VOID* szTemp[16384];
HINTERNET downFileHandle;
DWORD dwByteToRead = 0;
DWORD dwSizeOfRq = 4;
CFile downFile;
DWORD dwSize=0;
DWORD downTotal=0;
CString tempFileName;
if(m_hSession!=NULL)
{
if(!(downFileHandle=InternetOpenUrl(m_hSession, url, szHead,lstrlenA(szHead), INTERNET_FLAG_RELOAD,0)))
{
InternetCloseHandle(downFileHandle);
return HTTPDOWN_OPENFILEERROR;
}
if(isForceGetFileLength)
{
if(!HttpQueryInfo(downFileHandle, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,(LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
{
InternetCloseHandle(downFileHandle);
return HTTPDOWN_GETFILELENGTHERROR;
}
}else
dwByteToRead=fileSize;
if(!isForceDown)
{
CFileFind findDownload;
if(findDownload.FindFile(saveFile))
{
findDownload.FindNextFile();
DWORD fileLength=findDownload.GetLength();
findDownload.Close();
if(fileLength==dwByteToRead)
{
InternetCloseHandle(downFileHandle);
if(m_isSendMsg)
::PostMessage(m_hwnd,IOM_DOWNLOAD,0,fileLength);
return HTTPDOWN_DOWNLOADSUCCESS;
}
else
{
tempFileName=saveFile+".down";
if(!downFile.Open(tempFileName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite))
{
downFile.Close();
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADCREATEFILEERROR;
}
}
}else
{
findDownload.Close();
tempFileName=saveFile+".down";
if(!findDownload.FindFile(tempFileName))
{
findDownload.Close();
if(!downFile.Open(tempFileName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite))
{
downFile.Close();
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADCREATEFILEERROR;
}
}else
{
findDownload.Close();
if(!downFile.Open(tempFileName,CFile::modeWrite|CFile::shareDenyWrite))
{
downFile.Close();
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADCREATEFILEERROR;
}
DWORD curFileLength=downFile.SeekToEnd();
if(m_isSendMsg)
::PostMessage(m_hwnd,IOM_DOWNLOAD,0,curFileLength);
if(!InternetSetFilePointer(downFileHandle,curFileLength,NULL,0,0))
{
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADSETPOINTERROR;
}
}
}
}else
{
tempFileName=saveFile+".down";
DeleteFile(saveFile);
DeleteFile(tempFileName);
if(!downFile.Open(tempFileName,CFile::modeWrite|CFile::shareDenyWrite))
{
downFile.Close();
return HTTPDOWN_DOWNLOADCREATEFILEERROR;
}
}
do
{
if(!InternetReadFile(downFileHandle, szTemp, 16384, &dwSize) )
{
downFile.Close();
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADREADDATAERROR;
}
if(!dwSize)
break;
else
{
downTotal+=dwSize;
downFile.Write(szTemp,dwSize);
if(m_isSendMsg)
::PostMessage(m_hwnd,IOM_DOWNLOAD,0,dwSize);
}
}while(TRUE);
downFile.Close();
CFile::Rename(tempFileName,saveFile);
InternetCloseHandle(downFileHandle);
return HTTPDOWN_DOWNLOADSUCCESS;
}else
return HTTPDOWN_DOWNLOADSEESSIONNULL;
}
UINT HttpDownload::InitHttpSession()
{
DWORD dwFlags;
InternetGetConnectedState(&dwFlags, 0);
if(!(dwFlags & INTERNET_CONNECTION_PROXY))
{
AfxMessageBox("----1----");
m_hSession = ::InternetOpen("VISALL_DOWNLOAD",INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, NULL, NULL, 0);
}
else
{
AfxMessageBox("----2----");
m_hSession = ::InternetOpen("VISALL_DOWNLOAD",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
}
if(m_hSession==NULL)
return HTTPDOWN_INITSESSIONERROR;
else
return HTTPDOWN_INITSESSIONSUCCESS;
}
UINT HttpDownload::UnInitHttpSession()
{
if(m_hSession)
{
if(InternetCloseHandle(m_hSession))
return HTTPDOWN_UNINITSESSIONSUCCESS;
else
return HTTPDOWN_UNINITSESSIONERROR;
}else
return HTTPDOWN_UNINITSESSIONSUCCESS;
}
void HttpDownload::SetProgressHwnd(HWND hwnd)
{
m_hwnd=hwnd;
}
void HttpDownload::SetProgressMsg(BOOL isSend)
{
m_isSendMsg=isSend;
}
UINT HttpDownload::SetTimeOut(DWORD connectTimeOut,DWORD receiveTimeout,DWORD sendTimeOut)
{
if(m_hSession)
{
if(!InternetSetOption(m_hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &connectTimeOut, sizeof(DWORD)))
return HTTPDOWN_SETTIMEOUTERROR;
if(!InternetSetOption(m_hSession, INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT, &receiveTimeout, sizeof(DWORD)))
return HTTPDOWN_SETTIMEOUTERROR;
if(!InternetSetOption(m_hSession, INTERNET_OPTION_CONTROL_SEND_TIMEOUT, &sendTimeOut, sizeof(DWORD)))
return HTTPDOWN_SETTIMEOUTERROR;
if(!InternetSetOption(m_hSession, INTERNET_OPTION_DATA_SEND_TIMEOUT, &sendTimeOut, sizeof(DWORD)))
return HTTPDOWN_SETTIMEOUTERROR;
if(!InternetSetOption(m_hSession, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, &receiveTimeout, sizeof(DWORD)))
return HTTPDOWN_SETTIMEOUTERROR;
return HTTPDOWN_SETTIMEOUTSUCCESS;
}else
return HTTPDOWN_SETTIMEOUTERROR;
}
#if !defined(AFX_HTTPDOWNLOAD_H__41263D8F_321A_42F0_889F_3ADB44C80EC0__INCLUDED_)
#define AFX_HTTPDOWNLOAD_H__41263D8F_321A_42F0_889F_3ADB44C80EC0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <wininet.h>
#include <mmsystem.h>
const UINT HTTPDOWN_OPENFILEERROR=1;
const UINT HTTPDOWN_GETFILELENGTHERROR=2;
const UINT HTTPDOWN_INITSESSIONERROR=3;
const UINT HTTPDOWN_INITSESSIONSUCCESS=4;
const UINT HTTPDOWN_DOWNLOADSUCCESS=5;
const UINT HTTPDOWN_DOWNLOADCREATEFILEERROR=6;
const UINT HTTPDOWN_DOWNLOADSETPOINTERROR=7;
const UINT HTTPDOWN_DOWNLOADREADDATAERROR=8;
const UINT HTTPDOWN_UNINITSESSIONERROR=9;
const UINT HTTPDOWN_UNINITSESSIONSUCCESS=10;
const UINT HTTPDOWN_SETTIMEOUTSUCCESS=11;
const UINT HTTPDOWN_SETTIMEOUTERROR=12;
const UINT HTTPDOWN_DOWNLOADSEESSIONNULL=13;
class HttpDownload
{
public:
HttpDownload();
virtual ~HttpDownload();
//Operator
public:
UINT Download(CString url,CString saveFile,DWORD fileSize,BOOL isForceGetFileLength,BOOL isForceDown);
void SetProgressHwnd(HWND hwnd);
void SetProgressMsg(BOOL isSend);
UINT InitHttpSession();
UINT UnInitHttpSession();
UINT SetTimeOut(DWORD connectTimeOut,DWORD receiveTimeout,DWORD sendTimeOut);
//Attribtue
private:
HWND m_hwnd;
BOOL m_isSendMsg;
HINTERNET m_hSession;// 会话句柄
#define IOM_DOWNLOAD WM_USER +155
};
#endif // !defined(AFX_HTTPDOWNLOAD_H__41263D8F_321A_42F0_889F_3ADB44C80EC0__INCLUDED_)
================
3. 使用代理服务器
(1)请将dwAccessType设置成INTERNET_OPEN_TYPE_PROXY
(2)设置lpszProxy
(a)代理的格式必须为:[<protocol>=][<scheme>://]<proxy>[:<port>].
(b)其中protocol, scheme://, :port是可选项, 如果忽略这三者, 则它们默认分别为
HTTP, HTTP://, :80. 即默认为HTTP代理.
(c)多个代理必须使用" "(空格)隔开
(d)各种常用代理的使用见如下:
HTTP:
HTTP=HTTP://proxyserver:port
FTP:
FTP:FTP://proxyserver:port
GOPHER
GOPHER=HTTP://proxyserver:port
SOCKS=proxyserver:port
其中前三种都可以在msdn中找到, 但第四种我可是找了N多地方才好不容易找到了. 另外要注意, msdn中明确说明只有安装了IE才能使用SOCKS代理.
---------------------------------------------------------------
The following example code shows how authentication could be handled using InternetSetOption.
HINTERNET hOpenHandle, hResourceHandle;
DWORD dwError, dwStatus;
DWORD dwStatusSize = sizeof(dwStatus);
char strUsername[64], strPassword[64];
hOpenHandle = InternetOpen("Example",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0);
hConnectHandle = InternetConnect(hOpenHandle,
"www.server.com",
INTERNET_INVALID_PORT_NUMBER,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,0);
hResourceHandle = HttpOpenRequest(hConnectHandle, "GET",
"/premium/default.htm",
NULL, NULL, NULL,
INTERNET_FLAG_KEEP_CONNECTION,
0);
resend:
HttpSendRequest(hResourceHandle, NULL, 0, NULL, 0);
HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER |
HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL);
switch (dwStatus)
{
case HTTP_STATUS_PROXY_AUTH_REQ: // Proxy Authentication Required
// Insert code to set strUsername and strPassword.
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
DWORD cchUserLength, cchPasswordLength;
// Insert code to safely determine cchUserLength and
// cchPasswordLength. Insert appropriate error handling code.
InternetSetOption(hResourceHandle,
INTERNET_OPTION_PROXY_USERNAME,
strUsername,
cchUserLength+1);
InternetSetOption(hResourceHandle,
INTERNET_OPTION_PROXY_PASSWORD,
strPassword,
cchPasswordLength+1);
goto resend;
break;
case HTTP_STATUS_DENIED: // Server Authentication Required.
// Insert code to set strUsername and strPassword.
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
DWORD cchUserLength, cchPasswordLength;
// Insert code to safely determine cchUserLength and
// cchPasswordLength. Insert error handling code as
// appropriate.
InternetSetOption(hResourceHandle, INTERNET_OPTION_USERNAME,
strUsername, cchUserLength+1);
InternetSetOption(hResourceHandle, INTERNET_OPTION_PASSWORD,
strPassword, cchPasswordLength+1);
goto resend;
break;
}
// Insert code to read the data from the hResourceHandle
// at this point.
======================================
设置代理服务器的代码:
for example:
INTERNET_PER_CONN_OPTION_LIST List;
INTERNET_PER_CONN_OPTION Option[1];
unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
Option[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
Option[0].Value.pszValue = "http://myproxy:8080";
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
List.pszConnection = NULL;
List.dwOptionCount = 1;
List.dwOptionError = 0;
List.pOptions = Option;
if(!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
printf("InternetQueryOption failed! (%d)/n", GetLastError());
//more detail:
HOWTO: Programmatically Query and Set Proxy Settings Under Internet Explorer