99
1010namespace curl_utils {
1111namespace {
12- size_t WriteCallback (void * contents, size_t size, size_t nmemb,
13- std::string* output) {
14- size_t totalSize = size * nmemb;
15- output->append ((char *)contents, totalSize);
16- return totalSize;
17- }
12+ class CurlResponse {
13+ public:
14+ static size_t WriteCallback (char * buffer, size_t size, size_t nitems,
15+ void * userdata) {
16+ auto * response = static_cast <CurlResponse*>(userdata);
17+ return response->Append (buffer, size * nitems);
18+ }
19+
20+ size_t Append (const char * buffer, size_t size) {
21+ data_.append (buffer, size);
22+ return size;
23+ }
24+
25+ const std::string& GetData () const { return data_; }
26+
27+ private:
28+ std::string data_;
29+ };
1830
1931void SetUpProxy (CURL* handle, const std::string& url) {
2032 auto config = file_manager_utils::GetCortexConfig ();
@@ -59,19 +71,18 @@ void SetUpProxy(CURL* handle, const std::string& url) {
5971}
6072} // namespace
6173
62- std::optional<std::unordered_map<std::string, std::string>> GetHeaders (
63- const std::string& url) {
74+ std::shared_ptr<Header> GetHeaders (const std::string& url) {
6475 auto url_obj = url_parser::FromUrlString (url);
6576 if (url_obj.has_error ()) {
66- return std:: nullopt ;
77+ return nullptr ;
6778 }
6879
6980 if (url_obj->host == kHuggingFaceHost ) {
70- std::unordered_map<std::string, std::string> headers{} ;
71- headers[" Content-Type" ] = " application/json" ;
81+ auto headers = std::make_shared<Header>() ;
82+ headers-> m [" Content-Type" ] = " application/json" ;
7283 auto const & token = file_manager_utils::GetCortexConfig ().huggingFaceToken ;
7384 if (!token.empty ()) {
74- headers[" Authorization" ] = " Bearer " + token;
85+ headers-> m [" Authorization" ] = " Bearer " + token;
7586
7687 // for debug purpose
7788 auto min_token_size = 6 ;
@@ -87,15 +98,15 @@ std::optional<std::unordered_map<std::string, std::string>> GetHeaders(
8798 }
8899
89100 if (url_obj->host == kGitHubHost ) {
90- std::unordered_map<std::string, std::string> headers{} ;
91- headers[" Accept" ] = " application/vnd.github.v3+json" ;
101+ auto headers = std::make_shared<Header>() ;
102+ headers-> m [" Accept" ] = " application/vnd.github.v3+json" ;
92103 // github API requires user-agent https://docs.github.com/en/rest/using-the-rest-api/getting-started-with-the-rest-api?apiVersion=2022-11-28#user-agent
93104 auto user_agent = file_manager_utils::GetCortexConfig ().gitHubUserAgent ;
94105 auto gh_token = file_manager_utils::GetCortexConfig ().gitHubToken ;
95- headers[" User-Agent" ] =
106+ headers-> m [" User-Agent" ] =
96107 user_agent.empty () ? kDefaultGHUserAgent : user_agent;
97108 if (!gh_token.empty ()) {
98- headers[" Authorization" ] = " Bearer " + gh_token;
109+ headers-> m [" Authorization" ] = " Bearer " + gh_token;
99110
100111 // for debug purpose
101112 auto min_token_size = 6 ;
@@ -109,7 +120,7 @@ std::optional<std::unordered_map<std::string, std::string>> GetHeaders(
109120 return headers;
110121 }
111122
112- return std:: nullopt ;
123+ return nullptr ;
113124}
114125
115126cpp::result<std::string, std::string> SimpleGet (const std::string& url,
@@ -122,21 +133,23 @@ cpp::result<std::string, std::string> SimpleGet(const std::string& url,
122133
123134 auto headers = GetHeaders (url);
124135 curl_slist* curl_headers = nullptr ;
125- if (headers. has_value () ) {
126- for (const auto & [key, value] : headers. value () ) {
136+ if (headers) {
137+ for (const auto & [key, value] : headers-> m ) {
127138 auto header = key + " : " + value;
128139 curl_headers = curl_slist_append (curl_headers, header.c_str ());
129140 }
130141
131142 curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
132143 }
133144
134- std::string readBuffer;
145+ auto * response = new CurlResponse ();
146+ std::shared_ptr<CurlResponse> s (response,
147+ std::default_delete<CurlResponse>());
135148
136149 SetUpProxy (curl, url);
137150 curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
138- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, WriteCallback);
139- curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer );
151+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, CurlResponse:: WriteCallback);
152+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, response );
140153 if (timeout > 0 ) {
141154 curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout);
142155 }
@@ -155,10 +168,10 @@ cpp::result<std::string, std::string> SimpleGet(const std::string& url,
155168 if (http_code >= 400 ) {
156169 CTL_ERR (" HTTP request failed with status code: " +
157170 std::to_string (http_code));
158- return cpp::fail (readBuffer );
171+ return cpp::fail (response-> GetData () );
159172 }
160173
161- return readBuffer ;
174+ return response-> GetData () ;
162175}
163176
164177cpp::result<std::string, std::string> SimpleRequest (
@@ -176,13 +189,15 @@ cpp::result<std::string, std::string> SimpleRequest(
176189 curl_slist_append (curl_headers, " Content-Type: application/json" );
177190 curl_headers = curl_slist_append (curl_headers, " Expect:" );
178191
179- if (headers. has_value () ) {
180- for (const auto & [key, value] : headers. value () ) {
192+ if (headers) {
193+ for (const auto & [key, value] : headers-> m ) {
181194 auto header = key + " : " + value;
182195 curl_headers = curl_slist_append (curl_headers, header.c_str ());
183196 }
184197 }
185- std::string readBuffer;
198+ auto * response = new CurlResponse ();
199+ std::shared_ptr<CurlResponse> s (response,
200+ std::default_delete<CurlResponse>());
186201
187202 SetUpProxy (curl, url);
188203 curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
@@ -196,8 +211,8 @@ cpp::result<std::string, std::string> SimpleRequest(
196211 curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, " DELETE" );
197212 }
198213 curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L );
199- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, WriteCallback);
200- curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer );
214+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, CurlResponse:: WriteCallback);
215+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, response );
201216
202217 curl_easy_setopt (curl, CURLOPT_POSTFIELDSIZE, body.length ());
203218 curl_easy_setopt (curl, CURLOPT_POSTFIELDS, body.c_str ());
@@ -221,10 +236,10 @@ cpp::result<std::string, std::string> SimpleRequest(
221236 if (http_code >= 400 ) {
222237 CTL_ERR (" HTTP request failed with status code: " +
223238 std::to_string (http_code));
224- return cpp::fail (readBuffer );
239+ return cpp::fail (response-> GetData () );
225240 }
226241
227- return readBuffer ;
242+ return response-> GetData () ;
228243}
229244
230245cpp::result<YAML::Node, std::string> ReadRemoteYaml (const std::string& url) {
0 commit comments