From 5fd724fceb5b73240634b433f672bff70c7946d8 Mon Sep 17 00:00:00 2001 From: Michele Albano Date: Tue, 7 Apr 2020 05:40:57 +0200 Subject: [PATCH] C client generator improvements to support petstore. Solves #5836 (#5837) * C client generator improvement to support: openapi-generator/modules/openapi-generator/src/test/resources/3_0/petstore.yaml * Improvements to the C client generator: - moved base64* from apiClient.c to binary.h/binary.c - changed CR/LF to LF in binary.h/binary.c * C client generator: better support for base64encode / base64decode --- .../languages/CLibcurlClientCodegen.java | 6 +- .../C-libcurl/CMakeLists.txt.mustache | 15 +++++ .../resources/C-libcurl/api-header.mustache | 1 + .../resources/C-libcurl/apiClient.c.mustache | 64 ++++--------------- .../resources/C-libcurl/apiClient.h.mustache | 15 +---- .../resources/C-libcurl/binary.c.mustache | 58 +++++++++++++++++ .../resources/C-libcurl/binary.h.mustache | 18 ++++++ .../resources/C-libcurl/model-body.mustache | 2 +- .../resources/C-libcurl/model-header.mustache | 1 + .../C-libcurl/object-header.mustache | 1 + .../petstore/c/.openapi-generator/VERSION | 2 +- samples/client/petstore/c/api/PetAPI.h | 1 + samples/client/petstore/c/api/StoreAPI.h | 1 + samples/client/petstore/c/api/UserAPI.h | 1 + samples/client/petstore/c/include/apiClient.h | 15 +---- samples/client/petstore/c/include/binary.h | 18 ++++++ .../client/petstore/c/model/api_response.h | 1 + samples/client/petstore/c/model/category.h | 1 + samples/client/petstore/c/model/object.h | 1 + samples/client/petstore/c/model/order.h | 1 + samples/client/petstore/c/model/pet.h | 1 + samples/client/petstore/c/model/tag.h | 1 + samples/client/petstore/c/model/user.h | 1 + samples/client/petstore/c/src/apiClient.c | 63 ++++-------------- samples/client/petstore/c/src/binary.c | 58 +++++++++++++++++ 25 files changed, 216 insertions(+), 131 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/C-libcurl/binary.c.mustache create mode 100644 modules/openapi-generator/src/main/resources/C-libcurl/binary.h.mustache create mode 100644 samples/client/petstore/c/include/binary.h create mode 100644 samples/client/petstore/c/src/binary.c diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java index 4ca1429b2a1..c059ff91397 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java @@ -223,10 +223,12 @@ public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConf supportingFiles.add(new SupportingFile("apiClient.c.mustache", "src", "apiClient.c")); supportingFiles.add(new SupportingFile("apiKey.c.mustache", "src", "apiKey.c")); supportingFiles.add(new SupportingFile("list.c.mustache", "src", "list.c")); + supportingFiles.add(new SupportingFile("binary.c.mustache", "src", "binary.c")); // include folder supportingFiles.add(new SupportingFile("apiClient.h.mustache", "include", "apiClient.h")); supportingFiles.add(new SupportingFile("keyValuePair.h.mustache", "include", "keyValuePair.h")); supportingFiles.add(new SupportingFile("list.h.mustache", "include", "list.h")); + supportingFiles.add(new SupportingFile("binary.h.mustache", "include", "binary.h")); // external folder supportingFiles.add(new SupportingFile("cJSON.licence.mustache", "external", "cJSON.licence")); supportingFiles.add(new SupportingFile("cJSON.c.mustache", "external", "cJSON.c")); @@ -377,14 +379,14 @@ public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConf example = "\"2013-10-20T19:20:30+01:00\""; return example; } else if (ModelUtils.isBinarySchema(schema)) { - example = "bytes(b'blah')"; + example = "instantiate_binary_t(\"blah\", 5)"; return example; } else if (ModelUtils.isByteArraySchema(schema)) { example = "YQ=="; } else if (ModelUtils.isStringSchema(schema)) { // a BigDecimal: if ("Number".equalsIgnoreCase(schema.getFormat())) {return "1";} - if (StringUtils.isNotBlank(schema.getPattern())) return "'a'"; // I cheat here, since it would be too complicated to generate a string from a regexp + if (StringUtils.isNotBlank(schema.getPattern())) return "\"a\""; // I cheat here, since it would be too complicated to generate a string from a regexp int len = 0; if (null != schema.getMinLength()) len = schema.getMinLength().intValue(); if (len < 1) len = 1; diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/CMakeLists.txt.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/CMakeLists.txt.mustache index 76c0470f008..41e5faf3e66 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/CMakeLists.txt.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/CMakeLists.txt.mustache @@ -8,6 +8,19 @@ set(CMAKE_CXX_VISIBILITY_PRESET default) set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF) set(CMAKE_BUILD_TYPE Debug) +find_package(OpenSSL) + +if (OPENSSL_FOUND) + message (STATUS "OPENSSL found") + set (CMAKE_C_FLAGS "-DOPENSSL") + include_directories(${OPENSSL_INCLUDE_DIR}) + include_directories(${OPENSSL_INCLUDE_DIRS}) + link_directories(${OPENSSL_LIBRARIES}) + message(STATUS "Using OpenSSL ${OPENSSL_VERSION}") +else() + message (STATUS "OpenSSL Not found.") +endif() + set(pkgName "{{projectName}}") find_package(CURL 7.58.0 REQUIRED) @@ -22,6 +35,7 @@ set(SRCS src/list.c src/apiKey.c src/apiClient.c + src/binary.c external/cJSON.c model/object.c {{#models}} @@ -42,6 +56,7 @@ set(SRCS set(HDRS include/apiClient.h include/list.h + include/binary.h include/keyValuePair.h external/cJSON.h model/object.h diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/api-header.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/api-header.mustache index 6247c6d97dc..7631aa03554 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/api-header.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/api-header.mustache @@ -4,6 +4,7 @@ #include "../include/list.h" #include "../external/cJSON.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" {{#imports}}{{{import}}} {{/imports}} diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.c.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.c.mustache index b9cd08f40b6..7ddd6a27dbb 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.c.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.c.mustache @@ -3,9 +3,6 @@ #include #include #include "../include/apiClient.h" -#ifdef OPENSSL -#include "openssl/pem.h" -#endif size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp); @@ -26,7 +23,7 @@ apiClient_t *apiClient_create() { apiClient->accessToken = NULL; {{/isOAuth}} {{#isApiKey}} - apiClient->apiKeys = NULL; + apiClient->apiKeys_{{name}} = NULL; {{/isApiKey}} {{/authMethods}} {{/hasAuthMethods}} @@ -39,7 +36,7 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath {{#hasAuthMethods}} {{#authMethods}} {{#isApiKey}} -, list_t *apiKeys +, list_t *apiKeys_{{name}} {{/isApiKey}} {{/authMethods}} {{/hasAuthMethods}} @@ -70,16 +67,16 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath apiClient->accessToken = NULL; {{/isOAuth}} {{#isApiKey}} - if(apiKeys!= NULL) { - apiClient->apiKeys = list_create(); + if(apiKeys_{{name}}!= NULL) { + apiClient->apiKeys_{{name}} = list_create(); listEntry_t *listEntry = NULL; - list_ForEach(listEntry, apiKeys) { + 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, pairDup); + list_addElement(apiClient->apiKeys_{{name}}, pairDup); } }else{ - apiClient->apiKeys = NULL; + apiClient->apiKeys_{{name}} = NULL; } {{/isApiKey}} {{/authMethods}} @@ -108,9 +105,9 @@ void apiClient_free(apiClient_t *apiClient) { } {{/isOAuth}} {{#isApiKey}} - if(apiClient->apiKeys) { + if(apiClient->apiKeys_{{name}}) { listEntry_t *listEntry = NULL; - list_ForEach(listEntry, apiClient->apiKeys) { + list_ForEach(listEntry, apiClient->apiKeys_{{name}}) { keyValuePair_t *pair = listEntry->data; if(pair->key){ free(pair->key); @@ -120,7 +117,7 @@ void apiClient_free(apiClient_t *apiClient) { } keyValuePair_free(pair); } - list_free(apiClient->apiKeys); + list_free(apiClient->apiKeys_{{name}}); } {{/isApiKey}} {{/authMethods}} @@ -440,9 +437,9 @@ void apiClient_invoke(apiClient_t *apiClient, {{#authMethods}} {{#isApiKey}} // this would only be generated for apiKey authentication - if (apiClient->apiKeys != NULL) + if (apiClient->apiKeys_{{name}} != NULL) { - list_ForEach(listEntry, apiClient->apiKeys) { + list_ForEach(listEntry, apiClient->apiKeys_{{name}}) { keyValuePair_t *apiKey = listEntry->data; if((apiKey->key != NULL) && (apiKey->value != NULL) ) @@ -616,40 +613,3 @@ char *strReplace(char *orig, char *rep, char *with) { return result; } -char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){ -#ifdef OPENSSL - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less. - BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data. - BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters. - BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure. - BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null. - (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail. - return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct). -#endif -} - -char *base64decode (const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes){ -#ifdef OPENSSL - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO. - BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines. - int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written. - while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte. - decoded_byte_index++; //Increment the index until read of BIO decoded data is complete. - } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - *decoded_bytes = decoded_byte_index; - return base64_decoded; //Returns base-64 decoded data with trailing null terminator. -#endif -} diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.h.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.h.mustache index 034205fc248..2c4cbe267a2 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.h.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/apiClient.h.mustache @@ -8,6 +8,7 @@ #include #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct sslConfig_t { char *clientCertFile; /* client certificate */ @@ -32,18 +33,12 @@ typedef struct apiClient_t { char *accessToken; {{/isOAuth}} {{#isApiKey}} - list_t *apiKeys; + list_t *apiKeys_{{name}}; {{/isApiKey}} {{/authMethods}} {{/hasAuthMethods}} } apiClient_t; -typedef struct binary_t -{ - uint8_t* data; - unsigned int len; -} binary_t; - apiClient_t* apiClient_create(); apiClient_t* apiClient_create_with_base_path(const char *basePath @@ -51,7 +46,7 @@ apiClient_t* apiClient_create_with_base_path(const char *basePath {{#hasAuthMethods}} {{#authMethods}} {{#isApiKey}} -, list_t *apiKeys +, list_t *apiKeys_{{name}} {{/isApiKey}} {{/authMethods}} {{/hasAuthMethods}} @@ -67,8 +62,4 @@ void sslConfig_free(sslConfig_t *sslConfig); char *strReplace(char *orig, char *rep, char *with); -char *base64encode(const void *b64_encode_this, int encode_this_many_bytes); - -char *base64decode(const void *b64_decode_this, int decode_this_many_bytes); - #endif // INCLUDE_API_CLIENT_H diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/binary.c.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/binary.c.mustache new file mode 100644 index 00000000000..ddd162a91f3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/C-libcurl/binary.c.mustache @@ -0,0 +1,58 @@ +#include +#include +#include "../include/binary.h" +#ifdef OPENSSL +#include "openssl/pem.h" +#endif + +binary_t* instantiate_binary_t(char* data, int len) { + binary_t* ret = malloc(sizeof(struct binary_t)); + ret->len=len; + ret->data = malloc(len); + memcpy(ret->data, data, len); + return ret; +} + +char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){ +#ifdef OPENSSL + BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data. + b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO. + BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less. + BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data. + BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters. + BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure. + BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed. + BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null. + (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail. + return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct). +#else // OPENSSL +#warning Data will not be encoded. If you want to use function "base64encode", please define "-DOPENSSL" when building the library. + return NULL; +#endif // OPENSSL +} + +char *base64decode (const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes){ +#ifdef OPENSSL + BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null. + b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO. + BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source. + BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines. + int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written. + while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte. + decoded_byte_index++; //Increment the index until read of BIO decoded data is complete. + } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error. + BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + *decoded_bytes = decoded_byte_index; + return base64_decoded; //Returns base-64 decoded data with trailing null terminator. +#else // OPENSSL +#warning Data will not be decoded. If you want to use function "base64decode", please define "-DOPENSSL" when building the library. + return NULL; +#endif // OPENSSL +} diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/binary.h.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/binary.h.mustache new file mode 100644 index 00000000000..571df5b35fb --- /dev/null +++ b/modules/openapi-generator/src/main/resources/C-libcurl/binary.h.mustache @@ -0,0 +1,18 @@ +#ifndef INCLUDE_BINARY_H +#define INCLUDE_BINARY_H + +#include + +typedef struct binary_t +{ + uint8_t* data; + unsigned int len; +} binary_t; + +binary_t* instantiate_binary_t(char* data, int len); + +char *base64encode(const void *b64_encode_this, int encode_this_many_bytes); + +char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes); + +#endif // INCLUDE_BINARY_H diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/model-body.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/model-body.mustache index 7a911ec6796..06f23c4d942 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/model-body.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/model-body.mustache @@ -534,7 +534,7 @@ fail: } {{/isByteArray}} {{#isBinary}} - binary_t* decoded_str_{{{name}}}; + binary_t* decoded_str_{{{name}}} = malloc(sizeof(struct binary_t)); {{^required}}if ({{{name}}}) { {{/required}} if(!cJSON_IsString({{{name}}})) { diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/model-header.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/model-header.mustache index 5618c306da6..1fa938ed4a2 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/model-header.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/model-header.mustache @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct {{classname}}_t {{classname}}_t; diff --git a/modules/openapi-generator/src/main/resources/C-libcurl/object-header.mustache b/modules/openapi-generator/src/main/resources/C-libcurl/object-header.mustache index 6b1a77fc508..18503e0c276 100644 --- a/modules/openapi-generator/src/main/resources/C-libcurl/object-header.mustache +++ b/modules/openapi-generator/src/main/resources/C-libcurl/object-header.mustache @@ -9,6 +9,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct object_t { diff --git a/samples/client/petstore/c/.openapi-generator/VERSION b/samples/client/petstore/c/.openapi-generator/VERSION index bfbf77eb7fa..b5d898602c2 100644 --- a/samples/client/petstore/c/.openapi-generator/VERSION +++ b/samples/client/petstore/c/.openapi-generator/VERSION @@ -1 +1 @@ -4.3.0-SNAPSHOT \ No newline at end of file +4.3.1-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/c/api/PetAPI.h b/samples/client/petstore/c/api/PetAPI.h index 23f8e1d9224..f223b60a0b8 100644 --- a/samples/client/petstore/c/api/PetAPI.h +++ b/samples/client/petstore/c/api/PetAPI.h @@ -4,6 +4,7 @@ #include "../include/list.h" #include "../external/cJSON.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" #include "../model/api_response.h" #include "../model/pet.h" diff --git a/samples/client/petstore/c/api/StoreAPI.h b/samples/client/petstore/c/api/StoreAPI.h index e38609bbcea..43bdf758376 100644 --- a/samples/client/petstore/c/api/StoreAPI.h +++ b/samples/client/petstore/c/api/StoreAPI.h @@ -4,6 +4,7 @@ #include "../include/list.h" #include "../external/cJSON.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" #include "../model/order.h" diff --git a/samples/client/petstore/c/api/UserAPI.h b/samples/client/petstore/c/api/UserAPI.h index cc93b91b571..b0a60accdab 100644 --- a/samples/client/petstore/c/api/UserAPI.h +++ b/samples/client/petstore/c/api/UserAPI.h @@ -4,6 +4,7 @@ #include "../include/list.h" #include "../external/cJSON.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" #include "../model/user.h" diff --git a/samples/client/petstore/c/include/apiClient.h b/samples/client/petstore/c/include/apiClient.h index a889c9ceaf8..11c89171dcb 100644 --- a/samples/client/petstore/c/include/apiClient.h +++ b/samples/client/petstore/c/include/apiClient.h @@ -8,6 +8,7 @@ #include #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct sslConfig_t { char *clientCertFile; /* client certificate */ @@ -22,21 +23,15 @@ typedef struct apiClient_t { sslConfig_t *sslConfig; void *dataReceived; long response_code; - list_t *apiKeys; + list_t *apiKeys_api_key; char *accessToken; } apiClient_t; -typedef struct binary_t -{ - uint8_t* data; - unsigned int len; -} binary_t; - apiClient_t* apiClient_create(); apiClient_t* apiClient_create_with_base_path(const char *basePath , sslConfig_t *sslConfig -, list_t *apiKeys +, list_t *apiKeys_api_key ); void apiClient_free(apiClient_t *apiClient); @@ -49,8 +44,4 @@ void sslConfig_free(sslConfig_t *sslConfig); char *strReplace(char *orig, char *rep, char *with); -char *base64encode(const void *b64_encode_this, int encode_this_many_bytes); - -char *base64decode(const void *b64_decode_this, int decode_this_many_bytes); - #endif // INCLUDE_API_CLIENT_H diff --git a/samples/client/petstore/c/include/binary.h b/samples/client/petstore/c/include/binary.h new file mode 100644 index 00000000000..571df5b35fb --- /dev/null +++ b/samples/client/petstore/c/include/binary.h @@ -0,0 +1,18 @@ +#ifndef INCLUDE_BINARY_H +#define INCLUDE_BINARY_H + +#include + +typedef struct binary_t +{ + uint8_t* data; + unsigned int len; +} binary_t; + +binary_t* instantiate_binary_t(char* data, int len); + +char *base64encode(const void *b64_encode_this, int encode_this_many_bytes); + +char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes); + +#endif // INCLUDE_BINARY_H diff --git a/samples/client/petstore/c/model/api_response.h b/samples/client/petstore/c/model/api_response.h index a829cd22443..d64dcbacedd 100644 --- a/samples/client/petstore/c/model/api_response.h +++ b/samples/client/petstore/c/model/api_response.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct api_response_t api_response_t; diff --git a/samples/client/petstore/c/model/category.h b/samples/client/petstore/c/model/category.h index 2e858c71e18..ec9efd6ccf6 100644 --- a/samples/client/petstore/c/model/category.h +++ b/samples/client/petstore/c/model/category.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct category_t category_t; diff --git a/samples/client/petstore/c/model/object.h b/samples/client/petstore/c/model/object.h index 6b1a77fc508..18503e0c276 100644 --- a/samples/client/petstore/c/model/object.h +++ b/samples/client/petstore/c/model/object.h @@ -9,6 +9,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct object_t { diff --git a/samples/client/petstore/c/model/order.h b/samples/client/petstore/c/model/order.h index f1e9f47dd43..32914a22749 100644 --- a/samples/client/petstore/c/model/order.h +++ b/samples/client/petstore/c/model/order.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct order_t order_t; diff --git a/samples/client/petstore/c/model/pet.h b/samples/client/petstore/c/model/pet.h index 70103c7c3aa..d7402551014 100644 --- a/samples/client/petstore/c/model/pet.h +++ b/samples/client/petstore/c/model/pet.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct pet_t pet_t; diff --git a/samples/client/petstore/c/model/tag.h b/samples/client/petstore/c/model/tag.h index 7edf903ecf7..9e7b5d053a9 100644 --- a/samples/client/petstore/c/model/tag.h +++ b/samples/client/petstore/c/model/tag.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct tag_t tag_t; diff --git a/samples/client/petstore/c/model/user.h b/samples/client/petstore/c/model/user.h index d0d5ea97c4a..45fa42c3f91 100644 --- a/samples/client/petstore/c/model/user.h +++ b/samples/client/petstore/c/model/user.h @@ -11,6 +11,7 @@ #include "../external/cJSON.h" #include "../include/list.h" #include "../include/keyValuePair.h" +#include "../include/binary.h" typedef struct user_t user_t; diff --git a/samples/client/petstore/c/src/apiClient.c b/samples/client/petstore/c/src/apiClient.c index 5c363653abd..bb0fd8ef866 100644 --- a/samples/client/petstore/c/src/apiClient.c +++ b/samples/client/petstore/c/src/apiClient.c @@ -3,9 +3,6 @@ #include #include #include "../include/apiClient.h" -#ifdef OPENSSL -#include "openssl/pem.h" -#endif size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp); @@ -16,7 +13,7 @@ apiClient_t *apiClient_create() { apiClient->sslConfig = NULL; apiClient->dataReceived = NULL; apiClient->response_code = 0; - apiClient->apiKeys = NULL; + apiClient->apiKeys_api_key = NULL; apiClient->accessToken = NULL; return apiClient; @@ -24,7 +21,7 @@ apiClient_t *apiClient_create() { apiClient_t *apiClient_create_with_base_path(const char *basePath , sslConfig_t *sslConfig -, list_t *apiKeys +, list_t *apiKeys_api_key ) { curl_global_init(CURL_GLOBAL_ALL); apiClient_t *apiClient = malloc(sizeof(apiClient_t)); @@ -42,16 +39,16 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath apiClient->dataReceived = NULL; apiClient->response_code = 0; - if(apiKeys!= NULL) { - apiClient->apiKeys = list_create(); + if(apiKeys_api_key!= NULL) { + apiClient->apiKeys_api_key = list_create(); listEntry_t *listEntry = NULL; - list_ForEach(listEntry, apiKeys) { + list_ForEach(listEntry, apiKeys_api_key) { keyValuePair_t *pair = listEntry->data; keyValuePair_t *pairDup = keyValuePair_create(strdup(pair->key), strdup(pair->value)); - list_addElement(apiClient->apiKeys, pairDup); + list_addElement(apiClient->apiKeys_api_key, pairDup); } }else{ - apiClient->apiKeys = NULL; + apiClient->apiKeys_api_key = NULL; } apiClient->accessToken = NULL; @@ -62,9 +59,9 @@ void apiClient_free(apiClient_t *apiClient) { if(apiClient->basePath) { free(apiClient->basePath); } - if(apiClient->apiKeys) { + if(apiClient->apiKeys_api_key) { listEntry_t *listEntry = NULL; - list_ForEach(listEntry, apiClient->apiKeys) { + list_ForEach(listEntry, apiClient->apiKeys_api_key) { keyValuePair_t *pair = listEntry->data; if(pair->key){ free(pair->key); @@ -74,7 +71,7 @@ void apiClient_free(apiClient_t *apiClient) { } keyValuePair_free(pair); } - list_free(apiClient->apiKeys); + list_free(apiClient->apiKeys_api_key); } if(apiClient->accessToken) { free(apiClient->accessToken); @@ -391,9 +388,9 @@ void apiClient_invoke(apiClient_t *apiClient, } // this would only be generated for apiKey authentication - if (apiClient->apiKeys != NULL) + if (apiClient->apiKeys_api_key != NULL) { - list_ForEach(listEntry, apiClient->apiKeys) { + list_ForEach(listEntry, apiClient->apiKeys_api_key) { keyValuePair_t *apiKey = listEntry->data; if((apiKey->key != NULL) && (apiKey->value != NULL) ) @@ -522,39 +519,3 @@ char *strReplace(char *orig, char *rep, char *with) { return result; } -char *sbi_base64encode (const void *b64_encode_this, int encode_this_many_bytes){ -#ifdef OPENSSL - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less. - BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data. - BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters. - BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure. - BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null. - (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail. - return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct). -#endif -} - -char *sbi_base64decode (const void *b64_decode_this, int decode_this_many_bytes){ -#ifdef OPENSSL - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO. - BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines. - int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written. - while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte. - decoded_byte_index++; //Increment the index until read of BIO decoded data is complete. - } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - return base64_decoded; //Returns base-64 decoded data with trailing null terminator. -#endif -} diff --git a/samples/client/petstore/c/src/binary.c b/samples/client/petstore/c/src/binary.c new file mode 100644 index 00000000000..ddd162a91f3 --- /dev/null +++ b/samples/client/petstore/c/src/binary.c @@ -0,0 +1,58 @@ +#include +#include +#include "../include/binary.h" +#ifdef OPENSSL +#include "openssl/pem.h" +#endif + +binary_t* instantiate_binary_t(char* data, int len) { + binary_t* ret = malloc(sizeof(struct binary_t)); + ret->len=len; + ret->data = malloc(len); + memcpy(ret->data, data, len); + return ret; +} + +char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){ +#ifdef OPENSSL + BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data. + b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO. + BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less. + BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data. + BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters. + BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure. + BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed. + BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null. + (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail. + return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct). +#else // OPENSSL +#warning Data will not be encoded. If you want to use function "base64encode", please define "-DOPENSSL" when building the library. + return NULL; +#endif // OPENSSL +} + +char *base64decode (const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes){ +#ifdef OPENSSL + BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null. + b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO. + BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source. + BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines. + int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written. + while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte. + decoded_byte_index++; //Increment the index until read of BIO decoded data is complete. + } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error. + BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + *decoded_bytes = decoded_byte_index; + return base64_decoded; //Returns base-64 decoded data with trailing null terminator. +#else // OPENSSL +#warning Data will not be decoded. If you want to use function "base64decode", please define "-DOPENSSL" when building the library. + return NULL; +#endif // OPENSSL +}