Skip to content

Commit cd50797

Browse files
authored
Merge pull request #76 from wazuh/bug/32416_request_log
Fix - Refactor cURL error handling to preserve response data
2 parents 6eca14e + 197496f commit cd50797

7 files changed

Lines changed: 309 additions & 206 deletions

File tree

include/IURLRequest.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ struct TPostRequestParameters
212212
* @brief Callback to be called when an error occurs.
213213
*
214214
*/
215-
std::function<void(const std::string&, const long)> onError = {};
215+
std::function<void(const std::string&, const long, const std::string&)> onError = {};
216216

217217
/**
218218
* @brief File name of to store the output data.

src/HTTPRequest.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <variant>
1919

2020
using wrapperType = cURLWrapper;
21+
auto constexpr INTERNAL_ERROR_MESSAGE = "Internal error in HTTPRequest module.";
2122

2223
void HTTPRequest::download(std::variant<TRequestParameters<std::string>,
2324
TRequestParameters<nlohmann::json>,
@@ -55,7 +56,7 @@ void HTTPRequest::download(std::variant<TRequestParameters<std::string>,
5556
{
5657
if (onError)
5758
{
58-
onError(ex.what(), ex.responseCode());
59+
onError(ex.what(), ex.responseCode(), ex.responseBody());
5960
}
6061
else
6162
{
@@ -66,7 +67,7 @@ void HTTPRequest::download(std::variant<TRequestParameters<std::string>,
6667
{
6768
if (onError)
6869
{
69-
onError(ex.what(), NOT_USED);
70+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
7071
}
7172
else
7273
{
@@ -191,7 +192,7 @@ void HTTPRequest::post(std::variant<TRequestParameters<std::string>,
191192
{
192193
if (onError)
193194
{
194-
onError(ex.what(), ex.responseCode());
195+
onError(ex.what(), ex.responseCode(), ex.responseBody());
195196
}
196197
else
197198
{
@@ -202,7 +203,7 @@ void HTTPRequest::post(std::variant<TRequestParameters<std::string>,
202203
{
203204
if (onError)
204205
{
205-
onError(ex.what(), NOT_USED);
206+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
206207
}
207208
else
208209
{
@@ -263,7 +264,7 @@ void HTTPRequest::get(std::variant<TRequestParameters<std::string>,
263264
{
264265
if (onError)
265266
{
266-
onError(ex.what(), ex.responseCode());
267+
onError(ex.what(), ex.responseCode(), ex.responseBody());
267268
}
268269
else
269270
{
@@ -274,7 +275,7 @@ void HTTPRequest::get(std::variant<TRequestParameters<std::string>,
274275
{
275276
if (onError)
276277
{
277-
onError(ex.what(), NOT_USED);
278+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
278279
}
279280
else
280281
{
@@ -399,7 +400,7 @@ void HTTPRequest::put(std::variant<TRequestParameters<std::string>,
399400
{
400401
if (onError)
401402
{
402-
onError(ex.what(), ex.responseCode());
403+
onError(ex.what(), ex.responseCode(), ex.responseBody());
403404
}
404405
else
405406
{
@@ -410,7 +411,7 @@ void HTTPRequest::put(std::variant<TRequestParameters<std::string>,
410411
{
411412
if (onError)
412413
{
413-
onError(ex.what(), NOT_USED);
414+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
414415
}
415416
else
416417
{
@@ -535,7 +536,7 @@ void HTTPRequest::patch(std::variant<TRequestParameters<std::string>,
535536
{
536537
if (onError)
537538
{
538-
onError(ex.what(), ex.responseCode());
539+
onError(ex.what(), ex.responseCode(), ex.responseBody());
539540
}
540541
else
541542
{
@@ -546,7 +547,7 @@ void HTTPRequest::patch(std::variant<TRequestParameters<std::string>,
546547
{
547548
if (onError)
548549
{
549-
onError(ex.what(), NOT_USED);
550+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
550551
}
551552
else
552553
{
@@ -607,7 +608,7 @@ void HTTPRequest::delete_(std::variant<TRequestParameters<std::string>,
607608
{
608609
if (onError)
609610
{
610-
onError(ex.what(), ex.responseCode());
611+
onError(ex.what(), ex.responseCode(), ex.responseBody());
611612
}
612613
else
613614
{
@@ -618,7 +619,7 @@ void HTTPRequest::delete_(std::variant<TRequestParameters<std::string>,
618619
{
619620
if (onError)
620621
{
621-
onError(ex.what(), NOT_USED);
622+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
622623
}
623624
else
624625
{

src/UNIXSocketRequest.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <string>
1616

1717
using wrapperType = cURLWrapper;
18+
auto constexpr INTERNAL_ERROR_MESSAGE = "Internal error in HTTPRequest module.";
1819

1920
void UNIXSocketRequest::download(std::variant<TRequestParameters<std::string>,
2021
TRequestParameters<nlohmann::json>,
@@ -52,7 +53,7 @@ void UNIXSocketRequest::download(std::variant<TRequestParameters<std::string>,
5253
{
5354
if (onError)
5455
{
55-
onError(ex.what(), ex.responseCode());
56+
onError(ex.what(), ex.responseCode(), ex.responseBody());
5657
}
5758
else
5859
{
@@ -63,7 +64,7 @@ void UNIXSocketRequest::download(std::variant<TRequestParameters<std::string>,
6364
{
6465
if (onError)
6566
{
66-
onError(ex.what(), NOT_USED);
67+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
6768
}
6869
else
6970
{
@@ -187,7 +188,7 @@ void UNIXSocketRequest::post(std::variant<TRequestParameters<std::string>,
187188
{
188189
if (onError)
189190
{
190-
onError(ex.what(), ex.responseCode());
191+
onError(ex.what(), ex.responseCode(), ex.responseBody());
191192
}
192193
else
193194
{
@@ -198,7 +199,7 @@ void UNIXSocketRequest::post(std::variant<TRequestParameters<std::string>,
198199
{
199200
if (onError)
200201
{
201-
onError(ex.what(), NOT_USED);
202+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
202203
}
203204
else
204205
{
@@ -259,7 +260,7 @@ void UNIXSocketRequest::get(std::variant<TRequestParameters<std::string>,
259260
{
260261
if (onError)
261262
{
262-
onError(ex.what(), ex.responseCode());
263+
onError(ex.what(), ex.responseCode(), ex.responseBody());
263264
}
264265
else
265266
{
@@ -270,7 +271,7 @@ void UNIXSocketRequest::get(std::variant<TRequestParameters<std::string>,
270271
{
271272
if (onError)
272273
{
273-
onError(ex.what(), NOT_USED);
274+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
274275
}
275276
else
276277
{
@@ -395,7 +396,7 @@ void UNIXSocketRequest::put(std::variant<TRequestParameters<std::string>,
395396
{
396397
if (onError)
397398
{
398-
onError(ex.what(), ex.responseCode());
399+
onError(ex.what(), ex.responseCode(), ex.responseBody());
399400
}
400401
else
401402
{
@@ -406,7 +407,7 @@ void UNIXSocketRequest::put(std::variant<TRequestParameters<std::string>,
406407
{
407408
if (onError)
408409
{
409-
onError(ex.what(), NOT_USED);
410+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
410411
}
411412
else
412413
{
@@ -531,7 +532,7 @@ void UNIXSocketRequest::patch(std::variant<TRequestParameters<std::string>,
531532
{
532533
if (onError)
533534
{
534-
onError(ex.what(), ex.responseCode());
535+
onError(ex.what(), ex.responseCode(), ex.responseBody());
535536
}
536537
else
537538
{
@@ -542,7 +543,7 @@ void UNIXSocketRequest::patch(std::variant<TRequestParameters<std::string>,
542543
{
543544
if (onError)
544545
{
545-
onError(ex.what(), NOT_USED);
546+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
546547
}
547548
else
548549
{
@@ -603,7 +604,7 @@ void UNIXSocketRequest::delete_(std::variant<TRequestParameters<std::string>,
603604
{
604605
if (onError)
605606
{
606-
onError(ex.what(), ex.responseCode());
607+
onError(ex.what(), ex.responseCode(), ex.responseBody());
607608
}
608609
else
609610
{
@@ -614,7 +615,7 @@ void UNIXSocketRequest::delete_(std::variant<TRequestParameters<std::string>,
614615
{
615616
if (onError)
616617
{
617-
onError(ex.what(), NOT_USED);
618+
onError(ex.what(), NOT_USED, INTERNAL_ERROR_MESSAGE);
618619
}
619620
else
620621
{

src/curlMultiHandler.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
static const int CURL_MULTI_HANDLER_TIMEOUT_MS = 1000;
2424
static const int CURL_MULTI_HANDLER_EXTRA_FDS = 0;
25+
auto constexpr NOT_USED_MULTI = -1;
2526

2627
using deleterCurlHandler = CustomDeleter<decltype(&curl_easy_cleanup), curl_easy_cleanup>;
2728
using deleterCurlMultiHandler = CustomDeleter<decltype(&curl_multi_cleanup), curl_multi_cleanup>;
@@ -102,6 +103,10 @@ class cURLMultiHandler final : public ICURLHandler
102103
}
103104
} while (stillRunning && m_shouldRun.load());
104105

106+
// Get HTTP status code before checking messages
107+
long responseCode = 0;
108+
curl_easy_getinfo(m_curlHandler.get(), CURLINFO_RESPONSE_CODE, &responseCode);
109+
105110
struct CURLMsg* multiHandleMessages = nullptr;
106111
do
107112
{
@@ -111,11 +116,17 @@ class cURLMultiHandler final : public ICURLHandler
111116
if (multiHandleMessages && (multiHandleMessages->msg == CURLMSG_DONE))
112117
{
113118
auto errorCode = multiHandleMessages->data.result;
119+
120+
// Check for cURL-level errors (network, DNS, timeout, etc.)
114121
if (errorCode != CURLE_OK)
115122
{
116-
throw Curl::CurlException("cURLMultiHandler::execute() failed: " +
117-
std::string(curl_easy_strerror(errorCode)),
118-
errorCode);
123+
throw Curl::CurlException(curl_easy_strerror(errorCode), NOT_USED_MULTI);
124+
}
125+
126+
// Handle HTTP-level errors (4xx and 5xx)
127+
if (responseCode >= 400)
128+
{
129+
throw Curl::CurlException("Request failed", responseCode);
119130
}
120131
}
121132
} while (multiHandleMessages);

src/curlSingleHandler.hpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,42 @@ class cURLSingleHandler final : public ICURLHandler
5050
*/
5151
void execute() override
5252
{
53-
const auto resPerform {curl_easy_perform(m_curlHandler.get())};
53+
// Perform the HTTP request
54+
const CURLcode resPerform = curl_easy_perform(m_curlHandler.get());
5455

55-
long responseCode = NOT_USED;
56-
const auto resGetInfo {curl_easy_getinfo(m_curlHandler.get(), CURLINFO_RESPONSE_CODE, &responseCode)};
56+
// Get HTTP status code before reset
57+
long responseCode = 0;
58+
const CURLcode resGetInfo = curl_easy_getinfo(m_curlHandler.get(), CURLINFO_RESPONSE_CODE, &responseCode);
5759

60+
// Clean up cURL handle state
5861
curl_easy_reset(m_curlHandler.get());
5962

63+
// Check for cURL-level errors (network, DNS, timeout, etc.)
6064
if (resPerform != CURLE_OK)
6165
{
62-
if (resPerform == CURLE_HTTP_RETURNED_ERROR)
66+
throw Curl::CurlException(curl_easy_strerror(resPerform), NOT_USED);
67+
}
68+
69+
// Verify we got response code (should always succeed if resPerform OK)
70+
if (resGetInfo != CURLE_OK)
71+
{
72+
throw Curl::CurlException("Failed to retrieve HTTP response code", NOT_USED);
73+
}
74+
75+
// Handle HTTP-level errors (4xx and 5xx)
76+
if (responseCode >= 400)
77+
{
78+
std::string errorMsg;
79+
if (responseCode >= 400 && responseCode < 500)
6380
{
64-
if (resGetInfo != CURLE_OK)
65-
{
66-
throw Curl::CurlException("cURLSingleHandler::execute() failed", NOT_USED);
67-
}
68-
throw Curl::CurlException(curl_easy_strerror(resPerform), responseCode);
81+
errorMsg = "Client error";
6982
}
70-
throw Curl::CurlException(curl_easy_strerror(resPerform), NOT_USED);
83+
else if (responseCode >= 500)
84+
{
85+
errorMsg = "Server error";
86+
}
87+
88+
throw Curl::CurlException(errorMsg, responseCode);
7189
}
7290
}
7391
};

0 commit comments

Comments
 (0)