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에 작성되었습니다.