C++ http 클라이언트 요청하기 - HappyHttp

HappyHttp

Visual Studio 2017에서 빌드하면 에러가 난다. 조금 수정이 필요하다.
happyhttp.cpp 파일의 상단에 아래의 전처리를 선언한다.

#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1

개요

  • 오픈 소스 라이브러리. 링크
    • 위에 언급된 수정한 버전은 여기 에 있다.
  • 멀티 플랫폼 지원.
  • happyhttp.h 와 happyhttp.cpp 단 두개의 파일 프로젝트에 포함하면 된다.

예제 - HappyHTTP를 사용한 HTTP Post Request

//HTTP 헤더 선언
const char* headers[] =
	{
		"Connection", "close",
		"Content-type", "application/x-www-form-urlencoded",
		"Accept", "text/plain",
		0
	};

//HTTP BODY 선언
const char* body = "answer=42&name=Bubba";

//연결할 대상을 지정하고 요청 결과에 따른 콜백 함수를 지정한다.
happyhttp::Connection conn("scumways.com", 80);
conn.setcallbacks(OnBegin, OnData, OnComplete, 0);

//POST 형식으로 웹에 요청한다.
conn.request("POST", "/happyhttp/test.php", headers, (const unsigned char*)body, strlen(body));

//요청 결과가 아직 처리되지 않았다면 계속해서 대기한다.
while (conn.outstanding())
	conn.pump();

요청이 처리되면 응답을 처리하기 위한 콜백 함수 OnData 함수가 실행된다.

void OnData(const happyhttp::Response* r, void* userdata, const unsigned char* data, int n)
{
	fwrite(data, 1, n, stdout);
	count += n;
}

예제 - HTTP Post로 JSON 데이터 보내기

#include "happyhttp.h"
#include <cstdio>
#include <cstring>

#ifdef WIN32
#include <winsock2.h>
#endif // WIN32

#pragma comment(lib, "ws2_32")

int count = 0;

void OnBegin(const happyhttp::Response* r, void* userdata)
{
	printf("BEGIN (%d %s)\n", r->getstatus(), r->getreason());
	count = 0;
}

void OnData(const happyhttp::Response* r, void* userdata, const unsigned char* data, int n)
{
	fwrite(data, 1, n, stdout);
	count += n;
}

void OnComplete(const happyhttp::Response* r, void* userdata)
{
	printf("COMPLETE (%d bytes)\n", count);
}



void Test1()
{
	puts("-----------------Test1------------------------");
	// simple simple GET
	happyhttp::Connection conn("scumways.com", 80);
	conn.setcallbacks(OnBegin, OnData, OnComplete, 0);

	conn.request("GET", "/happyhttp/test.php", 0, 0, 0);

	while (conn.outstanding())
		conn.pump();
}



void Test2()
{
	puts("-----------------Test2------------------------");
	// POST using high-level request interface

	const char* headers[] =
	{
		"Connection", "close",
		"Content-type", "application/x-www-form-urlencoded",
		"Accept", "text/plain",
		0
	};

	const char* body = "answer=42&name=Bubba";

	happyhttp::Connection conn("scumways.com", 80);
	conn.setcallbacks(OnBegin, OnData, OnComplete, 0);
	conn.request("POST",
		"/happyhttp/test.php",
		headers,
		(const unsigned char*)body,
		strlen(body));

	while (conn.outstanding())
		conn.pump();
}

void Test3()
{
	puts("-----------------Test3------------------------");
	// POST example using lower-level interface

	const char* params = "answer=42&foo=bar";
	int l = strlen(params);

	happyhttp::Connection conn("scumways.com", 80);
	conn.setcallbacks(OnBegin, OnData, OnComplete, 0);

	conn.putrequest("POST", "/happyhttp/test.php");
	conn.putheader("Connection", "close");
	conn.putheader("Content-Length", l);
	conn.putheader("Content-type", "application/x-www-form-urlencoded");
	conn.putheader("Accept", "text/plain");
	conn.endheaders();
	conn.send((const unsigned char*)params, l);

	while (conn.outstanding())
		conn.pump();
}

void Test4()
{
	puts("-----------------Test4------------------------");
	// POST example using lower-level interface

	auto reqJsonData = R"(
		  {
			"UserSeq": 1,
			"UserID": "jacking75",
			"UserPW": "123qwe"
		  }
		)";
	
	const char* headers[] =
	{
		"Connection", "close",
		"Content-type", "application/json",
		"Accept", "text/plain",
		0
	};

	//const char* body = "answer=42&name=Bubba";

	happyhttp::Connection conn("localhost", 19000);
	conn.setcallbacks(OnBegin, OnData, OnComplete, 0);
	conn.request("POST",
		"/Request/Login",
		headers,
		(const unsigned char*)reqJsonData,
		strlen(reqJsonData));

	while (conn.outstanding())
		conn.pump();
}


int main(int argc, char* argv[])
{
#ifdef WIN32
	WSAData wsaData;
	int code = WSAStartup(MAKEWORD(1, 1), &wsaData);
	if (code != 0)
	{
		fprintf(stderr, "shite. %d\n", code);
		return 0;
	}
#endif //WIN32
	try
	{
		//Test1();
		//Test2();
		//Test3();

		Test4();
	}

	catch (happyhttp::Wobbly& e)
	{
		fprintf(stderr, "Exception:\n%s\n", e.what());
	}

#ifdef WIN32
	WSACleanup();
#endif // WIN32

	return 0;
}


예제코드


이 글은 2018-04-17에 작성되었습니다.