C-libcurl.apiClient.c.mustache Maven / Gradle / Ivy
#include
#include
#include
#include
#include "../include/apiClient.h"
size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp);
apiClient_t *apiClient_create() {
apiClient_t *apiClient = malloc(sizeof(apiClient_t));
apiClient->basePath = strdup("{{{basePath}}}");
apiClient->sslConfig = NULL;
apiClient->dataReceived = NULL;
apiClient->dataReceivedLen = 0;
apiClient->data_callback_func = NULL;
apiClient->progress_func = NULL;
apiClient->progress_data = NULL;
apiClient->response_code = 0;
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasicBasic}}
apiClient->username = NULL;
apiClient->password = NULL;
{{/isBasicBasic}}
{{#isOAuth}}
apiClient->accessToken = NULL;
{{/isOAuth}}
{{#isApiKey}}
apiClient->apiKeys_{{name}} = NULL;
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
return apiClient;
}
apiClient_t *apiClient_create_with_base_path(const char *basePath
, sslConfig_t *sslConfig
{{#hasAuthMethods}}
{{#authMethods}}
{{#isApiKey}}
, list_t *apiKeys_{{name}}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
) {
apiClient_t *apiClient = malloc(sizeof(apiClient_t));
if(basePath){
apiClient->basePath = strdup(basePath);
}else{
apiClient->basePath = strdup("{{{basePath}}}");
}
if(sslConfig){
apiClient->sslConfig = sslConfig;
}else{
apiClient->sslConfig = NULL;
}
apiClient->dataReceived = NULL;
apiClient->dataReceivedLen = 0;
apiClient->data_callback_func = NULL;
apiClient->progress_func = NULL;
apiClient->progress_data = NULL;
apiClient->response_code = 0;
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasicBasic}}
apiClient->username = NULL;
apiClient->password = NULL;
{{/isBasicBasic}}
{{#isOAuth}}
apiClient->accessToken = NULL;
{{/isOAuth}}
{{#isApiKey}}
if(apiKeys_{{name}}!= NULL) {
apiClient->apiKeys_{{name}} = list_createList();
listEntry_t *listEntry = NULL;
list_ForEach(listEntry, apiKeys_{{name}}) {
keyValuePair_t *pair = listEntry->data;
keyValuePair_t *pairDup = keyValuePair_create(strdup(pair->key), strdup(pair->value));
list_addElement(apiClient->apiKeys_{{name}}, pairDup);
}
}else{
apiClient->apiKeys_{{name}} = NULL;
}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
return apiClient;
}
void apiClient_free(apiClient_t *apiClient) {
if(apiClient->basePath) {
free(apiClient->basePath);
}
apiClient->data_callback_func = NULL;
apiClient->progress_func = NULL;
apiClient->progress_data = NULL;
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasicBasic}}
if(apiClient->username) {
free(apiClient->username);
}
if(apiClient->password) {
free(apiClient->password);
}
{{/isBasicBasic}}
{{#isOAuth}}
if(apiClient->accessToken) {
free(apiClient->accessToken);
}
{{/isOAuth}}
{{#isApiKey}}
if(apiClient->apiKeys_{{name}}) {
listEntry_t *listEntry = NULL;
list_ForEach(listEntry, apiClient->apiKeys_{{name}}) {
keyValuePair_t *pair = listEntry->data;
if(pair->key){
free(pair->key);
}
if(pair->value){
free(pair->value);
}
keyValuePair_free(pair);
}
list_freeList(apiClient->apiKeys_{{name}});
}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
free(apiClient);
}
sslConfig_t *sslConfig_create(const char *clientCertFile, const char *clientKeyFile, const char *CACertFile, int insecureSkipTlsVerify) {
sslConfig_t *sslConfig = calloc(1, sizeof(sslConfig_t));
if ( clientCertFile ) {
sslConfig->clientCertFile = strdup(clientCertFile);
}
if ( clientKeyFile ) {
sslConfig->clientKeyFile = strdup(clientKeyFile);
}
if ( CACertFile ) {
sslConfig->CACertFile = strdup(CACertFile);
}
sslConfig->insecureSkipTlsVerify = insecureSkipTlsVerify;
return sslConfig;
}
void sslConfig_free(sslConfig_t *sslConfig) {
if ( sslConfig->clientCertFile ) {
free(sslConfig->clientCertFile);
}
if ( sslConfig->clientKeyFile ) {
free(sslConfig->clientKeyFile);
}
if ( sslConfig->CACertFile ){
free(sslConfig->CACertFile);
}
free(sslConfig);
}
void replaceSpaceWithPlus(char *stringToProcess) {
for(int i = 0; i < strlen(stringToProcess); i++) {
if(stringToProcess[i] == ' ') {
stringToProcess[i] = '+';
}
}
}
char *assembleTargetUrl(const char *basePath,
const char *operationParameter,
list_t *queryParameters) {
int neededBufferSizeForQueryParameters = 0;
listEntry_t *listEntry;
if(queryParameters != NULL) {
list_ForEach(listEntry, queryParameters) {
keyValuePair_t *pair = listEntry->data;
neededBufferSizeForQueryParameters +=
strlen(pair->key) + strlen(pair->value);
}
neededBufferSizeForQueryParameters +=
(queryParameters->count * 2); // each keyValuePair is separated by a = and a & except the last, but this makes up for the ? at the beginning
}
int operationParameterLength = 0;
int basePathLength = strlen(basePath);
if(operationParameter != NULL) {
operationParameterLength = (1 + strlen(operationParameter));
}
char *targetUrl =
malloc(
neededBufferSizeForQueryParameters + basePathLength + operationParameterLength +
1);
strcpy(targetUrl, basePath);
if(operationParameter != NULL) {
strcat(targetUrl, operationParameter);
}
if(queryParameters != NULL) {
strcat(targetUrl, "?");
list_ForEach(listEntry, queryParameters) {
keyValuePair_t *pair = listEntry->data;
replaceSpaceWithPlus(pair->key);
strcat(targetUrl, pair->key);
strcat(targetUrl, "=");
replaceSpaceWithPlus(pair->value);
strcat(targetUrl, pair->value);
if(listEntry->nextListEntry != NULL) {
strcat(targetUrl, "&");
}
}
}
return targetUrl;
}
char *assembleHeaderField(char *key, char *value) {
char *header = malloc(strlen(key) + strlen(value) + 3);
strcpy(header, key),
strcat(header, ": ");
strcat(header, value);
return header;
}
void postData(CURL *handle, const char *bodyParameters) {
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, bodyParameters);
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE_LARGE,
(curl_off_t)strlen(bodyParameters));
}
int lengthOfKeyPair(keyValuePair_t *keyPair) {
long length = 0;
if((keyPair->key != NULL) &&
(keyPair->value != NULL) )
{
length = strlen(keyPair->key) + strlen(keyPair->value);
return length;
}
return 0;
}
void apiClient_invoke(apiClient_t *apiClient,
const char *operationParameter,
list_t *queryParameters,
list_t *headerParameters,
list_t *formParameters,
list_t *headerType,
list_t *contentType,
const char *bodyParameters,
const char *requestType) {
CURL *handle = curl_easy_init();
CURLcode res;
if(handle) {
listEntry_t *listEntry;
curl_mime *mime = NULL;
struct curl_slist *headers = NULL;
char *buffContent = NULL;
char *buffHeader = NULL;
binary_t *fileVar = NULL;
char *formString = NULL;
if(headerType != NULL) {
list_ForEach(listEntry, headerType) {
if(strstr((char *) listEntry->data,
"xml") == NULL)
{
buffHeader = malloc(strlen(
"Accept: ") +
strlen((char *)
listEntry->
data) + 1);
sprintf(buffHeader, "%s%s", "Accept: ",
(char *) listEntry->data);
headers = curl_slist_append(headers,
buffHeader);
free(buffHeader);
}
}
}
if(contentType != NULL) {
list_ForEach(listEntry, contentType) {
if(strstr((char *) listEntry->data,
"xml") == NULL)
{
buffContent =
malloc(strlen(
"Content-Type: ") + strlen(
(char *)
listEntry->data) +
1);
sprintf(buffContent, "%s%s",
"Content-Type: ",
(char *) listEntry->data);
headers = curl_slist_append(headers,
buffContent);
free(buffContent);
buffContent = NULL;
}
}
} else {
headers = curl_slist_append(headers,
"Content-Type: application/json");
}
if(requestType != NULL) {
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST,
requestType);
}
if(formParameters != NULL) {
if(contentType &&
findStrInStrList(contentType, "application/x-www-form-urlencoded") != NULL)
{
long parameterLength = 0;
long keyPairLength = 0;
list_ForEach(listEntry, formParameters) {
keyValuePair_t *keyPair =
listEntry->data;
keyPairLength =
lengthOfKeyPair(keyPair) + 1;
if(listEntry->nextListEntry != NULL) {
parameterLength++;
}
parameterLength = parameterLength +
keyPairLength;
}
formString = malloc(parameterLength + 1);
memset(formString, 0, parameterLength + 1);
list_ForEach(listEntry, formParameters) {
keyValuePair_t *keyPair =
listEntry->data;
if((keyPair->key != NULL) &&
(keyPair->value != NULL) )
{
strcat(formString,
keyPair->key);
strcat(formString, "=");
strcat(formString,
keyPair->value);
if(listEntry->nextListEntry !=
NULL)
{
strcat(formString, "&");
}
}
}
curl_easy_setopt(handle, CURLOPT_POSTFIELDS,
formString);
}
if(contentType &&
findStrInStrList(contentType, "multipart/form-data") != NULL) {
mime = curl_mime_init(handle);
list_ForEach(listEntry, formParameters) {
keyValuePair_t *keyValuePair =
listEntry->data;
if((keyValuePair->key != NULL) &&
(keyValuePair->value != NULL) )
{
curl_mimepart *part =
curl_mime_addpart(mime);
curl_mime_name(part,
keyValuePair->key);
if(strcmp(keyValuePair->key,
"file") == 0)
{
memcpy(&fileVar,
keyValuePair->value,
sizeof(fileVar));
curl_mime_data(part,
fileVar->data,
fileVar->len);
curl_mime_filename(part,
"image.png");
} else {
curl_mime_data(part,
keyValuePair->value,
CURL_ZERO_TERMINATED);
}
}
}
curl_easy_setopt(handle, CURLOPT_MIMEPOST,
mime);
}
}
list_ForEach(listEntry, headerParameters) {
keyValuePair_t *keyValuePair = listEntry->data;
if((keyValuePair->key != NULL) &&
(keyValuePair->value != NULL) )
{
char *headerValueToWrite = assembleHeaderField(
keyValuePair->key, keyValuePair->value);
curl_slist_append(headers, headerValueToWrite);
free(headerValueToWrite);
}
}
if ( strstr(apiClient->basePath, "https") != NULL ) {
if ( apiClient->sslConfig ) {
if( apiClient->sslConfig->clientCertFile ) {
curl_easy_setopt(handle, CURLOPT_SSLCERT, apiClient->sslConfig->clientCertFile);
}
if( apiClient->sslConfig->clientKeyFile ) {
curl_easy_setopt(handle, CURLOPT_SSLKEY, apiClient->sslConfig->clientKeyFile);
}
if( apiClient->sslConfig->CACertFile ) {
curl_easy_setopt(handle, CURLOPT_CAINFO, apiClient->sslConfig->CACertFile);
}
if ( 1 == apiClient->sslConfig->insecureSkipTlsVerify ) {
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
} else {
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 2L);
}
} else {
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
}
}
if (apiClient->progress_func != NULL) {
curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, apiClient->progress_func);
if (apiClient->progress_data != NULL) {
curl_easy_setopt(handle, CURLOPT_XFERINFODATA, apiClient->progress_data);
}
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);
}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isApiKey}}
// this would only be generated for apiKey authentication
if (apiClient->apiKeys_{{name}} != NULL)
{
list_ForEach(listEntry, apiClient->apiKeys_{{name}}) {
keyValuePair_t *apiKey = listEntry->data;
if((apiKey->key != NULL) &&
(apiKey->value != NULL) )
{
char *headerValueToWrite = assembleHeaderField(
apiKey->key, apiKey->value);
curl_slist_append(headers, headerValueToWrite);
free(headerValueToWrite);
}
}
}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
char *targetUrl =
assembleTargetUrl(apiClient->basePath,
operationParameter,
queryParameters);
curl_easy_setopt(handle, CURLOPT_URL, targetUrl);
curl_easy_setopt(handle,
CURLOPT_WRITEFUNCTION,
writeDataCallback);
curl_easy_setopt(handle,
CURLOPT_WRITEDATA,
apiClient);
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_VERBOSE, 0); // to get curl debug msg 0: to disable, 1L:to enable
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasicBasic}}
// this would only be generated for basic authentication:
char *authenticationToken;
if((apiClient->username != NULL) &&
(apiClient->password != NULL) )
{
authenticationToken = malloc(strlen(
apiClient->username) +
strlen(
apiClient->password) +
2);
sprintf(authenticationToken,
"%s:%s",
apiClient->username,
apiClient->password);
curl_easy_setopt(handle,
CURLOPT_HTTPAUTH,
CURLAUTH_BASIC);
curl_easy_setopt(handle,
CURLOPT_USERPWD,
authenticationToken);
}
{{/isBasicBasic}}
{{#isOAuth}}
// this would only be generated for OAuth2 authentication
if(apiClient->accessToken != NULL) {
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
curl_easy_setopt(handle,
CURLOPT_XOAUTH2_BEARER,
apiClient->accessToken);
}
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
if(bodyParameters != NULL) {
postData(handle, bodyParameters);
}
res = curl_easy_perform(handle);
curl_slist_free_all(headers);
free(targetUrl);
if(res == CURLE_OK) {
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &apiClient->response_code);
} else {
char *url,*ip,*scheme;
long port;
curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
curl_easy_getinfo(handle, CURLINFO_PRIMARY_IP, &ip);
curl_easy_getinfo(handle, CURLINFO_PRIMARY_PORT, &port);
curl_easy_getinfo(handle, CURLINFO_SCHEME, &scheme);
fprintf(stderr, "curl_easy_perform() failed\n\nURL: %s\nIP: %s\nPORT: %li\nSCHEME: %s\nStrERROR: %s\n",url,ip,port,scheme,
curl_easy_strerror(res));
}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasicBasic}}
if((apiClient->username != NULL) &&
(apiClient->password != NULL) )
{
free(authenticationToken);
}
{{/isBasicBasic}}
{{/authMethods}}
{{/hasAuthMethods}}
curl_easy_cleanup(handle);
if(formParameters != NULL) {
free(formString);
curl_mime_free(mime);
}
}
}
size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp) {
size_t size_this_time = nmemb * size;
apiClient_t *apiClient = (apiClient_t *)userp;
apiClient->dataReceived = (char *)realloc( apiClient->dataReceived, apiClient->dataReceivedLen + size_this_time + 1);
memcpy((char *)apiClient->dataReceived + apiClient->dataReceivedLen, buffer, size_this_time);
apiClient->dataReceivedLen += size_this_time;
((char*)apiClient->dataReceived)[apiClient->dataReceivedLen] = '\0'; // the space size of (apiClient->dataReceived) = dataReceivedLen + 1
if (apiClient->data_callback_func) {
apiClient->data_callback_func(&apiClient->dataReceived, &apiClient->dataReceivedLen);
}
return size_this_time;
}
char *strReplace(char *orig, char *rep, char *with) {
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
int lenRep; // length of rep (the string to remove)
int lenWith; // length of with (the string to replace rep with)
int lenFront; // distance between rep and end of last rep
int count; // number of replacements
// sanity checks and initialization
if(!orig || !rep)
{
return NULL;
}
lenRep = strlen(rep);
if(lenRep == 0) {
return NULL; // empty rep causes infinite loop during count
}
if(!with) {
with = "";
}
lenWith = strlen(with);
// count the number of replacements needed
ins = orig;
for(count = 0; tmp = strstr(ins, rep); ++count) {
ins = tmp + lenRep;
}
tmp = result = malloc(strlen(orig) + (lenWith - lenRep) * count + 1);
if(!result) {
return NULL;
}
char *originalPointer = orig; // copying original pointer to free the memory
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
while(count--) {
ins = strstr(orig, rep);
lenFront = ins - orig;
tmp = strncpy(tmp, orig, lenFront) + lenFront;
tmp = strcpy(tmp, with) + lenWith;
orig += lenFront + lenRep; // move to next "end of rep"
}
strcpy(tmp, orig);
free(originalPointer);
return result;
}
void apiClient_setupGlobalEnv() {
curl_global_init(CURL_GLOBAL_ALL);
}
void apiClient_unsetupGlobalEnv() {
curl_global_cleanup();
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy