int callback_get_audio_stream (const struct _u_request * request, struct _u_response * response, void * user_data) { FILE * file = fopen((char *)user_data, "rb"); int fd; struct stat buf; printf("stream audio file\n"); if (file != NULL) { fd = fileno (file); if (-1 == fd) { fclose (file); return U_ERROR; /* internal error */ } if ( (0 != fstat (fd, &buf)) || (! S_ISREG (buf.st_mode)) ) { /* not a regular file, refuse to serve */ fclose (file); file = NULL; return U_ERROR; } u_map_put(response->map_header, "Content-Type", "audio/mpeg"); ulfius_set_stream_response(response, 200, stream_audio_file, free_stream_audio_file, buf.st_size, 32 * 1024, file); return U_OK; } else { return U_ERROR; } }
/** * write_header * Write the header value into the response map_header structure * return the size_t of the header written */ static size_t write_header(void * buffer, size_t size, size_t nitems, void * user_data) { struct _u_response * response = (struct _u_response *) user_data; char * header = (char *)buffer, * key, * value, * saveptr; if (strchr(header, ':') != NULL) { if (response->map_header != NULL) { // Expecting a header (key: value) key = trim_whitespace(strtok_r(header, ":", &saveptr)); value = trim_whitespace(strtok_r(NULL, ":", &saveptr)); u_map_put(response->map_header, key, value); } } else if (strlen(trim_whitespace(header)) > 0) { // Expecting the HTTP/x.x header if (response->protocol != NULL) { free(response->protocol); } response->protocol = nstrdup(header); if (response->protocol == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for response->protocol"); return 0; } } return nitems * size; }
/** * Main function */ int main (int argc, char **argv) { // jansson integer type can vary #if JSON_INTEGER_IS_LONG_LONG long long nb_sheep = 0; #else long nb_sheep = 0; #endif // Initialize the instance struct _u_instance instance; if (ulfius_init_instance(&instance, PORT, NULL) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_init_instance, abort"); return(1); } // MIME types that will define the static files struct _u_map mime_types; u_map_init(&mime_types); u_map_put(&mime_types, ".html", "text/html"); u_map_put(&mime_types, ".css", "text/css"); u_map_put(&mime_types, ".js", "application/javascript"); u_map_put(&mime_types, ".png", "image/png"); u_map_put(&mime_types, ".jpeg", "image/jpeg"); u_map_put(&mime_types, ".jpg", "image/jpeg"); u_map_put(&mime_types, "*", "application/octet-stream"); // Endpoint list declaration // The first 3 are webservices with a specific url // The last endpoint will be called for every GET call and will serve the static files ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, NULL, &callback_sheep_counter_start, &nb_sheep); ulfius_add_endpoint_by_val(&instance, "PUT", PREFIX, NULL, &callback_sheep_counter_add, &nb_sheep); ulfius_add_endpoint_by_val(&instance, "DELETE", PREFIX, NULL, &callback_sheep_counter_reset, &nb_sheep); ulfius_add_endpoint_by_val(&instance, "GET", NULL, "*", &callback_static_file, &mime_types); // Start the framework if (ulfius_start_framework(&instance) == U_OK) { printf("Start sheep counter on port %d\n", instance.port); // Wait for the user to press <enter> on the console to quit the application getchar(); } else { printf("Error starting framework\n"); } // Clean the mime map u_map_clean(&mime_types); printf("End framework\n"); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); return 0; }
/** * ulfius_parse_url * fills map with the keys/values defined in the url that are described in the endpoint format url * return U_OK on success */ int ulfius_parse_url(const char * url, const struct _u_endpoint * endpoint, struct _u_map * map) { char * saveptr = NULL, * cur_word = NULL, * url_cpy = NULL, * url_cpy_addr = NULL; char * saveptr_format = NULL, * saveptr_prefix = NULL, * cur_word_format = NULL, * url_format_cpy = NULL, * url_format_cpy_addr = NULL; if (map != NULL && endpoint != NULL) { url_cpy = url_cpy_addr = nstrdup(url); url_format_cpy = url_format_cpy_addr = nstrdup(endpoint->url_prefix); cur_word = strtok_r( url_cpy, ULFIUS_URL_SEPARATOR, &saveptr ); if (endpoint->url_prefix != NULL && url_format_cpy == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for url_format_cpy"); } else if (url_format_cpy != NULL) { cur_word_format = strtok_r( url_format_cpy, ULFIUS_URL_SEPARATOR, &saveptr_prefix ); } while (cur_word_format != NULL && cur_word != NULL) { // Ignoring url_prefix words cur_word = strtok_r( NULL, ULFIUS_URL_SEPARATOR, &saveptr ); cur_word_format = strtok_r( NULL, ULFIUS_URL_SEPARATOR, &saveptr_prefix ); } free(url_format_cpy_addr); url_format_cpy = url_format_cpy_addr = nstrdup(endpoint->url_format); if (endpoint->url_format != NULL && url_format_cpy == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for url_format_cpy"); } else if (url_format_cpy != NULL) { cur_word_format = strtok_r( url_format_cpy, ULFIUS_URL_SEPARATOR, &saveptr_format ); } while (cur_word_format != NULL && cur_word != NULL) { if (cur_word_format[0] == ':' || cur_word_format[0] == '@') { if (u_map_put(map, cur_word_format+1, cur_word) != U_OK) { url_cpy_addr = NULL; url_format_cpy_addr = NULL; return U_ERROR_MEMORY; } } cur_word = strtok_r( NULL, ULFIUS_URL_SEPARATOR, &saveptr ); cur_word_format = strtok_r( NULL, ULFIUS_URL_SEPARATOR, &saveptr_format ); } free(url_cpy_addr); free(url_format_cpy_addr); url_cpy_addr = NULL; url_format_cpy_addr = NULL; return U_OK; } else { return U_ERROR_PARAMS; } }
/** * serve a static file to the client as a very simple http server */ int callback_static_file (const struct _u_request * request, struct _u_response * response, void * user_data) { void * buffer = NULL; long length; FILE * f; char * file_path = malloc(strlen(request->http_url)+strlen(STATIC_FOLDER)+sizeof(char)); const char * content_type; snprintf(file_path, (strlen(request->http_url)+strlen(STATIC_FOLDER)+sizeof(char)), "%s%s", STATIC_FOLDER, request->http_url); if (access(file_path, F_OK) != -1) { f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = malloc(length*sizeof(void)); if (buffer) { fread (buffer, 1, length, f); } fclose (f); } if (buffer) { content_type = u_map_get((struct _u_map *)user_data, get_filename_ext(request->http_url)); response->binary_body = buffer; response->binary_body_length = length; u_map_put(response->map_header, "Content-Type", content_type); response->status = 200; } else { response->string_body = u_strdup(""); response->status = 404; } } else { response->string_body = u_strdup(""); response->status = 404; } free(file_path); return U_OK; }
int main (int argc, char **argv) { int ret; // Set the framework port number struct _u_instance instance; if (ulfius_init_instance(&instance, PORT, NULL) != U_OK) { printf("Error ulfius_init_instance, abort\n"); return(1); } u_map_put(instance.default_headers, "Access-Control-Allow-Origin", "*"); // Endpoint list declaration ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, NULL, NULL, NULL, NULL, &callback_get_stream, NULL); if (argc > 1) { ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/audio", NULL, NULL, NULL, &callback_get_audio_stream, argv[1]); } // Start the framework ret = ulfius_start_framework(&instance); if (ret == U_OK) { printf("Start framework on port %d\n", instance.port); // Wait for the user to press <enter> on the console to quit the application getchar(); } else { printf("Error starting framework\n"); } printf("End framework\n"); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); return 0; }
int main (int argc, char **argv) { int ret; // Set the framework port number struct _u_instance instance; y_init_logs("simple_example", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting simple_example"); if (ulfius_init_instance(&instance, PORT, NULL) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_init_instance, abort"); return(1); } u_map_put(instance.default_headers, "Access-Control-Allow-Origin", "*"); // Maximum body size sent by the client is 1 Kb instance.max_post_body_size = 1024; // Endpoint list declaration ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, NULL, NULL, NULL, NULL, &callback_get_test, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/empty", NULL, NULL, NULL, &callback_get_empty_response, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/multiple/:multiple/:multiple/:not_multiple", NULL, NULL, NULL, &callback_all_test_foo, NULL); ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, NULL, NULL, NULL, NULL, &callback_post_test, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/:foo", NULL, NULL, NULL, &callback_all_test_foo, "user data 1"); ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/:foo", NULL, NULL, NULL, &callback_all_test_foo, "user data 2"); ulfius_add_endpoint_by_val(&instance, "PUT", PREFIX, "/:foo", NULL, NULL, NULL, &callback_all_test_foo, "user data 3"); ulfius_add_endpoint_by_val(&instance, "DELETE", PREFIX, "/:foo", NULL, NULL, NULL, &callback_all_test_foo, "user data 4"); ulfius_add_endpoint_by_val(&instance, "PUT", PREFIXJSON, NULL, NULL, NULL, NULL, &callback_put_jsontest, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIXCOOKIE, "/:lang/:extra", NULL, NULL, NULL, &callback_get_cookietest, NULL); // default_endpoint declaration ulfius_set_default_endpoint(&instance, NULL, NULL, NULL, &callback_default, NULL); // Start the framework if (argc == 4 && strcmp("-secure", argv[1]) == 0) { // If command-line options are -secure <key_file> <cert_file>, then open an https connection char * key_pem = read_file(argv[2]), * cert_pem = read_file(argv[3]); ret = ulfius_start_secure_framework(&instance, key_pem, cert_pem); free(key_pem); free(cert_pem); } else { // Open an http connection ret = ulfius_start_framework(&instance); } if (ret == U_OK) { y_log_message(Y_LOG_LEVEL_DEBUG, "Start %sframework on port %d", ((argc == 4 && strcmp("-secure", argv[1]) == 0)?"secure ":""), instance.port); // Wait for the user to press <enter> on the console to quit the application getchar(); } else { y_log_message(Y_LOG_LEVEL_DEBUG, "Error starting framework"); } y_log_message(Y_LOG_LEVEL_DEBUG, "End framework"); y_close_logs(); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); return 0; }
int main (int argc, char **argv) { y_init_logs("test_u_map", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting test_u_map"); struct _u_map map, * map_copy; char * print, * print_copy; u_map_init(&map); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 1, map is\n%s\n", print); free(print); u_map_put(&map, "key1", "value1"); u_map_put(&map, "key2", "value2"); u_map_put(&map, "key3", "value3"); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 2, map is\n%s\n", print); free(print); u_map_put(&map, "key2", "value4"); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 3, map is\n%s\n", print); free(print); map_copy = u_map_copy(&map); u_map_put(map_copy, "key4", "value5"); print = print_map(&map); print_copy = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 4, map is\n%s\nmap_copy is\n%s\n", print, print_copy); free(print); free(print_copy); u_map_remove_at(&map, 2); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 5: remove item 2 from map, map is\n%s\n", print); free(print); u_map_remove_from_key(map_copy, "key1"); print = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 6: remove key:key1 from map_copy, map is\n%s\n", print); free(print); u_map_remove_from_key(map_copy, "key_nope"); print = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 7: remove key:key_nope from map_copy, map is\n%s\n", print); free(print); u_map_remove_from_key_case(map_copy, "Key2"); print = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 8: remove case key:Key2 from map_copy, map is\n%s\n", print); free(print); u_map_remove_from_value(map_copy, "value3"); print = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 9: remove value:value3 from map_copy, map is\n%s\n", print); free(print); u_map_remove_from_value_case(map_copy, "Value5"); print = print_map(map_copy); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 10: remove case value:Value5 from map_copy, map is\n%s\n", print); free(print); y_log_message(Y_LOG_LEVEL_DEBUG, "map has key key1? %d", u_map_has_key(&map, "key1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has key key_nope? %d", u_map_has_key(&map, "key_nope")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has key Key1? %d", u_map_has_key(&map, "Key1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has key Key1 (no case) ? %d", u_map_has_key_case(&map, "Key1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has key Key_nope (no case) ? %d", u_map_has_key_case(&map, "Key_nope")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has value value1? %d", u_map_has_value(&map, "value1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has value value_nope? %d", u_map_has_value(&map, "value_nope")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has value Value1? %d", u_map_has_value(&map, "Value1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has value Value1 (no case) ? %d", u_map_has_value_case(&map, "Value1")); y_log_message(Y_LOG_LEVEL_DEBUG, "map has value Value_nope (no case) ? %d", u_map_has_value_case(&map, "Value_nope")); y_log_message(Y_LOG_LEVEL_DEBUG, "get value from key key1: %s", u_map_get(&map, "key1")); y_log_message(Y_LOG_LEVEL_DEBUG, "get value from key key_nope: %s", u_map_get(&map, "key_nope")); y_log_message(Y_LOG_LEVEL_DEBUG, "get value from key Key1 (no case): %s", u_map_get_case(&map, "Key1")); y_log_message(Y_LOG_LEVEL_DEBUG, "get value from key Key_nope (no case): %s", u_map_get_case(&map, "Key_nope")); put_file_content_in_map(&map, "../sheep_counter/static/sheep.png", 0); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 11, map is\n%s\n", print); free(print); u_map_remove_from_key(&map, "../sheep_counter/static/sheep.png"); put_file_content_in_map(&map, "Makefile", 0); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 12, map is\n%s\n", print); free(print); u_map_put_binary(&map, "Makefile", "Replace the first characters", 0, strlen("Replace the first characters")); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 12, map is\n%s\n", print); free(print); u_map_put_binary(&map, "Makefile", "Append at the end of the value", u_map_get_length(&map, "Makefile"), strlen("Append at the end of the value")); print = print_map(&map); y_log_message(Y_LOG_LEVEL_DEBUG, "iteration 12, map is\n%s\n", print); free(print); u_map_clean(&map); u_map_clean_full(map_copy); y_close_logs(); return 0; }
int main (int argc, char **argv) { struct _u_map headers, url_params, post_params, req_headers; char * string_body = "param1=one¶m2=two"; json_t * json_body = json_object(); struct _u_response response; int res; u_map_init(&headers); u_map_init(&url_params); u_map_put(&url_params, "test", "one"); u_map_put(&url_params, "other_test", "two"); u_map_init(&post_params); u_map_put(&post_params, "third_test", "three"); u_map_put(&post_params, "fourth_test", "four"); u_map_put(&post_params, "extreme_test", "Here ! are %9_ some $ ö\\)]= special châraçters"); u_map_init(&req_headers); u_map_put(&req_headers, "Content-Type", MHD_HTTP_POST_ENCODING_FORM_URLENCODED); json_object_set_new(json_body, "param1", json_string("one")); json_object_set_new(json_body, "param2", json_string("two")); struct _u_request req_list[] = { {"GET", SERVER_URL_PREFIX "/get/", 0, NULL, NULL, NULL, &url_params, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0}, // Parameters in url {"DELETE", SERVER_URL_PREFIX "/delete/", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0}, // No parameters {"POST", SERVER_URL_PREFIX "/post/param/", 0, NULL, NULL, NULL, NULL, NULL, NULL, &post_params, NULL, NULL, 0, string_body, strlen(string_body)}, // Parameters in post_map and string_body {"POST", SERVER_URL_PREFIX "/post/plain/", 0, NULL, NULL, NULL, NULL, &req_headers, NULL, NULL, NULL, NULL, 0, string_body, strlen(string_body)}, // Paremeters in string body, header MHD_HTTP_POST_ENCODING_FORM_URLENCODED {"POST", SERVER_URL_PREFIX "/post/json/", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, json_body, NULL, 0, NULL, 0}, // Parameters in json_body {"PUT", SERVER_URL_PREFIX "/put/plain", 0, NULL, NULL, NULL, NULL, &req_headers, NULL, NULL, NULL, NULL, 0, string_body, strlen(string_body)}, // Paremeters in string body, header MHD_HTTP_POST_ENCODING_FORM_URLENCODED {"PUT", SERVER_URL_PREFIX "/put/json", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, json_body, NULL, 0, NULL, 0}, // Parameters in json_body {"POST", SERVER_URL_PREFIX "/post/param/", 0, NULL, NULL, NULL, NULL, NULL, NULL, &post_params, NULL, NULL, 0, NULL, 0} // Parameters in post_map }; printf("Press <enter> to run get test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[0], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run get test with no interest on the response\n"); getchar(); printf("Request sent, result is %d\n", ulfius_send_http_request(&req_list[0], NULL)); printf("Press <enter> to run delete test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[1], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run post parameters test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[2], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run post plain test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[3], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run post json test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[4], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run put plain test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[5], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run put json test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[6], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); printf("Press <enter> to run post only test\n"); getchar(); ulfius_init_response(&response); res = ulfius_send_http_request(&req_list[7], &response); if (res == U_OK) { print_response(&response); } else { printf("Error in http request: %d\n", res); } ulfius_clean_response(&response); // Wait for the user to press <enter> on the console to quit the application printf("Press <enter> to quit test\n"); getchar(); json_decref(json_body); u_map_clean(&headers); u_map_clean(&url_params); u_map_clean(&post_params); u_map_clean(&req_headers); return 0; }
/** * ulfius_send_http_streaming_request * Send a HTTP request and store the result into a _u_response * Except for the body which will be available using write_body_function in the write_body_data * return U_OK on success */ int ulfius_send_http_streaming_request(const struct _u_request * request, struct _u_response * response, size_t (* write_body_function)(void * contents, size_t size, size_t nmemb, void * user_data), void * write_body_data) { CURLcode res; CURL * curl_handle = NULL; struct curl_slist * header_list = NULL; char * key_esc, * value_esc, * cookie, * header, * param, * fp = "?", * np = "&"; const char * value, ** keys; int i, has_params = 0, len; struct _u_request * copy_request = NULL; if (request != NULL) { // Duplicate the request and work on it copy_request = ulfius_duplicate_request(request); if (copy_request == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error ulfius_duplicate_request"); return U_ERROR_MEMORY; } curl_handle = curl_easy_init(); if (copy_request != NULL) { // Append header values if (copy_request->map_header == NULL) { copy_request->map_header = malloc(sizeof(struct _u_map)); if (copy_request->map_header == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for copy_request->map_header"); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } if (u_map_init(copy_request->map_header) != U_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } } // Set basic auth if defined if (copy_request->auth_basic_user != NULL && copy_request->auth_basic_password != NULL) { if (curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC) == CURLE_OK) { if (curl_easy_setopt(curl_handle, CURLOPT_USERNAME, copy_request->auth_basic_user) != CURLE_OK || curl_easy_setopt(curl_handle, CURLOPT_PASSWORD, copy_request->auth_basic_password) != CURLE_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting HTTP Basic user name or password"); ulfius_clean_request_full(copy_request); curl_easy_cleanup(curl_handle); return U_ERROR_LIBCURL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting HTTP Basic Auth option"); ulfius_clean_request_full(copy_request); curl_easy_cleanup(curl_handle); return U_ERROR_LIBCURL; } } has_params = (strchr(copy_request->http_url, '?') != NULL); if (copy_request->map_url != NULL && u_map_count(copy_request->map_url) > 0) { // Append url parameters keys = u_map_enum_keys(copy_request->map_url); // Append parameters from map_url for (i=0; keys != NULL && keys[i] != NULL; i++) { value = u_map_get(copy_request->map_url, keys[i]); key_esc = curl_easy_escape(curl_handle, keys[i], 0); value_esc = curl_easy_escape(curl_handle, value, 0); if (key_esc == NULL || value_esc == NULL) { curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } param = msprintf("%s=%s", key_esc, value_esc); if (param == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for param"); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } if (has_params == 0) { copy_request->http_url = realloc(copy_request->http_url, strlen(copy_request->http_url) + strlen(param) + 2); if (copy_request->http_url == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for copy_request->http_url"); free(param); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } strcat(copy_request->http_url, fp); strcat(copy_request->http_url, param); has_params = 1; } else { copy_request->http_url = realloc(copy_request->http_url, strlen(copy_request->http_url) + strlen(param) + 2); if (copy_request->http_url == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for copy_request->http_url"); free(param); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } strcat(copy_request->http_url, np); strcat(copy_request->http_url, param); } free(param); curl_free(key_esc); curl_free(value_esc); } } if (copy_request->json_body != NULL) { // Append json body parameter free(copy_request->binary_body); copy_request->binary_body = json_dumps(copy_request->json_body, JSON_COMPACT); if (copy_request->binary_body == NULL) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } else { copy_request->binary_body_length = strlen(copy_request->binary_body); if (u_map_put(copy_request->map_header, ULFIUS_HTTP_HEADER_CONTENT, ULFIUS_HTTP_ENCODING_JSON) != U_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } } } else if (u_map_count(copy_request->map_post_body) > 0) { // Append MHD_HTTP_POST_ENCODING_FORM_URLENCODED post parameters keys = u_map_enum_keys(copy_request->map_post_body); for (i=0; keys != NULL && keys[i] != NULL; i++) { // Build parameter value = u_map_get(copy_request->map_post_body, keys[i]); if (value == NULL) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } key_esc = curl_easy_escape(curl_handle, keys[i], 0); value_esc = curl_easy_escape(curl_handle, value, 0); if (key_esc == NULL || value_esc == NULL) { curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } param = msprintf("%s=%s", key_esc, value_esc); if (param == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for param"); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } // Append parameter to body if (copy_request->binary_body_length == 0) { len = strlen(param) + sizeof(char); copy_request->binary_body = malloc(len); if (copy_request->binary_body == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for copy_request->binary_body"); free(param); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } strcpy(copy_request->binary_body, ""); strcat(copy_request->binary_body, param); copy_request->binary_body_length = len; } else { len = (copy_request->binary_body_length + strlen(param) + sizeof(char)); copy_request->binary_body = realloc(copy_request->binary_body, len); if (copy_request->binary_body == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for copy_request->binary_body"); free(param); curl_free(key_esc); curl_free(value_esc); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } memcpy(copy_request->binary_body + copy_request->binary_body_length, np, 1); memcpy(copy_request->binary_body + copy_request->binary_body_length + 1, param, strlen(param)); copy_request->binary_body_length = len; } free(param); curl_free(key_esc); curl_free(value_esc); } if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, copy_request->binary_body) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting POST fields"); return U_ERROR_LIBCURL; } if (u_map_put(copy_request->map_header, ULFIUS_HTTP_HEADER_CONTENT, MHD_HTTP_POST_ENCODING_FORM_URLENCODED) != U_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } } if (copy_request->map_header != NULL && u_map_count(copy_request->map_header) > 0) { // Append map headers keys = u_map_enum_keys(copy_request->map_header); for (i=0; keys != NULL && keys[i] != NULL; i++) { value = u_map_get(copy_request->map_header, keys[i]); if (value == NULL) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } header = msprintf("%s:%s", keys[i], value); if (header == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for header"); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } header_list = curl_slist_append(header_list, header); if (header_list == NULL) { free(header); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } free(header); } } if (copy_request->map_cookie != NULL && u_map_count(copy_request->map_cookie) > 0) { // Append cookies keys = u_map_enum_keys(copy_request->map_cookie); for (i=0; keys != NULL && keys[i] != NULL; i++) { value = u_map_get(copy_request->map_cookie, keys[i]); if (value == NULL) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } cookie = msprintf("%s=%s", keys[i], value); if (cookie == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for cookie"); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } if (curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookie) != CURLE_OK) { free(cookie); ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); return U_ERROR_MEMORY; } free(cookie); } } // Request parameters if (curl_easy_setopt(curl_handle, CURLOPT_URL, copy_request->http_url) != CURLE_OK || curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, copy_request->http_verb) != CURLE_OK || curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, header_list) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting libcurl options (1)"); return U_ERROR_LIBCURL; } // Set CURLOPT_WRITEFUNCTION if specified if (write_body_function != NULL && curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_body_function) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting libcurl options (2)"); return U_ERROR_LIBCURL; } // Set CURLOPT_WRITEDATA if specified if (write_body_data != NULL && curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, write_body_data) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting libcurl options (3)"); return U_ERROR_LIBCURL; } // Disable certificate validation if needed if (!copy_request->check_server_certificate) { if (curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0) != CURLE_OK || curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting libcurl options (4)"); return U_ERROR_LIBCURL; } } // Response parameters if (response != NULL) { if (response->map_header != NULL) { if (curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, write_header) != CURLE_OK || curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, response) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting headers"); return U_ERROR_LIBCURL; } } } if (copy_request->binary_body != NULL) { if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, copy_request->binary_body) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting POST fields"); return U_ERROR_LIBCURL; } if (copy_request->binary_body_length > 0) { if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, copy_request->binary_body_length) != CURLE_OK) { ulfius_clean_request_full(copy_request); curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting POST fields"); return U_ERROR_LIBCURL; } } } if (curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1) != CURLE_OK) { curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); ulfius_clean_request_full(copy_request); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting libcurl CURLOPT_NOSIGNAL"); return U_ERROR_LIBCURL; } res = curl_easy_perform(curl_handle); if(res == CURLE_OK && response != NULL) { if (curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &response->status) != CURLE_OK) { curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); ulfius_clean_request_full(copy_request); y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error executing http request, libcurl error: %d, error message %s", res, curl_easy_strerror(res)); return U_ERROR_LIBCURL; } } curl_slist_free_all(header_list); curl_easy_cleanup(curl_handle); ulfius_clean_request_full(copy_request); if (res == CURLE_OK) { return U_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error executing curl command: %s", curl_easy_strerror(res)); return U_ERROR_LIBCURL; } } } return U_ERROR_PARAMS; }