src/HTTPClient.cpp
branchv_0
changeset 26 53c6f76603f6
parent 25 dbeae485a3fd
equal deleted inserted replaced
25:dbeae485a3fd 26:53c6f76603f6
    30 
    30 
    31 class HTTPClient::HTTPClientImpl {
    31 class HTTPClient::HTTPClientImpl {
    32 public:
    32 public:
    33 	CURL* curl;
    33 	CURL* curl;
    34 	char curlErrorBuffer[CURL_ERROR_SIZE];
    34 	char curlErrorBuffer[CURL_ERROR_SIZE];
    35 	std::stringstream requestBody;
    35 	std::string requestBody;
    36 	std::stringstream responseBody;
    36 	std::stringstream responseBody;
    37 	std::stringstream responseHeaders;
    37 	std::stringstream responseHeaders;
    38 
    38 
    39 	HTTPClientImpl(CURL* curl) : curl(curl) {
    39 	HTTPClientImpl(CURL* curl) : curl(curl) {
    40 	}
    40 	}
    92 };
    92 };
    93 
    93 
    94 HTTPClient* HTTPClient::open() {
    94 HTTPClient* HTTPClient::open() {
    95 	HTTPClient::HTTPClientImpl* impl = new HTTPClient::HTTPClientImpl(curl_easy_init());
    95 	HTTPClient::HTTPClientImpl* impl = new HTTPClient::HTTPClientImpl(curl_easy_init());
    96 
    96 
    97 	typedef size_t(*CurlReadCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*);
       
    98 	typedef size_t(*CurlWriteCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*);
    97 	typedef size_t(*CurlWriteCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*);
    99 
       
   100 	// set request body callback
       
   101 	curl_easy_setopt(impl->curl, CURLOPT_READDATA, impl);
       
   102 	curl_easy_setopt(impl->curl, CURLOPT_READFUNCTION, (CurlReadCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl) {
       
   103 		size_t r = size * nmemb;
       
   104 		ssize_t bytesRead = impl->requestBody.readsome(buffer, r);
       
   105 		return (size_t) bytesRead;
       
   106 	});
       
   107 
    98 
   108 	// set response body callback
    99 	// set response body callback
   109 	curl_easy_setopt(impl->curl, CURLOPT_WRITEDATA, impl);
   100 	curl_easy_setopt(impl->curl, CURLOPT_WRITEDATA, impl);
   110 	curl_easy_setopt(impl->curl, CURLOPT_WRITEFUNCTION, (CurlWriteCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl)->size_t {
   101 	curl_easy_setopt(impl->curl, CURLOPT_WRITEFUNCTION, (CurlWriteCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl)->size_t {
   111 		size_t r = size * nmemb;
   102 		size_t r = size * nmemb;
   164 	// set request headers
   155 	// set request headers
   165 	CurlList requestHeders;
   156 	CurlList requestHeders;
   166 	for (size_t i = 0; i < request.headers.size(); i += 2) requestHeders.append(request.headers[i] + ": " + request.headers[i + 1]); // TODO: validate, no CR/LF...
   157 	for (size_t i = 0; i < request.headers.size(); i += 2) requestHeders.append(request.headers[i] + ": " + request.headers[i + 1]); // TODO: validate, no CR/LF...
   167 	curl_easy_setopt(impl->curl, CURLOPT_HTTPHEADER, requestHeders.getList());
   158 	curl_easy_setopt(impl->curl, CURLOPT_HTTPHEADER, requestHeders.getList());
   168 
   159 
   169 	// store request body
   160 	// set request body
   170 	if (request.body.size()) {
   161 	if (request.body.size()) {
   171 		impl->requestBody = std::stringstream(request.body);
   162 		impl->requestBody = request.body;
   172 		curl_easy_setopt(impl->curl, CURLOPT_UPLOAD, 1L);
   163 		curl_off_t requestBodySize = impl->requestBody.size();
   173 		curl_easy_setopt(impl->curl, CURLOPT_EXPECT_100_TIMEOUT_MS, 0);
   164 		curl_easy_setopt(impl->curl, CURLOPT_POSTFIELDS, impl->requestBody.c_str());
       
   165 		curl_easy_setopt(impl->curl, CURLOPT_POSTFIELDSIZE_LARGE, requestBodySize);
   174 	}
   166 	}
   175 
   167 
   176 
   168 
   177 	// clear the error buffer
   169 	// clear the error buffer
   178 	impl->curlErrorBuffer[0] = 0;
   170 	impl->curlErrorBuffer[0] = 0;