Пример #1
0
/**
 * ulfius_init_request
 * Initialize a request structure by allocating inner elements
 * return U_OK on success
 */
int ulfius_init_request(struct _u_request * request) {
  if (request != NULL) {
    request->map_url = malloc(sizeof(struct _u_map));
    request->map_header = malloc(sizeof(struct _u_map));
    request->map_cookie = malloc(sizeof(struct _u_map));
    request->map_post_body = malloc(sizeof(struct _u_map));
    if (request->map_post_body == NULL || request->map_cookie == NULL || 
        request->map_url == NULL || request->map_header == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for request->map*");
      ulfius_clean_request(request);
      return U_ERROR_MEMORY;
    }
    u_map_init(request->map_url);
    u_map_init(request->map_header);
    u_map_init(request->map_cookie);
    u_map_init(request->map_post_body);
    request->http_verb = NULL;
    request->http_url = NULL;
    request->client_address = NULL;
    request->json_body = NULL;
    request->json_has_error = 0;
    request->binary_body = NULL;
    request->binary_body_length = 0;
    return U_OK;
  } else {
    return U_ERROR_PARAMS;
  }
}
Пример #2
0
/**
 * 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;
}
Пример #3
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;
}
Пример #4
0
int main (int argc, char **argv) {
  
  struct _u_map headers, url_params, post_params, req_headers;
  char * string_body = "param1=one&param2=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;
}
Пример #5
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;
}