VC++ cpprestsdkを使ったHTTP通信(ファイルダウンロード)

vc-cpprestsdk-file-downloadのアイキャッチ画像 Windows

前回の記事で、MicrosoftがGitHubでオープンソースとして公開しているcpprestsdkを使い、VC++でHTTP通信(POST/GET/PUT/DELETEといったREST APIの実行)ができるようになりました。

今回は、cpprestsdkを使ったファイルダウンロードの方法を解説します。

環境構築

まずは前回の記事の通り、環境構築を行って下さい。
その上で、サンプルコードを実装していきます。

サンプルコード

HttpClient

「C:\src\components\component1\component1.vcxproj」のHttpClientクラスに、ファイルダウンロード用のメソッドを追加します。

src/components/component1/HttpClient.h

#pragma once

#include <stdio.h>
#include "cpprest/http_client.h"
#include "cpprest/filestream.h"

using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;

// HTTP(S)クライアント
class HttpClient
{
public:

	// 前回と同じPOST/GET/PUT/DELETEなどのpublicメソッド

	// ファイルダウンロード
	int download(const std::string& inUrl, const std::string& inFilePath);

private:

	// 前回と同じPOST/GET/PUT/DELETEなどのprivateメソッド

	void _download(istream inBody, size_t inChunk, size_t inLength, size_t inContentLength, streambuf<unsigned char>& outBuff);

	pplx::task<int> _download(const std::string& inUrl, const std::string& inFilePath);

private:

	json::value _m_cResultValue;
	int _m_nStatusCode;
};

src/components/component1/HttpClient.cpp

#include "HttpClient.h"

// 前回と同じPOST/GET/PUT/DELETEなどのpublicメソッド

int HttpClient::download(const std::string& inUrl, const std::string& inFilePath)
{
	try {
		this->_download(inUrl, inFilePath).wait();
	} catch (const std::exception& e) {
		::printf("<!> %s \n", e.what());
		if (this->_m_nStatusCode == 0) return 1;
		else return this->_m_nStatusCode;
	}

	if (this->_m_nStatusCode == 200) return 0;
	else if (this->_m_nStatusCode == 0) return 1;
	else return this->_m_nStatusCode;
}

// 前回と同じPOST/GET/PUT/DELETEなどのprivateメソッド

void HttpClient::_download(istream inBody, size_t inChunk, size_t inLength, size_t inContentLength, streambuf<unsigned char>& outBuff)
{
	size_t nLength = inBody.read(outBuff, inChunk).get();
	if (nLength > 0) {
		::printf("[Download] %llu/%llu \n", inLength + nLength, inContentLength);
		this->_download(inBody, inChunk, inLength + nLength, inContentLength, outBuff);
	} else {
		return;
	}
}

pplx::task<int> HttpClient::_download(const std::string& inUrl, const std::string& inFilePath)
{
	const std::string sUrl = inUrl;
	static std::string sFilePath;
	sFilePath = inFilePath;
	this->_m_cResultValue = json::value::null();
	this->_m_nStatusCode = 0;
	size_t nContentLength(0);

	// 実行タスク生成
	return pplx::create_task([sUrl]
	{
		utility::string_t sUtf16 = utility::conversions::utf8_to_utf16(sUrl);
		sUtf16 = uri::encode_uri(sUtf16, uri::components::component::query);
		http_client cClient(sUtf16);
		http_request cRequest(methods::GET);
		return cClient.request(cRequest);
	}).then([this, &nContentLength, sUrl](http_response cResponse)
	{
		nContentLength = cResponse.headers().content_length();
		if (cResponse.status_code() == status_codes::OK) {
			::printf("[GET] %s success. \n", sUrl.c_str());
		} else {
			::printf("<!> [GET] %s failed. status=%d \n", sUrl.c_str(), cResponse.status_code());
		}
		this->_m_nStatusCode = cResponse.status_code();
		return cResponse.body();
	}).then([this, &nContentLength](istream cStream)
	{
		utility::string_t sUtf16 = utility::conversions::utf8_to_utf16(sFilePath);
		streambuf<unsigned char> cBuff = file_buffer<unsigned char>::open(sUtf16).get();
		if (nContentLength == 0) ::printf("<!> Content length is zero. \n");
		else {
			size_t nChunkSize = nContentLength / 10;
			this->_download(cStream, nChunkSize, 0, nContentLength, cBuff);
		}
		cBuff.close().wait();
		return 0;
	});
}

メインプログラム

メインプログラムのサンプルコードです。

src/components/component1/main.cpp

#include "HttpClient.h"

int main(int argc, const char** argv)
{
	int ret;
	json::value cOutData;

	// URL
	std::string sUrl = "http://localhost/hoge.pdf";	// ダウンロードしたいファイルのURLを指定

	// ダウンロード先
	std::string sLocalFilePath = "C:/hoge.pdf";	// ダウンロード先となるローカルのファイルパスをフルパスで指定

	// REST API実行
	HttpClient cHttpClient;
	ret = cHttpClient.download(sUrl, sLocalFilePath);
	if (ret == 0) {
		::printf("downloaded \n");
	}

	return 0;
}

前回の記事の通りビルドし、component1.exeを実行すると、HTTP通信が実行されます。

以上で、cpprestsdkを使ったHTTP通信(ファイルダウンロード)をすることができるようになりました。

タイトルとURLをコピーしました