HTTPDownloader

08/20/2015 15:46 Daifoku#1
Small snippet to download a simple file to a buffer

header
Code:
#pragma once
class HTTPDownload {
private:
	char * lpszUrl;
	HINTERNET hInternet = NULL; /* The handle to the current Internet session. The handle must have been returned by a previous call to InternetOpen. */
	HINTERNET hFile = NULL; /*Handle returned from a previous call to InternetOpenUrl, FtpOpenFile, or HttpOpenRequest.*/
	DWORD dwNumberOfBytesToRead; /* used for HttpQueryInfo */
	DWORD dwNumberOfBytesRead; /* Pointer to a variable that receives the number of bytes read InternetReadFile sets this value to zero before doing any work or error checking. */
	DWORD dwBufferLength = sizeof(DWORD);
	std::vector<char> buffer;
	unsigned int readCompleteFile(size_t filesize);
	unsigned int readPartialFile(size_t partialSize);
public:
	HTTPDownload();
	~HTTPDownload();
	/**
		Get the content of a previously downloaded file

		@author Daifoku
		@version 20/08/2015 15:00 CEST
		@return	Returns the pointer to a buffer
	*/
	std::vector<char> & getBuffer();

	/**
		Downloads an url to a buffer and returns the filesize.
		Call HTTPDownload::&getBuffer to get the content.

		@author Daifoku
		@version 20/08/2015 16:15 CEST
		@param url The url to download. has to start with ftp://, http:// or https://
		@return Returns the filesize if there was no error
				Returns 0 if InternetOpenUrlA fails
				Returns -1 if InternetOpenA fails
	*/
	int download(char * url); 
};
Source
Code:
/**
	HTTPDownload.cpp
	Purpose: Download a file to a buffer

	@author Daifoku
	@version 1.0 20/08/2015 15:00 CEST
*/

#include <stdafx.h>
#include "HTTPDownload.h"
#include <vector>
#include <winsock.h> /* InternetReadFile */
#include <wininet.h> /* InternetReadFile */
#pragma comment(lib, "wininet.lib")

unsigned int HTTPDownload::readCompleteFile(size_t filesize)
{
	buffer.resize(filesize + 1);
	do {
		InternetReadFile(hFile, &buffer.at(0), dwNumberOfBytesToRead, &dwNumberOfBytesRead);
	} while (dwNumberOfBytesRead);
	return filesize;

}

unsigned int HTTPDownload::readPartialFile(size_t partialSize)
{
	unsigned int filesize = 0;
	buffer.resize(partialSize + 1);
	do {
		buffer.resize(partialSize + filesize);
		InternetReadFile(hFile, &(buffer.at(filesize)), partialSize, &dwNumberOfBytesRead);
		filesize += dwNumberOfBytesRead;
	} while (dwNumberOfBytesRead);
	buffer.resize(filesize);
	return filesize;
}
HTTPDownload::HTTPDownload() {
	hInternet = InternetOpenA("Hi", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
}
HTTPDownload::~HTTPDownload()
{
	InternetCloseHandle(hInternet);
}
std::vector<char> & HTTPDownload::getBuffer()
{
	return HTTPDownload::buffer;
}
int HTTPDownload::download(char * url)
{
	if (!hInternet) return -1;
	unsigned int fileSize = 0;
	
	hFile = InternetOpenUrlA(hInternet, url, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, NULL);
	if (!hFile) return 0;
	
	if (HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwNumberOfBytesToRead, &dwBufferLength, NULL) && dwNumberOfBytesToRead > 0)
		fileSize = HTTPDownload::readCompleteFile(dwNumberOfBytesToRead);
	else
		fileSize = HTTPDownload::readPartialFile(0x400);
	InternetCloseHandle(hFile);
	return fileSize;
}
example
Code:
HTTPDownload downloader{ };
	size_t fileSize = downloader.download("http://grandfantasia.patch.aeriagames.com/release/ELF/CompressionGameData/version.txt");
	if (fileSize) {
		for (char & c : downloader.getBuffer())
			std::cout << c;
	}