Callback parameter stuff

FossilOrigin-Name: a546f5470413f8daa0d1952244b3e7c5139734b35c4eb0e93e537ba45bbf7a8c
This commit is contained in:
nekobit 2022-10-20 03:54:41 +00:00
parent 81116dccdf
commit 90393af306
6 changed files with 119 additions and 96 deletions

View file

@ -19,20 +19,42 @@
#include <mastodont_types.h>
#include <curl/curl.h>
struct mstdnt_fetch_results
/** Used to store the response from CURL */
struct mstdnt_fetch_data
{
char* response;
size_t size;
// Callback from user
mstdnt_request_cb_t callback;
void* callback_args;
};
enum mstdnt_fetch_await
{
MSTDNT_AWAIT_ALL,
MSTDNT_AWAIT_ONCE,
};
size_t mstdnt_curl_write_callback(char* ptr, size_t _size, size_t nmemb, void* _content);
void mstdnt_fetch_results_cleanup(struct mstdnt_fetch_results* res);
int mstdnt_fetch_curl(mastodont_t* mstdnt,
CURL* curl,
struct mstdnt_args* args,
char* url,
struct mstdnt_fetch_results* results,
CURLoption request_t,
char* request_t_custom);
void mstdnt_fetch_data_cleanup(struct mstdnt_fetch_data* res);
/**
* @brief Attempts to fetch, async or blocking.
*
* @param mstdnt Mastodont struct
* @param curl curl API
* @param args Mastodont General args passed
* @param url URL of request
* @param results Results from response
*/
int mstdnt_fetch_curl_async(mastodont_t* mstdnt,
CURL* curl,
struct mstdnt_args* args,
mstdnt_request_cb_t cb_request,
void* cb_args,
char* url,
CURLoption request_t,
char* request_t_custom);
#endif /* MASTODONT_FETCH_H */

View file

@ -34,10 +34,19 @@ struct mstdnt_request_args
int (*callback)(cJSON*, void*);
};
/**
* Sends a mastoAPI request to an HTTP server.
*
* @param data Mastodont struct
* @param m_args Mastodont general args pointer
* @param cb_request Callback pointer associated with this request
* @param cb_args Args passed into cb_request
* @param args Propagated arguments to request to the server
*/
int mstdnt_request(mastodont_t* data,
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
struct mstdnt_request_args* args);
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
struct mstdnt_request_args* args);
#endif /* MASTODONT_REQUEST_H */

View file

@ -23,13 +23,13 @@
#define MSTDNT_URLSIZE 2048
#define MSTDNT_URISIZE 512
typedef int8_t mstdnt_bool;
// Don't be fooled!
#define MSTDNT_TRUE 2
#define MSTDNT_FALSE 1
#define MSTDNT_BOOL_UNSET 0
typedef void (*mstdnt_request_cb_t)(void* data, void* args);
// It's more logical to not sanitize than to sanitize data
#define MSTDNT_FLAG_NO_URI_SANITIZE (1<<0)
#define MSTDNT_FLAG_SSL_UNVERIFIED (1<<1)
#define MSTDNT_FLAG_ISSET(flags, flag) (((flags) & (flag)) == (flag))

View file

