/*! * test_utils.c * * Copyright (c) 2015-2020, NADAL Jean-Baptiste. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * @Author: NADAL Jean-Baptiste * @Date: 24/02/2020 * */ /*--------------------------------------------------------------------------*/ #define kpost_method "POST" #define kget_method "GET" #define kput_method "PUT" #define kdelete_method "DELETE" #define kserver_port "7777" /*--------------------------------------------------------------------------*/ int rows_eq(int *a, int *b) { int i; for (i = 0; i < 16; i++) { if (a[i] != b[i]) { return 0; } } return 1; } /*--------------------------------------------------------------------------*/ void dump_row(long a_count, int a_numinrow, int *a_chs) { int i; printf("%08lX:", a_count - a_numinrow); if (a_numinrow > 0) { for (i = 0; i < a_numinrow; i++) { if (i == 8) { printf(" :"); } printf(" %02X", a_chs[i]); } for (i = a_numinrow; i < 16; i++) { if (i == 8) { printf(" :"); } printf(" "); } printf(" "); for (i = 0; i < a_numinrow; i++) { if (isprint(a_chs[i])) { printf("%c", a_chs[i]); } else { printf("."); } } } printf("\n"); } /*--------------------------------------------------------------------------*/ void dump_memory(void const *a_buffer, size_t a_len) { unsigned char *the_buf = (unsigned char *)a_buffer; long the_count = 0; int the_numinrow = 0; int the_chs[16]; int the_oldchs[16] = {0}; int the_showed_dots = 0; size_t i; for (i = 0; i < a_len; i++) { int the_ch = the_buf[i]; if (the_numinrow == 16) { int j; if (rows_eq(the_oldchs, the_chs)) { if (!the_showed_dots) { the_showed_dots = 1; printf(" .. .. .. .. .. .. .. .. : .. .. .. .. .. .. .. ..\n"); } } else { the_showed_dots = 0; dump_row(the_count, the_numinrow, the_chs); } for (j = 0; j < 16; j++) { the_oldchs[j] = the_chs[j]; } the_numinrow = 0; } the_count++; the_chs[the_numinrow++] = the_ch; } dump_row(the_count, the_numinrow, the_chs); if (the_numinrow != 0) { printf("%08lX:\n", the_count); } } /*--------------------------------------------------------------------------*/ size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) { size_t body_size = 0; size_t curent_size = size * nmemb; char *body = *((char **)stream); char *new_body; if (body != 0) { body_size = strlen(body); } new_body = (char *)realloc(body, curent_size + body_size + 1); if (new_body == NULL) { free(body); return 0; } memcpy(new_body + body_size, ptr, curent_size); new_body[curent_size + body_size] = 0; *((char **)stream) = new_body; return curent_size; } /*--------------------------------------------------------------------------*/ int exec_request(const char *request, const char *path, int expected_code, const char *body, const char *expected_body, bool debug) { int ret = 0; CURL *curl_handle; CURLcode res; char *resp_body = NULL; long http_result_code; /* init libcurl */ curl_global_init(CURL_GLOBAL_ALL); /* init the curl session */ curl_handle = curl_easy_init(); /* specify URL and method */ curl_easy_setopt(curl_handle, CURLOPT_URL, path); if (strcmp(request, kget_method) == 0) { curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1); } else if (strcmp(request, kdelete_method) == 0) { curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kdelete_method); } else if (strcmp(request, kput_method) == 0) { curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kput_method); curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); } else if (strcmp(request, kpost_method) == 0) { curl_easy_setopt(curl_handle, CURLOPT_POST, 0); curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); } curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 2); if (debug) curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); /* send all data to this function */ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &resp_body); curl_easy_setopt(curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); /* get it! */ res = curl_easy_perform(curl_handle); if (res != CURLE_OK) { printf("Error: %d\n", res); } ASSERT_EQUAL_INT(res, CURLE_OK); curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_result_code); ASSERT_EQUAL_INT(http_result_code, expected_code); if (resp_body == NULL) { if (expected_code != 204) res = 1; } else { res = strcmp(expected_body, resp_body); if ((debug) && (res != 0)) { printf("res: != %d\n", res); printf("resp_body:\n=========\n"); dump_memory(resp_body, strlen(resp_body)); printf("expected_body:\n==============\n"); dump_memory(expected_body, strlen(expected_body)); } } if (debug) printf ("body: %s != expected_body: %s\n", resp_body, expected_body); if (res != 0) { ret = 2; goto exit; } ASSERT_EQUAL_INT(res, 0); exit: free(resp_body); /* cleanup curl stuff */ curl_easy_cleanup(curl_handle); /* we're done with libcurl, so clean it up */ curl_global_cleanup(); return ret; }