#include <iostream>
using namespace std;
#include <windows.h>
#include <WinInet.h>
#include <tchar.h>
#pragma comment(lib,"wininet.lib")
struct UrlDownloadCallback {
UrlDownloadCallback() {
progress = NULL;
progress_data = NULL;
write = NULL;
write_data = NULL;
read = NULL;
read_data = NULL;
time_out = 0;
mode = 0;
}
int (*progress)(long now, long total, void* handle);
void* progress_data;
int (*write)(void* buf, long size, long count, void* handle);
void* write_data;
int (*read)(void* buf, long size, long count, void* handle);
void* read_data;
unsigned long time_out;
unsigned long mode; //0:Get 1:post 2:put
unsigned long length; //file length
};
bool UrlDownload(LPTSTR lpszUrl, UrlDownloadCallback* callback) {
HINTERNET hSession = NULL;
HINTERNET hHttpFile = NULL;
BYTE *buffer = NULL;
bool res = false;
if (callback == NULL && callback->write == NULL)
return false;
URL_COMPONENTS urlComponents = { sizeof(URL_COMPONENTS) };
urlComponents.dwHostNameLength = 1;
urlComponents.dwUserNameLength = 1;
urlComponents.dwPasswordLength = 1;
urlComponents.dwUrlPathLength = 1;
urlComponents.dwExtraInfoLength = 1;
if (!InternetCrackUrl(lpszUrl, lstrlen(lpszUrl), 0, &urlComponents))
return false;
hSession = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession == NULL)
goto END;
if (callback->time_out != 0) {
::InternetSetOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &callback->time_out, sizeof(DWORD));
::InternetSetOption(hSession, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, &callback->time_out, sizeof(DWORD));
::InternetSetOption(hSession, INTERNET_OPTION_DATA_SEND_TIMEOUT, &callback->time_out, sizeof(DWORD));
}
hHttpFile = ::InternetOpenUrl(hSession, lpszUrl, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL);
if (hHttpFile == NULL)
goto END;
DWORD filesize = 0;
if (urlComponents.nScheme == INTERNET_SCHEME_FTP) {
filesize = FtpGetFileSize(hHttpFile, NULL);
}
else {
DWORD dwStatus;
DWORD dwSize;
if ((!::HttpQueryInfo(hHttpFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL)) ||
(dwStatus != HTTP_STATUS_OK))
goto END;
if (::HttpQueryInfo(hHttpFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL))
filesize = dwStatus;
}
if (filesize == 0 && callback->progress != NULL) {
callback->progress(0, 0, callback->progress_data);
}
DWORD read = 0;
DWORD total = 0;
DWORD length = 1024;
if (filesize > 0 && filesize < length)
length = filesize;
buffer = (BYTE*)malloc(length);
do {
BOOL ret = ::InternetReadFile(hHttpFile, buffer, length, &read);
if (ret == FALSE)
goto END;
total += read;
if (filesize != 0) {
if (total > filesize)
goto END;
if (callback->progress != NULL)
callback->progress(total, filesize, callback->progress_data);
}
int write_bytes = callback->write(buffer, 1, read, callback->write_data);
if (write_bytes != read)
goto END;
} while (read > 0);
res = true;
END:
if (hHttpFile)
InternetCloseHandle(hHttpFile);
if (hSession)
InternetCloseHandle(hSession);
if (buffer)
free(buffer);
return res;
}
int progress(long now, long total, void* handle)
{
cout << "now:" << now << "total:" << total << endl;
return 0;
}
int write(void* buf, long size, long count, void* handle)
{
FILE* file = (FILE*)handle;
return fwrite(buf, size, count, file);
}
const LPCTSTR szHtmlVerbs[] = {
L"GET",
L"POST",
L"PUT",
};
static inline LPWSTR strndup(LPCTSTR str, UINT max_len)
{
LPWSTR ret;
UINT len;
if (!str)
return NULL;
for (len = 0; len < max_len; len++)
if (str[len] == '\0')
break;
ret = (LPWSTR)malloc(sizeof(TCHAR)*(len + 1));
if (ret) {
memcpy(ret, str, sizeof(TCHAR)*len);
ret[len] = _T('\0');
}
return ret;
}
bool HttpDownload(LPCTSTR lpszUrl, UrlDownloadCallback* callback) {
URL_COMPONENTS urlComponents = { sizeof(URL_COMPONENTS) };
TCHAR *host = NULL, *user = NULL, *pass = NULL, *path = NULL;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BYTE* buffer = NULL;
BOOL ret = FALSE;
bool hr = false;
urlComponents.dwHostNameLength = 1;
urlComponents.dwUserNameLength = 1;
urlComponents.dwPasswordLength = 1;
urlComponents.dwUrlPathLength = 1;
urlComponents.dwExtraInfoLength = 1;
if (!InternetCrackUrl(lpszUrl, lstrlen(lpszUrl), 0, &urlComponents))
return false;
if (urlComponents.nScheme == INTERNET_SCHEME_GOPHER)
goto END;
host = strndup(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
path = strndup(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
if (urlComponents.dwUserNameLength)
user = strndup(urlComponents.lpszUserName, urlComponents.dwUserNameLength);
if (urlComponents.dwPasswordLength)
pass = strndup(urlComponents.lpszPassword, urlComponents.dwPasswordLength);
hSession = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession == NULL)
goto END;
if (callback->time_out != 0) {
InternetSetOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &callback->time_out, sizeof(DWORD));
InternetSetOption(hSession, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, &callback->time_out, sizeof(DWORD));
InternetSetOption(hSession, INTERNET_OPTION_DATA_SEND_TIMEOUT, &callback->time_out, sizeof(DWORD));
}
DWORD filesize = 0;
DWORD dwFlags = INTERNET_FLAG_RELOAD |INTERNET_FLAG_NO_CACHE_WRITE;
if (urlComponents.nScheme == INTERNET_SCHEME_FTP) {
hConnect = InternetConnect(hSession, host, urlComponents.nPort, user, pass, INTERNET_SERVICE_FTP, dwFlags, 0);
if (hConnect == NULL)
goto END;
hRequest = FtpOpenFile(hConnect, path, GENERIC_READ, dwFlags, 0);
if (hRequest == NULL)
goto END;
filesize = FtpGetFileSize(hRequest, NULL);
}
else {
if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS)
dwFlags |= INTERNET_FLAG_SECURE; //| SECURITY_IGNORE_ERROR_MASK | SECURITY_INTERNET_MASK |INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP;
hConnect = InternetConnect(hSession, host, urlComponents.nPort, user, pass, INTERNET_SERVICE_HTTP, dwFlags, 0);
if (hConnect == NULL)
goto END;
static const WCHAR szStars[] = { '*','/','*', 0 };
LPCWSTR accept[2] = { szStars, NULL };
hRequest = HttpOpenRequest(hConnect, szHtmlVerbs[callback->mode], path, NULL, NULL, accept, dwFlags, 0);
if (hRequest == NULL)
goto END;
/*
for (int i = 0; i < count; ++i) {
HttpAddRequestHeaders(hRequest, header[i], -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
}
*/
if (callback->mode > 0 && callback->read) {
INTERNET_BUFFERS ib = { sizeof(INTERNET_BUFFERS) };
ib.dwBufferTotal = callback->length;
ret = HttpSendRequestEx(hRequest, &ib, NULL, 0, 0);
if (ret == FALSE)
goto END;
DWORD count = 0;
DWORD bytesWritten = 0;
buffer = (BYTE*)malloc(1024);
do {
count = callback->read(buffer, 1, 1024, callback->read_data);
ret = InternetWriteFile(hRequest, buffer, count, &bytesWritten);
if (ret == FALSE || bytesWritten != count)
goto END;
} while (count > 0);
ret = HttpEndRequest(hRequest, 0, 0, 0);
if (ret == FALSE)
goto END;
}
else if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0))
goto END;
DWORD dwStatus;
DWORD dwSize = sizeof(DWORD);
if ((!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL)) ||
(dwStatus != HTTP_STATUS_OK))
goto END;
if (::HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL))
filesize = dwStatus;
}
if (callback->write) {
if (filesize == 0 && callback->progress != NULL) {
callback->progress(0, 0, callback->progress_data);
}
DWORD read = 0;
DWORD total = 0;
DWORD length = 1024;
if (filesize > 0 && filesize < length && buffer != NULL)
length = filesize;
if (buffer == NULL)
buffer = (BYTE*)malloc(length);
do {
ret = ::InternetReadFile(hRequest, buffer, length, &read);
if (ret == FALSE)
goto END;
total += read;
if (filesize != 0) {
if (total > filesize)
goto END;
if (callback->progress != NULL)
callback->progress(total, filesize, callback->progress_data);
}
int write_bytes = callback->write(buffer, 1, read, callback->write_data);
if (write_bytes != read)
goto END;
} while (read > 0);
}
hr = true;
END:
if (host != NULL)
free(host);
if (user != NULL)
free(user);
if (pass != NULL)
free(pass);
if (path != NULL)
free(path);
if (buffer != NULL)
free(buffer);
if (hRequest)
InternetCloseHandle(hRequest);
if (hConnect)
InternetCloseHandle(hConnect);
if (hSession)
InternetCloseHandle(hSession);
return hr;
}
int main()
{
FILE* file = fopen("d:\\1.exe", "w+b");
UrlDownloadCallback _UrlDownloadCallback;
_UrlDownloadCallback.progress = progress;
_UrlDownloadCallback.write = write;
_UrlDownloadCallback.write_data = file;
//UrlDownload(L"https://xxxxxx, &_UrlDownloadCallback);
UrlDownload(L"ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-1-10-0-release/include/md5.sum", &_UrlDownloadCallback);
_UrlDownloadCallback.mode = 0;
//HttpDownload(L"https://xxxxx",&_UrlDownloadCallback);
//HttpDownload(L"ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-1-10-0-release/include/md5.sum", &_UrlDownloadCallback);
if (file)
fclose(file);
return 0;
}
using namespace std;
#include <windows.h>
#include <WinInet.h>
#include <tchar.h>
#pragma comment(lib,"wininet.lib")
struct UrlDownloadCallback {
UrlDownloadCallback() {
progress = NULL;
progress_data = NULL;
write = NULL;
write_data = NULL;
read = NULL;
read_data = NULL;
time_out = 0;
mode = 0;
}
int (*progress)(long now, long total, void* handle);
void* progress_data;
int (*write)(void* buf, long size, long count, void* handle);
void* write_data;
int (*read)(void* buf, long size, long count, void* handle);
void* read_data;
unsigned long time_out;
unsigned long mode; //0:Get 1:post 2:put
unsigned long length; //file length
};
bool UrlDownload(LPTSTR lpszUrl, UrlDownloadCallback* callback) {
HINTERNET hSession = NULL;
HINTERNET hHttpFile = NULL;
BYTE *buffer = NULL;
bool res = false;
if (callback == NULL && callback->write == NULL)
return false;
URL_COMPONENTS urlComponents = { sizeof(URL_COMPONENTS) };
urlComponents.dwHostNameLength = 1;
urlComponents.dwUserNameLength = 1;
urlComponents.dwPasswordLength = 1;
urlComponents.dwUrlPathLength = 1;
urlComponents.dwExtraInfoLength = 1;
if (!InternetCrackUrl(lpszUrl, lstrlen(lpszUrl), 0, &urlComponents))
return false;
hSession = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession == NULL)
goto END;
if (callback->time_out != 0) {
::InternetSetOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &callback->time_out, sizeof(DWORD));
::InternetSetOption(hSession, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, &callback->time_out, sizeof(DWORD));
::InternetSetOption(hSession, INTERNET_OPTION_DATA_SEND_TIMEOUT, &callback->time_out, sizeof(DWORD));
}
hHttpFile = ::InternetOpenUrl(hSession, lpszUrl, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL);
if (hHttpFile == NULL)
goto END;
DWORD filesize = 0;
if (urlComponents.nScheme == INTERNET_SCHEME_FTP) {
filesize = FtpGetFileSize(hHttpFile, NULL);
}
else {
DWORD dwStatus;
DWORD dwSize;
if ((!::HttpQueryInfo(hHttpFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL)) ||
(dwStatus != HTTP_STATUS_OK))
goto END;
if (::HttpQueryInfo(hHttpFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL))
filesize = dwStatus;
}
if (filesize == 0 && callback->progress != NULL) {
callback->progress(0, 0, callback->progress_data);
}
DWORD read = 0;
DWORD total = 0;
DWORD length = 1024;
if (filesize > 0 && filesize < length)
length = filesize;
buffer = (BYTE*)malloc(length);
do {
BOOL ret = ::InternetReadFile(hHttpFile, buffer, length, &read);
if (ret == FALSE)
goto END;
total += read;
if (filesize != 0) {
if (total > filesize)
goto END;
if (callback->progress != NULL)
callback->progress(total, filesize, callback->progress_data);
}
int write_bytes = callback->write(buffer, 1, read, callback->write_data);
if (write_bytes != read)
goto END;
} while (read > 0);
res = true;
END:
if (hHttpFile)
InternetCloseHandle(hHttpFile);
if (hSession)
InternetCloseHandle(hSession);
if (buffer)
free(buffer);
return res;
}
int progress(long now, long total, void* handle)
{
cout << "now:" << now << "total:" << total << endl;
return 0;
}
int write(void* buf, long size, long count, void* handle)
{
FILE* file = (FILE*)handle;
return fwrite(buf, size, count, file);
}
const LPCTSTR szHtmlVerbs[] = {
L"GET",
L"POST",
L"PUT",
};
static inline LPWSTR strndup(LPCTSTR str, UINT max_len)
{
LPWSTR ret;
UINT len;
if (!str)
return NULL;
for (len = 0; len < max_len; len++)
if (str[len] == '\0')
break;
ret = (LPWSTR)malloc(sizeof(TCHAR)*(len + 1));
if (ret) {
memcpy(ret, str, sizeof(TCHAR)*len);
ret[len] = _T('\0');
}
return ret;
}
bool HttpDownload(LPCTSTR lpszUrl, UrlDownloadCallback* callback) {
URL_COMPONENTS urlComponents = { sizeof(URL_COMPONENTS) };
TCHAR *host = NULL, *user = NULL, *pass = NULL, *path = NULL;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BYTE* buffer = NULL;
BOOL ret = FALSE;
bool hr = false;
urlComponents.dwHostNameLength = 1;
urlComponents.dwUserNameLength = 1;
urlComponents.dwPasswordLength = 1;
urlComponents.dwUrlPathLength = 1;
urlComponents.dwExtraInfoLength = 1;
if (!InternetCrackUrl(lpszUrl, lstrlen(lpszUrl), 0, &urlComponents))
return false;
if (urlComponents.nScheme == INTERNET_SCHEME_GOPHER)
goto END;
host = strndup(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
path = strndup(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
if (urlComponents.dwUserNameLength)
user = strndup(urlComponents.lpszUserName, urlComponents.dwUserNameLength);
if (urlComponents.dwPasswordLength)
pass = strndup(urlComponents.lpszPassword, urlComponents.dwPasswordLength);
hSession = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession == NULL)
goto END;
if (callback->time_out != 0) {
InternetSetOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &callback->time_out, sizeof(DWORD));
InternetSetOption(hSession, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, &callback->time_out, sizeof(DWORD));
InternetSetOption(hSession, INTERNET_OPTION_DATA_SEND_TIMEOUT, &callback->time_out, sizeof(DWORD));
}
DWORD filesize = 0;
DWORD dwFlags = INTERNET_FLAG_RELOAD |INTERNET_FLAG_NO_CACHE_WRITE;
if (urlComponents.nScheme == INTERNET_SCHEME_FTP) {
hConnect = InternetConnect(hSession, host, urlComponents.nPort, user, pass, INTERNET_SERVICE_FTP, dwFlags, 0);
if (hConnect == NULL)
goto END;
hRequest = FtpOpenFile(hConnect, path, GENERIC_READ, dwFlags, 0);
if (hRequest == NULL)
goto END;
filesize = FtpGetFileSize(hRequest, NULL);
}
else {
if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS)
dwFlags |= INTERNET_FLAG_SECURE; //| SECURITY_IGNORE_ERROR_MASK | SECURITY_INTERNET_MASK |INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP;
hConnect = InternetConnect(hSession, host, urlComponents.nPort, user, pass, INTERNET_SERVICE_HTTP, dwFlags, 0);
if (hConnect == NULL)
goto END;
static const WCHAR szStars[] = { '*','/','*', 0 };
LPCWSTR accept[2] = { szStars, NULL };
hRequest = HttpOpenRequest(hConnect, szHtmlVerbs[callback->mode], path, NULL, NULL, accept, dwFlags, 0);
if (hRequest == NULL)
goto END;
/*
for (int i = 0; i < count; ++i) {
HttpAddRequestHeaders(hRequest, header[i], -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
}
*/
if (callback->mode > 0 && callback->read) {
INTERNET_BUFFERS ib = { sizeof(INTERNET_BUFFERS) };
ib.dwBufferTotal = callback->length;
ret = HttpSendRequestEx(hRequest, &ib, NULL, 0, 0);
if (ret == FALSE)
goto END;
DWORD count = 0;
DWORD bytesWritten = 0;
buffer = (BYTE*)malloc(1024);
do {
count = callback->read(buffer, 1, 1024, callback->read_data);
ret = InternetWriteFile(hRequest, buffer, count, &bytesWritten);
if (ret == FALSE || bytesWritten != count)
goto END;
} while (count > 0);
ret = HttpEndRequest(hRequest, 0, 0, 0);
if (ret == FALSE)
goto END;
}
else if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0))
goto END;
DWORD dwStatus;
DWORD dwSize = sizeof(DWORD);
if ((!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL)) ||
(dwStatus != HTTP_STATUS_OK))
goto END;
if (::HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL))
filesize = dwStatus;
}
if (callback->write) {
if (filesize == 0 && callback->progress != NULL) {
callback->progress(0, 0, callback->progress_data);
}
DWORD read = 0;
DWORD total = 0;
DWORD length = 1024;
if (filesize > 0 && filesize < length && buffer != NULL)
length = filesize;
if (buffer == NULL)
buffer = (BYTE*)malloc(length);
do {
ret = ::InternetReadFile(hRequest, buffer, length, &read);
if (ret == FALSE)
goto END;
total += read;
if (filesize != 0) {
if (total > filesize)
goto END;
if (callback->progress != NULL)
callback->progress(total, filesize, callback->progress_data);
}
int write_bytes = callback->write(buffer, 1, read, callback->write_data);
if (write_bytes != read)
goto END;
} while (read > 0);
}
hr = true;
END:
if (host != NULL)
free(host);
if (user != NULL)
free(user);
if (pass != NULL)
free(pass);
if (path != NULL)
free(path);
if (buffer != NULL)
free(buffer);
if (hRequest)
InternetCloseHandle(hRequest);
if (hConnect)
InternetCloseHandle(hConnect);
if (hSession)
InternetCloseHandle(hSession);
return hr;
}
int main()
{
FILE* file = fopen("d:\\1.exe", "w+b");
UrlDownloadCallback _UrlDownloadCallback;
_UrlDownloadCallback.progress = progress;
_UrlDownloadCallback.write = write;
_UrlDownloadCallback.write_data = file;
//UrlDownload(L"https://xxxxxx, &_UrlDownloadCallback);
UrlDownload(L"ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-1-10-0-release/include/md5.sum", &_UrlDownloadCallback);
_UrlDownloadCallback.mode = 0;
//HttpDownload(L"https://xxxxx",&_UrlDownloadCallback);
//HttpDownload(L"ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-1-10-0-release/include/md5.sum", &_UrlDownloadCallback);
if (file)
fclose(file);
return 0;
}