@ -89,7 +89,7 @@ void* cb_args,
mstdnt_accounts_json_callback,
};
return mstdnt_request(data, m_args, &req_args);
return mstdnt_request(data, m_args, &req_args, );
}
int mstdnt_get_followers(mastodont_t* data,

View file

@ -23,7 +23,7 @@
size_t mstdnt_curl_write_callback(char* ptr, size_t _size, size_t nmemb, void* _content)
{
size_t size = nmemb * _size; /* Mostly pointless, but portable */
struct mstdnt_fetch_results* res = _content; /* Cast */
struct mstdnt_fetch_data* res = _content; /* Cast */
char* data;
if ((data = mstdnt_realloc(res->response, res->size + size + 1)) == NULL)
@ -40,36 +40,33 @@ size_t mstdnt_curl_write_callback(char* ptr, size_t _size, size_t nmemb, void* _
return size;
}
void mstdnt_fetch_results_cleanup(struct mstdnt_fetch_results* res)
void mstdnt_fetch_data_cleanup(struct mstdnt_fetch_data* res)
{
mstdnt_free(res->response);
}
#define TOKEN_STR_SIZE 512
int mstdnt_fetch_curl(mastodont_t* mstdnt,
CURL* curl,
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
char* _url,
struct mstdnt_fetch_results* results,
CURLoption request_t,
char* request_t_custom)
int mstdnt_fetch_curl_async(mastodont_t* mstdnt,
CURL* curl,
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
char* _url,
CURLoption request_t,
char* request_t_custom)
{
#define is_custom request_t_custom && request_t == CURLOPT_CUSTOMREQUEST
struct mstdnt_fetch_data* results = NULL;
CURLMcode res = 3;
int status = 0;
CURLMsg* msg;
int running = 1;
char token[TOKEN_STR_SIZE] = { 0 };
struct curl_slist* list = NULL;
/* Setup URL */
// Setup URL
char url[MSTDNT_URLSIZE] = { 0 };
strncpy(url, m_args->url, MSTDNT_URLSIZE-1);
strncat(url, _url, MSTDNT_URLSIZE-1);
/* Setup token */
// Setup token
if (m_args->token)
{
snprintf(token, TOKEN_STR_SIZE, "Authorization: Bearer %s",
@ -78,81 +75,74 @@ void* cb_args,
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
}
/* Set options */
// Setup data to pass into results
results = calloc(1, sizeof(struct mstdnt_fetch_data));
results.callback = cb_request;
results.callback_args = cb_args;
// Set options
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, mstdnt_curl_write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, results);
/* Copy into private pointer value
* A little stupid, but we can let CURL hold our values for us.
* Curl won't let us get the WRITEDATA opt pointer back sadly, so this has to be done */
curl_easy_setopt(curl, CURLOPT_PRIVATE, results);
/* Should we verify the peer's SSL cert? */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,
!MSTDNT_T_FLAG_ISSET(m_args, MSTDNT_FLAG_SSL_UNVERIFIED));
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 */
// PUT, POST, GET, Custom
// Mimes are expected to be set beforehand manually
if (is_custom)
curl_easy_setopt(curl, request_t, request_t_custom);
else if (request_t != CURLOPT_MIMEPOST)
curl_easy_setopt(curl, request_t, 1);
// Add curl handle to multi, then run and block
#ifndef THREAD_UNSAFE
static pthread_mutex_t multi_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
#ifndef THREAD_UNSAFE
pthread_mutex_lock(&multi_mutex);
#endif
// Add curl handle to multi, then run
curl_multi_add_handle(mstdnt->curl, curl);
#ifndef THREAD_UNSAFE
pthread_mutex_unlock(&multi_mutex);
#endif
res = curl_multi_perform(mstdnt->curl, &running);
int msgs_left;
while (running)
if (list) curl_slist_free_all(list);
return res;
}
int mstdnt_await(enum mstdnt_fetch_await opt)
{
CURLMsg* msg;
int msgs_left = 1;
struct mstdnt_fetch_data* data;
// TODO
//curl_easy_getinfo(curl, CURLINFO_PRIVATE, &data);
do
{
#ifndef THREAD_UNSAFE
pthread_mutex_lock(&multi_mutex);
#endif
res = curl_multi_perform(mstdnt->curl, &running);
#ifndef THREAD_UNSAFE
pthread_mutex_unlock(&multi_mutex);
#endif
if (running)
res = curl_multi_poll(mstdnt->curl, NULL, 0, 1000, NULL);
res = curl_multi_poll(mstdnt->curl, NULL, 0, 1000, NULL);
// Check if our socket is done
#ifndef THREAD_UNSAEF
pthread_mutex_lock(&multi_mutex);
#endif
while ((msg = curl_multi_info_read(mstdnt->curl, &msgs_left)))
{
if (msg->msg == CURLMSG_DONE && msg->easy_handle == curl)
{
status = msg->data.result;
#ifndef THREAD_UNSAFE
pthread_mutex_unlock(&multi_mutex);
#endif
goto out;
}
}
#ifndef THREAD_UNSAFE
pthread_mutex_unlock(&multi_mutex);
#endif
if (res) break;
}
out:
#ifndef THREAD_UNSAFE
pthread_mutex_lock(&multi_mutex);
#endif
// Looks like we're done here
curl_multi_remove_handle(mstdnt->curl, curl);
#ifndef THREAD_UNSAFE
pthread_mutex_unlock(&multi_mutex);
#endif
if (list) curl_slist_free_all(list);
return status;
while (opt == MSTDNT_AWAIT_ALL && msgs_left);
//mstdnt_fetch_data_cleanup(&results);
// Note: the fetch removed the handle from our multi handle
out:
/* // Looks like we're done here */
/* curl_multi_remove_handle(mstdnt->curl, curl); */
//curl_easy_cleanup(curl);
}

View file

@ -72,18 +72,16 @@ static void mime_params_post(curl_mime* mime,
}
int mstdnt_request(mastodont_t* data,
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
struct mstdnt_request_args* args)
struct mstdnt_args* m_args,
mstdnt_request_cb_t cb_request,
void* cb_args,
struct mstdnt_request_args* args)
{
int res = 0, curlerror = 0;
struct mstdnt_storage* storage = args->storage;
struct mstdnt_fetch_results results = { 0 };
cJSON* root;
curl_mime* mime = NULL;
char* post;
// TODO debug me
char* url_query = args->params_query ?
_mstdnt_query_string(data, m_args, args->url, args->params_query, args->params_query_len) :
args->url;
@ -116,14 +114,17 @@ void* cb_args,
else if (args->request_type == CURLOPT_POST)
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
curlerror = mstdnt_fetch_curl(data,
curl,
m_args,
url_query,
&results,
args->request_type,
args->request_type_custom);
curlerror = mstdnt_fetch_curl_async(
data,
curl,
m_args,
cb_request,
cb_args,
url_query,
args->request_type,
args->request_type_custom);
// Mime already used, free it early
if (mime) curl_mime_free(mime);
if (curlerror != CURLE_OK)
@ -134,6 +135,7 @@ void* cb_args,
}
// Create json structure
#if 0
if (_mstdnt_json_init(&root, &results, storage))
{
res = 1;
@ -148,14 +150,14 @@ void* cb_args,
}
else
res = 1;
#endif
cleanup_res:
mstdnt_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)
mstdnt_free(post);
if (args->params_post && args->request_type == CURLOPT_POST) mstdnt_free(post);
/* Only free if params_query set */
if (args->params_query) mstdnt_free(url_query);
return res;