# HG changeset patch # User František Kučera # Date 1649109972 -7200 # Node ID dbeae485a3fd00ded8f65c001505884c39fbae9a # Parent 4f96098f7c5728e20d38a69b7a0372e0c5f6c4d1 request body support: unfinished version with read callback diff -r 4f96098f7c57 -r dbeae485a3fd src/HTTPClient.cpp --- a/src/HTTPClient.cpp Mon Apr 04 23:07:31 2022 +0200 +++ b/src/HTTPClient.cpp Tue Apr 05 00:06:12 2022 +0200 @@ -32,6 +32,7 @@ public: CURL* curl; char curlErrorBuffer[CURL_ERROR_SIZE]; + std::stringstream requestBody; std::stringstream responseBody; std::stringstream responseHeaders; @@ -93,8 +94,17 @@ HTTPClient* HTTPClient::open() { HTTPClient::HTTPClientImpl* impl = new HTTPClient::HTTPClientImpl(curl_easy_init()); + typedef size_t(*CurlReadCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*); typedef size_t(*CurlWriteCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*); + // set request body callback + curl_easy_setopt(impl->curl, CURLOPT_READDATA, impl); + curl_easy_setopt(impl->curl, CURLOPT_READFUNCTION, (CurlReadCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl) { + size_t r = size * nmemb; + ssize_t bytesRead = impl->requestBody.readsome(buffer, r); + return (size_t) bytesRead; + }); + // set response body callback curl_easy_setopt(impl->curl, CURLOPT_WRITEDATA, impl); curl_easy_setopt(impl->curl, CURLOPT_WRITEFUNCTION, (CurlWriteCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl)->size_t { @@ -156,6 +166,14 @@ 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... curl_easy_setopt(impl->curl, CURLOPT_HTTPHEADER, requestHeders.getList()); + // store request body + if (request.body.size()) { + impl->requestBody = std::stringstream(request.body); + curl_easy_setopt(impl->curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(impl->curl, CURLOPT_EXPECT_100_TIMEOUT_MS, 0); + } + + // clear the error buffer impl->curlErrorBuffer[0] = 0; diff -r 4f96098f7c57 -r dbeae485a3fd src/HTTPHandler.h --- a/src/HTTPHandler.h Mon Apr 04 23:07:31 2022 +0200 +++ b/src/HTTPHandler.h Tue Apr 05 00:06:12 2022 +0200 @@ -212,6 +212,8 @@ if (attributeName == L"id") requestId = value; else if (attributeName == L"url") request.url = convertor.to_bytes(value); else if (attributeName == L"method") request.method = parseMethod(value); + else if (attributeName == L"text") request.body = convertor.to_bytes(value); + else if (attributeName == L"data") request.body = "TODO: read binary data: " + convertor.to_bytes(value); // TODO: read hex/binary request body else if (isHeaderAttribute(attributeName)) appendRequestHeader(fetchHeaderName(attributeName), value); else throw std::invalid_argument("Unsupported attribute in the header relation: " + convertor.to_bytes(attributeName + L" = " + value));