Switch to curl_multi
FossilOrigin-Name: 45caa8672395503ccfe940a18057ec3d3f182bd15f2f1ce5dda614e7ca89adfa
This commit is contained in:
parent
570bf94ef5
commit
7373faab3f
7 changed files with 76 additions and 39 deletions
|
@ -28,6 +28,7 @@ struct mstdnt_fetch_results
|
|||
size_t mstdnt_curl_write_callback(char* ptr, size_t _size, size_t nmemb, void* _content);
|
||||
void mastodont_fetch_results_cleanup(struct mstdnt_fetch_results* res);
|
||||
int mastodont_fetch_curl(mastodont_t* mstdnt,
|
||||
CURL* curl,
|
||||
struct mstdnt_args* args,
|
||||
char* url,
|
||||
struct mstdnt_fetch_results* results,
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef int8_t mstdnt_bool;
|
|||
|
||||
typedef struct mastodont
|
||||
{
|
||||
CURL* curl;
|
||||
CURLM* curl;
|
||||
} mastodont_t;
|
||||
|
||||
struct mstdnt_storage
|
||||
|
|
|
@ -29,13 +29,13 @@ typedef char* mstdnt_visibility_t;
|
|||
|
||||
enum mstdnt_visibility_type
|
||||
{
|
||||
MSTDNT_VISIBILITY_UNKNOWN,
|
||||
MSTDNT_VISIBILITY_PUBLIC,
|
||||
MSTDNT_VISIBILITY_UNLISTED,
|
||||
MSTDNT_VISIBILITY_PRIVATE,
|
||||
MSTDNT_VISIBILITY_LIST,
|
||||
MSTDNT_VISIBILITY_DIRECT,
|
||||
MSTDNT_VISIBILITY_LOCAL,
|
||||
MSTDNT_VISIBILITY_LIST,
|
||||
MSTDNT_VISIBILITY_UNKNOWN,
|
||||
};
|
||||
|
||||
#endif /* MASTODONT_VISIBILITY_TYPES_H */
|
||||
|
|
54
src/fetch.c
54
src/fetch.c
|
@ -45,6 +45,7 @@ void mastodont_fetch_results_cleanup(struct mstdnt_fetch_results* res)
|
|||
|
||||
#define TOKEN_STR_SIZE 512
|
||||
int mastodont_fetch_curl(mastodont_t* mstdnt,
|
||||
CURL* curl,
|
||||
struct mstdnt_args* m_args,
|
||||
char* _url,
|
||||
struct mstdnt_fetch_results* results,
|
||||
|
@ -52,7 +53,10 @@ int mastodont_fetch_curl(mastodont_t* mstdnt,
|
|||
char* request_t_custom)
|
||||
{
|
||||
#define is_custom request_t_custom && request_t == CURLOPT_CUSTOMREQUEST
|
||||
int res = 3;
|
||||
CURLMcode res = 3;
|
||||
int status = 0;
|
||||
CURLMsg* msg;
|
||||
int running = 1;
|
||||
char token[TOKEN_STR_SIZE] = { 0 };
|
||||
struct curl_slist* list = NULL;
|
||||
|
||||
|
@ -67,35 +71,51 @@ int mastodont_fetch_curl(mastodont_t* mstdnt,
|
|||
snprintf(token, TOKEN_STR_SIZE, "Authorization: Bearer %s",
|
||||
m_args->token);
|
||||
list = curl_slist_append(list, token);
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_HTTPHEADER, list);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
|
||||
}
|
||||
|
||||
/* Set options */
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_WRITEFUNCTION, mstdnt_curl_write_callback);
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_WRITEDATA, results);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, mstdnt_curl_write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, results);
|
||||
/* Should we verify the peer's SSL cert? */
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_SSL_VERIFYPEER,
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,
|
||||
!MSTDNT_T_FLAG_ISSET(m_args, MSTDNT_FLAG_SSL_UNVERIFIED));
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_SSL_VERIFYHOST,
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,
|
||||
!MSTDNT_T_FLAG_ISSET(m_args, MSTDNT_FLAG_SSL_UNVERIFIED));
|
||||
/* PUT, POST, GET, Custom */
|
||||
/* Mimes are expected to be set beforehand manually */
|
||||
if (is_custom)
|
||||
curl_easy_setopt(mstdnt->curl, request_t, request_t_custom);
|
||||
curl_easy_setopt(curl, request_t, request_t_custom);
|
||||
else if (request_t != CURLOPT_MIMEPOST)
|
||||
curl_easy_setopt(mstdnt->curl, request_t, 1);
|
||||
curl_easy_setopt(curl, request_t, 1);
|
||||
|
||||
res = curl_easy_perform(mstdnt->curl);
|
||||
// Add curl handle to multi, then run and block
|
||||
curl_multi_add_handle(mstdnt->curl, curl);
|
||||
|
||||
// Reset values that are optional
|
||||
// Reset if custom
|
||||
if (is_custom)
|
||||
curl_easy_setopt(mstdnt->curl, request_t, NULL);
|
||||
int msgs_left;
|
||||
while (running)
|
||||
{
|
||||
res = curl_multi_perform(mstdnt->curl, &running);
|
||||
|
||||
curl_easy_setopt(mstdnt->curl, CURLOPT_HTTPHEADER, NULL);
|
||||
if (running)
|
||||
res = curl_multi_poll(mstdnt->curl, NULL, 0, 1000, NULL);
|
||||
|
||||
// Check if our socket is done
|
||||
while ((msg = curl_multi_info_read(mstdnt->curl, &msgs_left)))
|
||||
if (msg->msg == CURLMSG_DONE && msg->easy_handle == curl)
|
||||
{
|
||||
status = msg->data.result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (res) break;
|
||||
}
|
||||
|
||||
out:
|
||||
// Looks like we're done here
|
||||
curl_multi_remove_handle(mstdnt->curl, curl);
|
||||
|
||||
if (list) curl_slist_free_all(list);
|
||||
|
||||
return res;
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -13,15 +13,16 @@ void mastodont_global_curl_cleanup()
|
|||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
// Curl multi can still be used with single context's
|
||||
int mastodont_init(mastodont_t* data)
|
||||
{
|
||||
data->curl = curl_easy_init();
|
||||
data->curl = curl_multi_init();
|
||||
return data->curl == NULL;
|
||||
}
|
||||
|
||||
void mastodont_cleanup(mastodont_t* data)
|
||||
{
|
||||
curl_easy_cleanup(data->curl);
|
||||
curl_multi_cleanup(data->curl);
|
||||
}
|
||||
|
||||
void mastodont_free(void* ptr)
|
||||
|
|
|
@ -85,6 +85,9 @@ int mastodont_request(mastodont_t* data,
|
|||
_mstdnt_query_string(data, m_args, args->url, args->params_query, args->params_query_len) :
|
||||
args->url;
|
||||
|
||||
// Create cURL single handle, we will run this later and then block
|
||||
CURL* curl = curl_easy_init();
|
||||
|
||||
/* Zero out */
|
||||
memset(storage, 0, sizeof(struct mstdnt_storage));
|
||||
storage->needs_cleanup = 0;
|
||||
|
@ -94,13 +97,13 @@ int mastodont_request(mastodont_t* data,
|
|||
args->request_type == CURLOPT_CUSTOMREQUEST))
|
||||
{
|
||||
post = _mstdnt_query_string(data, m_args, NULL, args->params_post, args->params_post_len);
|
||||
curl_easy_setopt(data->curl, CURLOPT_POSTFIELDS, post);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
|
||||
}
|
||||
else if (args->params_post && args->request_type == CURLOPT_MIMEPOST)
|
||||
{
|
||||
/* Initialize MIME post */
|
||||
mime = curl_mime_init(data->curl);
|
||||
curl_easy_setopt(data->curl, args->request_type, mime);
|
||||
mime = curl_mime_init(curl);
|
||||
curl_easy_setopt(curl, args->request_type, mime);
|
||||
|
||||
/* Let's handle query params array */
|
||||
mime_params_post(mime, args->params_post, args->params_post_len);
|
||||
|
@ -108,9 +111,10 @@ int mastodont_request(mastodont_t* data,
|
|||
/* Make it empty, no post data provided */
|
||||
/* I'm not sure why the pleroma api does this */
|
||||
else if (args->request_type == CURLOPT_POST)
|
||||
curl_easy_setopt(data->curl, CURLOPT_POSTFIELDS, "");
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
|
||||
|
||||
curlerror = mastodont_fetch_curl(data,
|
||||
curl,
|
||||
m_args,
|
||||
url_query,
|
||||
&results,
|
||||
|
@ -136,7 +140,7 @@ int mastodont_request(mastodont_t* data,
|
|||
// Make sure there is no error
|
||||
if (!mstdnt_check_error(storage))
|
||||
{
|
||||
/* Optional */
|
||||
/* Call our callback and do the large work */
|
||||
if (args->callback) res = args->callback(storage->root, args->args);
|
||||
}
|
||||
else
|
||||
|
@ -145,6 +149,9 @@ int mastodont_request(mastodont_t* data,
|
|||
cleanup_res:
|
||||
mastodont_fetch_results_cleanup(&results);
|
||||
cleanup:
|
||||
// Note: the fetch removed the handle from our multi handle
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (args->params_post && args->request_type == CURLOPT_POST) free(post);
|
||||
/* Only free if params_query set */
|
||||
if (args->params_query) free(url_query);
|
||||
|
|
32
src/static.c
32
src/static.c
|
@ -20,22 +20,30 @@ int mastodont_instance_panel(mastodont_t* api,
|
|||
struct mstdnt_args* m_args,
|
||||
struct mstdnt_fetch_results* html)
|
||||
{
|
||||
return mastodont_fetch_curl(api,
|
||||
m_args,
|
||||
"instance/panel.html",
|
||||
html,
|
||||
CURLOPT_HTTPGET,
|
||||
NULL);
|
||||
CURL* curl = curl_easy_init();
|
||||
int status = mastodont_fetch_curl(api,
|
||||
curl,
|
||||
m_args,
|
||||
"instance/panel.html",
|
||||
html,
|
||||
CURLOPT_HTTPGET,
|
||||
NULL);
|
||||
curl_easy_cleanup(curl);
|
||||
return status;
|
||||
}
|
||||
|
||||
int mastodont_terms_of_service(mastodont_t* api,
|
||||
struct mstdnt_args* m_args,
|
||||
struct mstdnt_fetch_results* html)
|
||||
{
|
||||
return mastodont_fetch_curl(api,
|
||||
m_args,
|
||||
"static/terms-of-service.html",
|
||||
html,
|
||||
CURLOPT_HTTPGET,
|
||||
NULL);
|
||||
CURL* curl = curl_easy_init();
|
||||
int status = mastodont_fetch_curl(api,
|
||||
curl,
|
||||
m_args,
|
||||
"static/terms-of-service.html",
|
||||
html,
|
||||
CURLOPT_HTTPGET,
|
||||
NULL);
|
||||
curl_easy_cleanup(curl);
|
||||
return status;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue