From eaeaa6474adcad32744e11eee5d3687cc54e058f Mon Sep 17 00:00:00 2001 From: armatusmiles <akurotych@gmail.com> Date: Fri, 8 Feb 2019 00:02:02 +0700 Subject: [PATCH] [+] Realization dap_http_user_agent with unit-tests --- http_server/http_client/dap_http_user_agent.c | 142 +++++++++++++++--- http_server/http_client/dap_http_user_agent.h | 68 ++++++--- test/http_server/CMakeLists.txt | 2 +- test/http_server/dap_http_user_agent_test.c | 133 ++++++++++++++++ test/http_server/dap_http_user_agent_test.h | 6 + test/http_server/main.c | 2 + 6 files changed, 311 insertions(+), 42 deletions(-) create mode 100644 test/http_server/dap_http_user_agent_test.c create mode 100644 test/http_server/dap_http_user_agent_test.h diff --git a/http_server/http_client/dap_http_user_agent.c b/http_server/http_client/dap_http_user_agent.c index b7e2a6e..92b851a 100644 --- a/http_server/http_client/dap_http_user_agent.c +++ b/http_server/http_client/dap_http_user_agent.c @@ -1,41 +1,145 @@ #include "dap_http_user_agent.h" +#include "dap_common.h" #include <string.h> +#include <stdio.h> -dap_http_user_agent_t* dap_http_user_agent_new(const char* a_name, - const char* a_comment, - unsigned short a_major_version, - unsigned short a_minor_version) +#define LOG_TAG "dap_http_user_agent" + +struct dap_http_user_agent { + char* name; // Ex: "DapVpnClient/2.2 + char* comment; // text after name + unsigned int major_version; + unsigned int minor_version; + char* string_representation; +}; + +static char* _dap_http_user_agent_to_string(dap_http_user_agent_ptr_t a_agent) { - // TODO - return NULL; + char * result = calloc(1, sizeof(*a_agent)); + + if(a_agent->comment) { + sprintf(result, "%s/%d.%d %s", a_agent->name, + a_agent->major_version, a_agent->minor_version, + a_agent->comment); + } else { + sprintf(result, "%s/%d.%d", a_agent->name, + a_agent->major_version, a_agent->minor_version); + } + + return result; } -void dap_http_user_agent_delete(dap_http_user_agent_t* a_agent) + +dap_http_user_agent_ptr_t dap_http_user_agent_new(const char* a_name, + unsigned short a_major_version, + unsigned short a_minor_version, + const char* a_comment) { - // TODO + if(a_name == NULL) { + log_it(L_ERROR, "Name is NULL"); + return NULL; + } + + dap_http_user_agent_ptr_t res = DAP_NEW_Z(struct dap_http_user_agent); + res->name = strdup(a_name); + res->comment = a_comment ? strdup(a_comment) : NULL; + res->major_version = a_major_version; + res->minor_version = a_minor_version; + res->string_representation = _dap_http_user_agent_to_string(res); + return res; } -dap_http_user_agent_t* dap_http_user_agent_new_from_str(const char* a_user_agent_str) +void dap_http_user_agent_delete(dap_http_user_agent_ptr_t a_agent) { - // TODO - return NULL; + free(a_agent->name); + free(a_agent->comment); + free(a_agent->string_representation); + free(a_agent); +} + +dap_http_user_agent_ptr_t dap_http_user_agent_new_from_str(const char* a_user_agent_str) +{ + dap_http_user_agent_ptr_t result = NULL; + /* Parse user agent line */ + char* user_agent_str_copy = strdup(a_user_agent_str); + char* version_line = strtok(user_agent_str_copy, " "); + char* comment = strtok(NULL, " "); + + char* l_name = strtok(version_line, "/"); + + char* l_version = strtok(NULL, "/"); + if(l_version == NULL) { + log_it(L_ERROR, "Wrong input value %s", a_user_agent_str); + goto END; + } + + char* l_major = strtok(l_version, "."); + char* l_minor = strtok(NULL, "."); + if(l_minor == NULL) { + log_it(L_ERROR, "Wrong input value %s", a_user_agent_str); + goto END; + } + /* PARSE LINE successful */ + + result = DAP_NEW_Z(struct dap_http_user_agent); + result->name = strdup(l_name); + result->comment = comment ? strdup(comment) : NULL; + result->major_version = (unsigned int) atoi(l_major); + result->minor_version = (unsigned int) atoi(l_minor); + +END: + free(user_agent_str_copy); + return result; } -char* dap_http_user_agent_to_string(dap_http_user_agent_t* a_agent) +void dap_http_user_agent_add_comment(dap_http_user_agent_ptr_t a_agent, const char* comment) { // TODO - return NULL; } +static inline int _compare_versions(unsigned int ver1, unsigned int ver2) +{ + if(ver1 > ver2) + return 1; + if(ver1 < ver2) + return -1; + return 0; +} -void dap_http_user_agent_add_comment(dap_http_user_agent_t* a_agent, const char* comment) +int dap_http_user_agent_versions_compare(dap_http_user_agent_ptr_t a_agent1, + dap_http_user_agent_ptr_t a_agent2) { - // TODO + if(strcmp(a_agent1->name, a_agent2->name) != 0) { + log_it(L_ERROR, "Names not equal"); + return -3; + } + + int result = _compare_versions(a_agent1->major_version, a_agent2->major_version); + if(result != 0) return result; + return _compare_versions(a_agent1->minor_version, a_agent2->minor_version); } -int dap_http_user_agent_versions_compare(dap_http_user_agent_t* a_agent1, - dap_http_user_agent_t* a_agent2) +unsigned int dap_http_user_agent_get_major_version(dap_http_user_agent_ptr_t a_agent) { - // TODO - return -2; + return a_agent->major_version; +} + +unsigned int dap_http_user_agent_get_minor_version(dap_http_user_agent_ptr_t a_agent) +{ + return a_agent->minor_version; +} + +const char* dap_http_user_agent_get_comment(dap_http_user_agent_ptr_t a_agent) +{ + return a_agent->comment; +} + +const char* dap_http_user_agent_get_name(dap_http_user_agent_ptr_t a_agent) +{ + return a_agent->name; +} + +char* dap_http_user_agent_to_string(dap_http_user_agent_ptr_t a_agent) +{ + return a_agent->string_representation; } diff --git a/http_server/http_client/dap_http_user_agent.h b/http_server/http_client/dap_http_user_agent.h index 8f37fc6..409565c 100644 --- a/http_server/http_client/dap_http_user_agent.h +++ b/http_server/http_client/dap_http_user_agent.h @@ -2,7 +2,7 @@ * Authors: * Anatolii Kurotych <akurotych@gmail.com> * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://github.com/demlabsinc + * DeM Labs Open source community https://github.com/kelvinblockchain * Copyright (c) 2017-2019 * All rights reserved. @@ -25,30 +25,54 @@ #ifndef _DAP_HTTP_USER_AGENT_H_ #define _DAP_HTTP_USER_AGENT_H_ -typedef struct dap_http_user_agent { - char* name; // Ex: "DapVpnClient/2.2 - char* comment; // text after name - unsigned short major_version; - unsigned short minor_version; -} dap_http_user_agent_t; +typedef struct dap_http_user_agent* dap_http_user_agent_ptr_t; -dap_http_user_agent_t* dap_http_user_agent_new(const char* a_name, - const char* a_comment, - unsigned short a_major_version, - unsigned short a_minor_version); +/** + * @brief dap_http_user_agent_new + * @param a_name + * @param a_comment - Can be NULL + * @param a_major_version + * @param a_minor_version + * @return + */ +dap_http_user_agent_ptr_t dap_http_user_agent_new(const char* a_name, + unsigned short a_major_version, + unsigned short a_minor_version, + const char* a_comment); -void dap_http_user_agent_delete(dap_http_user_agent_t* a_agent); +/** + * @brief dap_http_user_agent_delete + * @param a_agent + */ +void dap_http_user_agent_delete(dap_http_user_agent_ptr_t a_agent); -// If parsing not successful - returns NULL -dap_http_user_agent_t* dap_http_user_agent_new_from_str(const char* a_user_agent_str); +/** + * @brief dap_http_user_agent_new_from_str + * @param a_user_agent_str + * @return If parsing not successful - NULL + */ +dap_http_user_agent_ptr_t dap_http_user_agent_new_from_str(const char* a_user_agent_str); -// Allocates memory for string and returns result -char* dap_http_user_agent_to_string(dap_http_user_agent_t* a_agent); -// returns: -// 0 - equals -// 1 - a_agent1 version above then a_agent2 -// -1 - a_agent2 version above then a_agent1 -int dap_http_user_agent_versions_compare(dap_http_user_agent_t* a_agent1, - dap_http_user_agent_t* a_agent2); +/** + * @brief dap_http_user_agent_to_string + * @param a_agent + * @details Don't allocates memory. Uses internal buffer + * @return + */ +char* dap_http_user_agent_to_string(dap_http_user_agent_ptr_t a_agent); + +/** + * @brief dap_http_user_agent_versions_compare + * @param a_agent1 + * @param a_agent2 + * @return 0 == equals -1 == a_agent1 < a_agent2 | 1 == a_agent1 > a_agent2 | -2 == Erorr agent names not equals + */ +int dap_http_user_agent_versions_compare(dap_http_user_agent_ptr_t a_agent1, + dap_http_user_agent_ptr_t a_agent2); + +unsigned int dap_http_user_agent_get_major_version(dap_http_user_agent_ptr_t); +unsigned int dap_http_user_agent_get_minor_version(dap_http_user_agent_ptr_t); +const char* dap_http_user_agent_get_name(dap_http_user_agent_ptr_t); +const char* dap_http_user_agent_get_comment(dap_http_user_agent_ptr_t); #endif diff --git a/test/http_server/CMakeLists.txt b/test/http_server/CMakeLists.txt index a1a01f6..7c84471 100644 --- a/test/http_server/CMakeLists.txt +++ b/test/http_server/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB SRC *.h *.c) add_executable(${PROJECT_NAME} ${SRC}) -target_link_libraries(${PROJECT_NAME} dap_test dap_core) +target_link_libraries(${PROJECT_NAME} dap_test dap_core dap_http_server) add_test( NAME ${PROJECT_NAME} diff --git a/test/http_server/dap_http_user_agent_test.c b/test/http_server/dap_http_user_agent_test.c new file mode 100644 index 0000000..569a7ac --- /dev/null +++ b/test/http_server/dap_http_user_agent_test.c @@ -0,0 +1,133 @@ +#include "dap_http_user_agent_test.h" + + +static void dap_http_user_agent_test_new_delete() +{ + dap_http_user_agent_ptr_t agent = + dap_http_user_agent_new("DapVpn", 2, 3, NULL); + + dap_assert(dap_http_user_agent_get_major_version(agent) == 2, "Major version"); + dap_assert(dap_http_user_agent_get_minor_version(agent) == 3, "Minor version"); + + dap_http_user_agent_delete(agent); + dap_pass_msg("Allocate and delete object"); +} + +static void dap_http_user_agent_test_new_from_string() +{ + const char* user_agent_string = "DapVpn/23.32 somecomment"; + + dap_http_user_agent_ptr_t agent = + dap_http_user_agent_new_from_str(user_agent_string); + + dap_assert(dap_http_user_agent_get_major_version(agent) == 23, + "Check major version"); + dap_assert(dap_http_user_agent_get_minor_version(agent) == 32, + "Check minor version"); + + dap_assert(dap_str_equals(dap_http_user_agent_get_name(agent), "DapVpn"), + "Check agent name"); + dap_assert(dap_str_equals(dap_http_user_agent_get_comment(agent), "somecomment"), + "Check comment"); + + dap_http_user_agent_delete(agent); + dap_pass_msg("dap_http_user_agent_test_new_from_string"); +} + +static void dap_http_user_agent_test_new_from_string_without_comment() +{ + const char* user_agent_string = "DapVpn/23.32"; + + dap_http_user_agent_ptr_t agent = + dap_http_user_agent_new_from_str(user_agent_string); + + dap_assert(dap_http_user_agent_get_major_version(agent) == 23, + "Check major version"); + dap_assert(dap_http_user_agent_get_minor_version(agent) == 32, + "Check minor version"); + + dap_assert(dap_str_equals(dap_http_user_agent_get_name(agent), "DapVpn"), + "Check agent name"); + dap_assert(dap_http_user_agent_get_comment(agent) == NULL, + "Check comment"); + + dap_http_user_agent_delete(agent); + dap_pass_msg("dap_http_user_agent_test_new_from_string_without_comment"); +} + +static void dap_http_user_agent_test_to_string() +{ + dap_http_user_agent_ptr_t agent = + dap_http_user_agent_new("DapVpn", 2, 3, "Comment"); + const char* expected_string = "DapVpn/2.3 Comment"; + const char* result = dap_http_user_agent_to_string(agent); + + dap_assert(dap_str_equals(expected_string, result), result); + + dap_http_user_agent_delete(agent); + + dap_pass_msg("Allocate and delete object"); +} + +static void dap_http_user_agent_test_to_string_without_comment() +{ + dap_http_user_agent_ptr_t agent = + dap_http_user_agent_new("DapVpn", 2, 3, NULL); + const char* expected_string = "DapVpn/2.3"; + const char* result = dap_http_user_agent_to_string(agent); + + dap_assert(dap_str_equals(expected_string, result), result); + + dap_http_user_agent_delete(agent); + + dap_pass_msg("Allocate and delete object"); +} + +static void dap_http_user_agent_test_compare_versions() +{ + dap_http_user_agent_ptr_t agent1 = + dap_http_user_agent_new("DapVpn", 2, 3, NULL); + + dap_http_user_agent_ptr_t agent2 = + dap_http_user_agent_new("DapVpn", 2, 4, NULL); + + dap_http_user_agent_ptr_t agent3 = + dap_http_user_agent_new("DapVpn", 3, 1, NULL); + dap_http_user_agent_ptr_t agent4 = + dap_http_user_agent_new("OterName", 3, 11, NULL); + + + int result = dap_http_user_agent_versions_compare(agent1, agent4); + dap_assert(result == -3, "Checks different names"); + + result = dap_http_user_agent_versions_compare(agent1, agent2); + dap_assert(result == -1, "Checks agent1, agent2(above))"); + + result = dap_http_user_agent_versions_compare(agent1, agent1); + dap_assert(result == 0, "Checks agent1, agent1"); + + result = dap_http_user_agent_versions_compare(agent3, agent2); + dap_assert(result == 1, "Checks agent3(above major), agent2"); + + result = dap_http_user_agent_versions_compare(agent2, agent1); + dap_assert(result == 1, "Checks agent3(above major), agent2"); + + + dap_http_user_agent_delete(agent1); + dap_http_user_agent_delete(agent2); + dap_http_user_agent_delete(agent3); + dap_http_user_agent_delete(agent4); + + dap_pass_msg("Allocate and delete object"); +} + +void dap_http_user_agent_test_run(void) +{ + dap_print_module_name("dap_http_user_agent"); + dap_http_user_agent_test_new_delete(); + dap_http_user_agent_test_new_from_string(); + dap_http_user_agent_test_new_from_string_without_comment(); + dap_http_user_agent_test_to_string(); + dap_http_user_agent_test_to_string_without_comment(); + dap_http_user_agent_test_compare_versions(); +} diff --git a/test/http_server/dap_http_user_agent_test.h b/test/http_server/dap_http_user_agent_test.h new file mode 100644 index 0000000..1ef51b7 --- /dev/null +++ b/test/http_server/dap_http_user_agent_test.h @@ -0,0 +1,6 @@ +#pragma once + +#include "dap_test.h" +#include "dap_http_user_agent.h" + +void dap_http_user_agent_test_run(void); diff --git a/test/http_server/main.c b/test/http_server/main.c index d015aec..32fe6fa 100644 --- a/test/http_server/main.c +++ b/test/http_server/main.c @@ -1,7 +1,9 @@ #include "dap_common.h" +#include "dap_http_user_agent_test.h" int main(void) { // switch off debug info from library set_log_level(L_CRITICAL); + dap_http_user_agent_test_run(); return 0; } -- GitLab