Updated:

5 minute read

개요


빌드

  • ninja-build 설치
    • dnf config-manager --set-enabled crb
    • dnf install ninja-build
  • 공통
    • git clone https://github.com/microsoft/cpprestsdk.git
    • cd cpprestsdk/
    • git submodule update --init
  • debug 빌드
    • mkdir build.debug
    • cd build.debug
    • cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Debug
    • ninja
  • release 빌드
    • mkdir build.release
    • cd build.release/
    • cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release
    • ninja
  • 정적 라이브러리 빌드
    • cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0
  • 테스트
    • cd Release/Binaries
    • ./test_runner *_test.so
  • 헤더파일 위치
    • Release/include/
  • 라이브러리 위치
    • Release/Binaries


예제

  • 코드
    • #include "cpprest/asyncrt_utils.h"
      #include "cpprest/containerstream.h"
      #include "cpprest/filestream.h"
      #include "cpprest/http_client.h"
      #include "cpprest/http_listener.h"
      #include "cpprest/json.h"
      #include "cpprest/producerconsumerstream.h"
      #include "cpprest/uri.h"
      #include <future>
             
      using namespace std;
             
      class Handler {
      	private:
      		web::http::experimental::listener::http_listener listener;
             
      		void Get(web::http::http_request request);
      		void Post(web::http::http_request request);
      		void Put(web::http::http_request request);
      		void Delete(web::http::http_request request);
             
      	public:
      		Handler(const web::http::uri &address);
      		virtual ~Handler() = default;
             
      		pplx::task<void> Open() { return this->listener.open(); }
      		pplx::task<void> Close() { return this->listener.close(); }
      };
             
      Handler::Handler(const web::http::uri &address) : listener(address) {
      	this->listener.support(web::http::methods::GET,
      						   bind(&Handler::Get, this, placeholders::_1));
      	this->listener.support(web::http::methods::PUT,
      						   bind(&Handler::Put, this, placeholders::_1));
      	this->listener.support(web::http::methods::POST,
      						   bind(&Handler::Post, this, placeholders::_1));
      	this->listener.support(web::http::methods::DEL,
      						   bind(&Handler::Delete, this, placeholders::_1));
      }
             
      void Handler::Get(web::http::http_request request) {
      	ucout << "----- server get start -----" << endl;
             
      	// ucout << request.to_string() << endl;
             
      	ucout << "\tmethod : (" << request.method() << ")" << endl;
             
      	ucout << "\trequest_uri : (" << request.request_uri().to_string() << ")"
      		  << endl;
      	ucout << "\trelative_uri : (" << request.relative_uri().to_string() << ")"
      		  << endl;
      	ucout << "\tabsolute_uri : (" << request.absolute_uri().to_string() << ")"
      		  << endl;
             
      	ucout << "\tpath : (" << request.relative_uri().path() << ")" << endl;
      	for (const auto &iter :
      		 web::http::uri::split_path(request.relative_uri().path())) {
      		ucout << "\tpath : (" << iter << ")" << endl;
      	}
             
      	ucout << "\tquery : (" << request.request_uri().query() << ")" << endl;
      	for (const auto &iter :
      		 web::http::uri::split_query(request.request_uri().query())) {
      		ucout << "\tquery : (" << iter.first << ", " << iter.second << ")"
      			  << endl;
      	}
             
      	auto response = web::json::value::object();
      	response["a"] = web::json::value::string("1");
      	response["b"] = web::json::value::number(2);
      	response["c"] = web::json::value::boolean(true);
      	response["d"] = web::json::value::null();
      	response["e"] = web::json::value::array();
             
      	request.reply(web::http::status_codes::OK, response);
             
      	ucout << "----- server get end -----" << endl << endl << endl;
      };
             
      void Handler::Post(web::http::http_request request) {
      	ucout << "----- server post start -----" << endl;
             
      	// ucout << request.to_string() << endl;
             
      	ucout << "\theaders start" << endl;
      	for (const auto &iter : request.headers()) {
      		ucout << "\t\t(" << iter.first << "), (" << iter.second << ")" << endl;
      	}
      	ucout << "\theaders end" << endl;
             
      	request.extract_json().then([=](web::json::value body) {
      		ucout << "----- server post body start -----" << endl;
             
      		ucout << "\t(" << body.serialize() << ")" << endl;
      		ucout << "\t(" << body.at("a").as_integer() << ")" << endl;
             
      		ucout << "----- server post body end -----" << endl << endl << endl;
             
      		auto response = web::json::value::object();
      		response["id"] = web::json::value::number(1);
      		request.reply(web::http::status_codes::Created, response);
      	});
             
      	ucout << "----- server post end -----" << endl << endl << endl;
      };
             
      void Handler::Put(web::http::http_request request) {
      	ucout << "----- server put start -----" << endl;
             
      	// ucout << request.to_string() << endl;
             
      	request.extract_json(true).then([=](web::json::value body) {
      		ucout << "----- server put body start -----" << endl;
             
      		ucout << "\t(" << body.serialize() << ")" << endl;
      		ucout << "\t(" << body.at("b").as_integer() << ")" << endl;
             
      		ucout << "----- server put body end -----" << endl << endl << endl;
             
      		utility::string_t response = "put response";
      		request.reply(web::http::status_codes::OK, response);
      	});
             
      	ucout << "----- server put end -----" << endl << endl << endl;
      };
             
      void Handler::Delete(web::http::http_request request) {
      	ucout << "----- server delete start -----" << endl;
             
      	// ucout << request.to_string() << endl;
             
      	cout << "\tid : ("
      		 << web::http::uri::split_path(request.relative_uri().path())[1] << ")"
      		 << endl;
             
      	request.reply(web::http::status_codes::NoContent);
             
      	ucout << "----- server delete end -----" << endl << endl << endl;
      };
             
      int main() {
      	ucout << "main start" << endl << endl;
             
      	auto handler = make_unique<Handler>(U("http://0.0.0.0:10000"));
             
      	auto server_start = [&handler]() { handler->Open().wait(); };
      	auto server_stop = [&handler]() { handler->Close().wait(); };
      	auto client_job = []() {
      		web::http::client::http_client g("http://127.0.0.1:10000");
      		auto requestGet =
      			web::http::client::http_client(U("http://127.0.0.1:10000"))
      				.request(web::http::methods::GET,
      						 web::uri_builder(U("uri-1"))
      							 .append_path(U("uri-2"))
      							 .append_query(U("id-1"), 1)
      							 .append_query(U("id-2"), 2)
      							 .to_string())
      				.then([](web::http::http_response response) {
      					ucout << "----- client get start -----" << endl;
             
      					ucout << "\tstatus_code : (" << response.status_code()
      						  << ")" << endl;
             
      					return response.extract_json();
      				})
      				.then([](web::json::value body) {
      					ucout << "\tbody : (" << body.serialize() << ")" << endl;
             
      					ucout << "----- client get end -----" << endl
      						  << endl
      						  << endl
      						  << endl
      						  << endl;
      				});
      		requestGet.wait();
             
      		auto requestPost =
      			web::http::client::http_client(U("http://127.0.0.1:10000"))
      				.request(web::http::methods::POST,
      						 web::uri_builder(U("uri-1"))
      							 .append_path(U("uri-2"))
      							 .to_string(),
      						 "{\"a\" : 1}", U("application/json"))
      				.then([](web::http::http_response response) {
      					ucout << "----- client post start -----" << endl;
             
      					ucout << "\tstatus_code : (" << response.status_code()
      						  << ")" << endl;
             
      					return response.extract_json();
      				})
      				.then([](web::json::value body) {
      					ucout << "\tbody : (" << body.serialize() << ")" << endl;
             
      					ucout << "----- client post end -----" << endl
      						  << endl
      						  << endl
      						  << endl
      						  << endl;
      				});
      		requestPost.wait();
             
      		auto requestPut =
      			web::http::client::http_client(U("http://127.0.0.1:10000"))
      				.request(web::http::methods::PUT,
      						 web::uri_builder(U("uri-1"))
      							 .append_path(U("uri-2"))
      							 .to_string(),
      						 "{\"b\" : 1}", U("application/json"))
      				.then([](web::http::http_response response) {
      					ucout << "----- client put start -----" << endl;
             
      					ucout << "\tstatus_code : (" << response.status_code()
      						  << ")" << endl;
             
      					return response.extract_string();
      				})
      				.then([](utility::string_t body) {
      					ucout << "\tbody : (" << body << ")" << endl;
             
      					ucout << "----- client put end -----" << endl
      						  << endl
      						  << endl
      						  << endl
      						  << endl;
      				});
      		requestPut.wait();
             
      		auto requestDelete =
      			web::http::client::http_client(U("http://127.0.0.1:10000"))
      				.request(web::http::methods::DEL, web::uri_builder(U("uri-1"))
      													  .append_path(U("1"))
      													  .to_string())
      				.then([](web::http::http_response response) {
      					ucout << "----- client delete start -----" << endl;
             
      					ucout << "\tstatus_code : (" << response.status_code()
      						  << ")" << endl;
             
      					ucout << "----- client delete end -----" << endl << endl;
      				});
      		requestDelete.wait();
      	};
             
      	server_start();
             
      	client_job();
             
      	server_stop();
             
      	ucout << endl << "main end" << endl;
             
      	return EXIT_SUCCESS;
      }
      
  • 컴파일
    • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/.../cpprestsdk/build.debug/Release/Binaries/
    • g++ -g -Wall -o main main.cpp -I/.../cpprestsdk/Release/include/ -L/.../cpprestsdk/build.debug/Release/Binaries/ -lcrypto -lcpprest
  • 실행 결과
    • main start
             
      ----- server get start -----
              method : (GET)
              request_uri : (/uri-1/uri-2?id-1=1&id-2=2)
              relative_uri : (/uri-1/uri-2?id-1=1&id-2=2)
              absolute_uri : (/uri-1/uri-2?id-1=1&id-2=2)
              path : (/uri-1/uri-2)
              path : (uri-1)
              path : (uri-2)
              query : (id-1=1&id-2=2)
              query : (id-1, 1)
              query : (id-2, 2)
      ----- server get end -----
             
             
      ----- client get start -----
              status_code : (200)
              body : ({"a":"1","b":2,"c":true,"d":null,"e":[]})
      ----- client get end -----
             
             
             
             
      ----- server post start -----
              headers start
                      (Connection), (Keep-Alive)
                      (Content-Length), (9)
                      (Content-Type), (application/json)
                      (Host), (127.0.0.1:10000)
                      (User-Agent), (cpprestsdk/2.10.18)
              headers end
      ----- server post end -----
             
             
      ----- server post body start -----
              ({"a":1})
              (1)
      ----- server post body end -----
             
             
      ----- client post start -----
              status_code : (201)
              body : ({"id":1})
      ----- client post end -----
             
             
             
             
      ----- server put start -----
      ----- server put end -----
             
             
      ----- server put body start -----
              ({"b":1})
              (1)
      ----- server put body end -----
             
             
      ----- client put start -----
              status_code : (200)
              body : (put response)
      ----- client put end -----
             
             
             
             
      ----- server delete start -----
              id : (1)
      ----- server delete end -----
             
             
      ----- client delete start -----
              status_code : (204)
      ----- client delete end -----
             
             
      main end