Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
/**
 * ulfius_send_http_request
 * Send a HTTP request and store the result into a _u_response
 * return U_OK on success
 */
int ulfius_send_http_request(const struct _u_request * request, struct _u_response * response) {
  body body_data;
  body_data.size = 0;
  body_data.data = NULL;
  int res;
  const char * content_type;
  
  res = ulfius_send_http_streaming_request(request, response, ulfius_write_body, (void *)&body_data);
  
  if (res == U_OK && response != NULL) {
    if (body_data.data != NULL && body_data.size > 0) {
      response->string_body = nstrdup(body_data.data);
      response->binary_body = malloc(body_data.size);
      if (response->binary_body == NULL || response->string_body == NULL) {
        y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for response->binary_body");
        free(body_data.data);
        return U_ERROR_MEMORY;
      }
      memcpy(response->binary_body, body_data.data, body_data.size);
      response->binary_body_length = body_data.size;
      
      content_type = u_map_get_case(response->map_header, ULFIUS_HTTP_HEADER_CONTENT);
      if (content_type != NULL && 0 == nstrcmp(content_type, ULFIUS_HTTP_ENCODING_JSON)) {
        // Parsing json content
        response->json_body = json_loads(body_data.data, JSON_DECODE_ANY, NULL);
      }
    }
    free(body_data.data);
    return U_OK;
  } else {
    free(body_data.data);
    return res;
  }
}
Beispiel #3
0
int main (int argc, char **argv) {
  
  // 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);
  }
  
  // Endpoint list declaration
  ulfius_add_endpoint_by_val(&instance, "GET", NULL, "*", NULL, NULL, NULL, &callback_get, NULL);
  
  // Start the framework
  if (ulfius_start_framework(&instance) == U_OK) {
    printf("Start framework on port %d\n", instance.port);
    printf("Go to url / to proxify %s\n", PROXY_DEST);
    
    // 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;
}
Beispiel #4
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;
  }
}
Beispiel #5
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;
  }
}
Beispiel #6
0
/**
 * Get the dimmer value
 */
json_t * b_device_get_dimmer (json_t * device, const char * dimmer_name, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command get_dimmer for dimmer %s on device %s", dimmer_name, json_string_value(json_object_get(device, "name")));
  if (0 == o_strcmp(dimmer_name, "di1") || 0 == o_strcmp(dimmer_name, "di2")) {
    return json_pack("{sisI}", "result", WEBSERVICE_RESULT_OK, "value", json_integer_value(json_object_get(json_object_get((json_t *)device_ptr, "dimmers"), dimmer_name)));
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #7
0
/**
 * Get the sensor value
 */
json_t * b_device_get_sensor (json_t * device, const char * sensor_name, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command sensor for sensor %s on device %s", sensor_name, json_string_value(json_object_get(device, "name")));
  if (0 == o_strcmp(sensor_name, "se1") || 0 == o_strcmp(sensor_name, "se2")) {
    return json_pack("{sisf}", "result", WEBSERVICE_RESULT_OK, "value", get_sensor_value(sensor_name));
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #8
0
/**
 * Set the switch command
 */
json_t * b_device_set_switch (json_t * device, const char * switch_name, const int command, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command set_switch for switch %s on device %s with the value %d", switch_name, json_string_value(json_object_get(device, "name")), command);
  if (0 == o_strcmp(switch_name, "sw1") || 0 == o_strcmp(switch_name, "sw2")) {
    json_object_set_new(json_object_get((json_t *)device_ptr, "switches"), switch_name, json_integer(command));
    return json_pack("{si}", "result", WEBSERVICE_RESULT_OK);
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #9
0
/**
 * Get the switch value
 */
json_t * b_device_get_switch (json_t * device, const char * switch_name, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command get_switch for switch %s on device %s", switch_name, json_string_value(json_object_get(device, "name")));
  if (0 == o_strcmp(switch_name, "sw1")) {
    return json_pack("{sisi}", "result", WEBSERVICE_RESULT_OK, "value", json_integer_value(json_object_get(json_object_get((json_t *)device_ptr, "switches"), "sw1")));
  } else if (0 == o_strcmp(switch_name, "sw2")) {
    return json_pack("{sisi}", "result", WEBSERVICE_RESULT_OK, "value", json_integer_value(json_object_get(json_object_get((json_t *)device_ptr, "switches"), "sw2")));
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #10
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;
}
Beispiel #11
0
/**
 * Get the heater value
 */
json_t * b_device_get_heater (json_t * device, const char * heater_name, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command get_heater for heater %s on device %s", heater_name, json_string_value(json_object_get(device, "name")));
  if (0 == o_strcmp(heater_name, "he1")) {
    json_t * heater = json_copy(json_object_get(json_object_get((json_t *)device_ptr, "heaters"), heater_name));
    json_object_set_new(heater, "result", json_integer(WEBSERVICE_RESULT_OK));
    return heater;
  } else if (0 == o_strcmp(heater_name, "he2")) {
    json_t * heater = json_copy(json_object_get(json_object_get((json_t *)device_ptr, "heaters"), heater_name));
    json_object_set_new(heater, "result", json_integer(WEBSERVICE_RESULT_OK));
    return heater;
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #12
0
/**
 * Set the dimmer command
 */
json_t * b_device_set_dimmer (json_t * device, const char * dimmer_name, const int command, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command set_dimmer for dimmer %s on device %s with the value %d", dimmer_name, json_string_value(json_object_get(device, "name")), command);
  if (0 == o_strcmp(dimmer_name, "di1") || 0 == o_strcmp(dimmer_name, "di2")) {
    if (command < 101) {
      json_object_set_new(json_object_get((json_t *)device_ptr, "dimmers"), dimmer_name, json_integer(command));
      if (command > 0) {
        json_object_set_new(json_object_get((json_t *)device_ptr, "dimmers_values"), dimmer_name, json_integer(command));
      }
    } else {
      json_object_set_new(json_object_get((json_t *)device_ptr, "dimmers"), dimmer_name, json_copy(json_object_get(json_object_get((json_t *)device_ptr, "dimmers_values"), dimmer_name)));
    }
    return json_pack("{sisI}", "result", WEBSERVICE_RESULT_OK, "value", json_integer_value(json_object_get(json_object_get((json_t *)device_ptr, "dimmers"), dimmer_name)));
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #13
0
/**
 * ulfius_write_body
 * Internal function used to write the body response into a _body structure
 */
size_t ulfius_write_body(void * contents, size_t size, size_t nmemb, void * user_data) {
  size_t realsize = size * nmemb;
  body * body_data = (body *) user_data;
 
  body_data->data = realloc(body_data->data, body_data->size + realsize + 1);
  if(body_data->data == NULL) {
    y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for body_data->data");
    return 0;
  }
 
  memcpy(&(body_data->data[body_data->size]), contents, realsize);
  body_data->size += realsize;
  body_data->data[body_data->size] = 0;
 
  return realsize;
}
Beispiel #14
0
/**
 * Set the heater command
 */
json_t * b_device_set_heater (json_t * device, const char * heater_name, const char * mode, const float command, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command set_heater for heater %s on device %s with the value %f and the mode %s", heater_name, json_string_value(json_object_get(device, "name")), command, mode);
  if (0 == o_strcmp(heater_name, "he1") || 0 == o_strcmp(heater_name, "he2")) {
    json_t * heater = json_object_get(json_object_get((json_t *)device_ptr, "heaters"), heater_name);
    if (mode != NULL && 0 == o_strcmp(mode, BENOIC_ELEMENT_HEATER_MODE_MANUAL)) {
      json_object_set_new(heater, "mode", json_string(BENOIC_ELEMENT_HEATER_MODE_MANUAL));
    } else if (mode != NULL && 0 == o_strcmp(mode,  BENOIC_ELEMENT_HEATER_MODE_AUTO)) {
      json_object_set_new(heater, "mode", json_string(BENOIC_ELEMENT_HEATER_MODE_AUTO));
    } else if (mode != NULL && 0 == o_strcmp(mode, BENOIC_ELEMENT_HEATER_MODE_OFF)) {
      json_object_set_new(heater, "mode", json_string(BENOIC_ELEMENT_HEATER_MODE_OFF));
    } else if (mode != NULL) {
      return json_pack("{si}", "result", WEBSERVICE_RESULT_PARAM);
    }
    json_object_set_new(heater, "command", json_real(command));
    return json_pack("{si}", "result", WEBSERVICE_RESULT_OK);
  } else {
    return json_pack("{si}", "result", WEBSERVICE_RESULT_NOT_FOUND);
  }
}
Beispiel #15
0
/**
 * Return true if an element with the specified name and the specified type exist in this device
 */
int b_device_has_element (json_t * device, int element_type, const char * element_name, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Checking if element '%s' of type %d exists in device %s", element_name, element_type, json_string_value(json_object_get(device, "name")));
  switch (element_type) {
    case ELEMENT_TYPE_SENSOR:
      return (0 == o_strcmp(element_name, "se1") || 0 == o_strcmp(element_name, "se2"));
      break;
    case ELEMENT_TYPE_SWITCH:
      return (0 == o_strcmp(element_name, "sw1") || 0 == o_strcmp(element_name, "sw2"));
      break;
    case ELEMENT_TYPE_DIMMER:
      return (0 == o_strcmp(element_name, "di1") || 0 == o_strcmp(element_name, "di2"));
      break;
    case ELEMENT_TYPE_HEATER:
      return (0 == o_strcmp(element_name, "he1") || 0 == o_strcmp(element_name, "he2"));
      break;
    default:
      return 0;
      break;
  }
}
Beispiel #16
0
/**
 * Get the device overview
 * Returns a mocked overview with 2 sensors, 2 switches, 2 dimmers and 2 heaters
 */
json_t * b_device_overview (json_t * device, void * device_ptr) {
  y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command overview for device %s", json_string_value(json_object_get(device, "name")));
  json_t * sw1 = b_device_get_switch(device, "sw1", device_ptr),
         * sw2 = b_device_get_switch(device, "sw2", device_ptr),
         * di1 = b_device_get_dimmer(device, "di1", device_ptr),
         * di2 = b_device_get_dimmer(device, "di2", device_ptr),
         * he1 = b_device_get_heater(device, "he1", device_ptr),
         * he2 = b_device_get_heater(device, "he2", device_ptr);
  json_object_del(he1, "result");
  json_object_del(he2, "result");
    
  json_t * result = json_pack("{sis{s{sssf}s{sosf}}s{sIsI}s{sIsI}s{soso}}",
                             "result", 
                             WEBSERVICE_RESULT_OK,
                             "sensors", 
                                "se1", 
                                  "unit", "C",
                                  "value", get_sensor_value("se1"), 
                                "se2", 
                                  "trigger", json_true(),
                                  "value", get_sensor_value("se2"),
                             "switches", 
                                "sw1", json_integer_value(json_object_get(sw1, "value")), 
                                "sw2", json_integer_value(json_object_get(sw2, "value")),
                             "dimmers", 
                                "di1", json_integer_value(json_object_get(di1, "value")), 
                                "di2", json_integer_value(json_object_get(di2, "value")),
                             "heaters", 
                               "he1", he1,
                               "he2", he2);
  json_decref(sw1);
  json_decref(sw2);
  json_decref(di1);
  json_decref(di2);
  return result;
}
Beispiel #17
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;
}
Beispiel #18
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;
}
Beispiel #19
0
/**
 * create a new request based on the source elements
 * returned value must be free'd
 */
struct _u_request * ulfius_duplicate_request(const struct _u_request * request) {
  struct _u_request * new_request = NULL;
  if (request != NULL) {
    new_request = malloc(sizeof(struct _u_request));
    if (new_request == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for new_request");
      return NULL;
    }
    if (ulfius_init_request(new_request) == U_OK) {
      new_request->http_verb = nstrdup(request->http_verb);
      new_request->http_url = nstrdup(request->http_url);
      if (new_request->http_verb == NULL || new_request->http_url == NULL) {
        y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for ulfius_duplicate_request");
        ulfius_clean_request_full(new_request);
        return NULL;
      }
      if (request->client_address != NULL) {
        new_request->client_address = malloc(sizeof(struct sockaddr));
        if (new_request->client_address == NULL) {
          y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for new_request->client_address");
          ulfius_clean_request_full(new_request);
          return NULL;
        }
        memcpy(new_request->client_address, request->client_address, sizeof(struct sockaddr));
      }
      u_map_clean_full(new_request->map_url);
      u_map_clean_full(new_request->map_header);
      u_map_clean_full(new_request->map_cookie);
      u_map_clean_full(new_request->map_post_body);
      new_request->map_url = u_map_copy(request->map_url);
      new_request->map_header = u_map_copy(request->map_header);
      new_request->map_cookie = u_map_copy(request->map_cookie);
      new_request->map_post_body = u_map_copy(request->map_post_body);
      new_request->json_body = json_copy(request->json_body);
      new_request->json_has_error = request->json_has_error;
      if ((new_request->map_url == NULL && request->map_url != NULL) || 
          (new_request->map_header == NULL && request->map_header != NULL) || 
          (new_request->map_cookie == NULL && request->map_cookie != NULL) || 
          (new_request->map_post_body == NULL && request->map_post_body != NULL) || 
          (new_request->json_body == NULL && request->json_body != NULL)) {
        ulfius_clean_request_full(new_request);
        return NULL;
      }
      if (request->binary_body != NULL && request->binary_body_length > 0) {
        new_request->binary_body = malloc(request->binary_body_length);
        if (new_request->binary_body == NULL) {
          y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for new_request->binary_body");
          ulfius_clean_request_full(new_request);
          return NULL;
        }
        memcpy(new_request->binary_body, request->binary_body, request->binary_body_length);
      } else {
        new_request->binary_body_length = 0;
        new_request->binary_body = NULL;
      }
      new_request->binary_body_length = request->binary_body_length;
    } else {
      free(new_request);
      new_request = NULL;
    }
  }
  return new_request;
}
Beispiel #20
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;
}
Beispiel #21
0
/**
 * handles signal catch to exit properly when ^C is used for example
 */
void exit_handler(int signal) {
  y_log_message(Y_LOG_LEVEL_INFO, "Gareth caught a stop or kill signal (%d), exiting", signal);
  global_handler_variable = GARETH_STOP;
}
Beispiel #22
0
/**
 * Send an email using libcurl
 * email is plain/text and UTF8 charset
 * host: smtp server host name
 * port: tcp port number (optional, 0 for default)
 * use_tls: true if the connection is tls secured
 * verify_certificate: true if you want to disable the certificate verification on a tls server
 * user: connection user name (optional, NULL: no user name)
 * password: connection password (optional, NULL: no password)
 * from: from address (mandatory)
 * to: to recipient address (mandatory)
 * cc: cc recipient address (optional, NULL: no cc)
 * bcc: bcc recipient address (optional, NULL: no bcc)
 * subject: email subject (mandatory)
 * mail_body: email body (mandatory)
 * return U_OK on success
 */
int ulfius_send_smtp_email(const char * host, 
                            const int port, 
                            const int use_tls, 
                            const int verify_certificate, 
                            const char * user, 
                            const char * password, 
                            const char * from, 
                            const char * to, 
                            const char * cc, 
                            const char * bcc, 
                            const char * subject, 
                            const char * mail_body) {
  CURL * curl_handle;
  CURLcode res = CURLE_OK;
  char * smtp_url;
  int cur_port;
  struct curl_slist * recipients = NULL;
  struct upload_status upload_ctx;
  
  if (host != NULL && from != NULL && to != NULL && mail_body != NULL) {
    
    curl_handle = curl_easy_init();
    if (curl_handle != NULL) {
      if (port == 0 && !use_tls) {
        cur_port = 25;
      } else if (port == 0 && use_tls) {
        cur_port = 587;
      } else {
        cur_port = port;
      }
      smtp_url = msprintf("smtp%s://%s:%d", use_tls?"s":"", host, cur_port);
      if (smtp_url == NULL) {
        y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for smtp_url");
        return U_ERROR_MEMORY;
      }
      curl_easy_setopt(curl_handle, CURLOPT_URL, smtp_url);
      
      if (use_tls) {
        curl_easy_setopt(curl_handle, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
      }
      
      if (use_tls && !verify_certificate) {
        curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
      }
      
      if (user != NULL && password != NULL) {
        curl_easy_setopt(curl_handle, CURLOPT_USERNAME, user);
        curl_easy_setopt(curl_handle, CURLOPT_PASSWORD, password);
      }
      
      curl_easy_setopt(curl_handle, CURLOPT_MAIL_FROM, from);
      
      recipients = curl_slist_append(recipients, to);
      if (cc != NULL) {
        recipients = curl_slist_append(recipients, cc);
      }
      if (bcc != NULL) {
        recipients = curl_slist_append(recipients, bcc);
      }
      curl_easy_setopt(curl_handle, CURLOPT_MAIL_RCPT, recipients);
      
      upload_ctx.lines_read = 0;
      upload_ctx.to = (char*)to;
      upload_ctx.from = (char*)from;
      upload_ctx.cc = (char*)cc;
      upload_ctx.subject = (char*)subject;
      upload_ctx.data = (char*)mail_body;
      curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, smtp_payload_source);
      curl_easy_setopt(curl_handle, CURLOPT_READDATA, &upload_ctx);
      curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1L);
      
      res = curl_easy_perform(curl_handle);
      curl_slist_free_all(recipients);
      curl_easy_cleanup(curl_handle);
      free(smtp_url);
      
      if (res != CURLE_OK) {
        y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error sending smtp message, libcurl error: %d, error message %s", res, curl_easy_strerror(res));
        return U_ERROR_LIBCURL;
      } else {
        return U_OK;
      }
    } else {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error executing curl_easy_init");
      return U_ERROR_LIBCURL;
    }
  } else {
    return U_ERROR_PARAMS;
  }
}
Beispiel #23
0
/**
 * Main function
 * Gareth application entry point
 * Initialise the database connection
 * Starts the webservice
 * Infinite loop until an end signal is triggered
 */
int main(int argc, char ** argv) {
  struct config_elements * config = malloc(sizeof(struct config_elements));
  if (config == NULL) {
    fprintf(stderr, "Memory error - config\n");
    return 1;
  }
  
  config->config_file = NULL;
  config->url_prefix = NULL;
  config->log_mode = Y_LOG_MODE_NONE;
  config->log_level = Y_LOG_LEVEL_NONE;
  config->log_file = NULL;
  config->conn = NULL;
  config->instance = malloc(sizeof(struct _u_instance));
  if (config->instance == NULL) {
    fprintf(stderr, "Memory error - config->instance\n");
    return 1;
  }
  ulfius_init_instance(config->instance, 1, NULL, NULL);

  global_handler_variable = GARETH_RUNNING;
  // Catch end signals to make a clean exit
  signal (SIGQUIT, exit_handler);
  signal (SIGINT, exit_handler);
  signal (SIGTERM, exit_handler);
  signal (SIGHUP, exit_handler);

  // First we parse command line arguments
  if (!build_config_from_args(argc, argv, config)) {
    fprintf(stderr, "Error reading command-line parameters\n");
    print_help(stderr);
    exit_server(&config, GARETH_ERROR);
  }
  
  // Then we parse configuration file
  // They have lower priority than command line parameters
  if (!build_config_from_file(config)) {
    fprintf(stderr, "Error config file\n");
    exit_server(&config, GARETH_ERROR);
  }
  
  // Check if all mandatory configuration variables are present and correctly typed
  if (!check_config(config)) {
    fprintf(stderr, "Error initializing configuration\n");
    exit_server(&config, GARETH_ERROR);
  }
  
  // Initialize gareth webservice
  if (!init_gareth(config->instance, config->url_prefix, config->conn)) {
    fprintf(stderr, "Error initializing gareth webservice\n");
    exit_server(&config, GARETH_ERROR);
  }
  
  // Default endpoint
  ulfius_set_default_endpoint(config->instance, &callback_default, (void*)config->conn);
    
  // Start the webservice
  y_log_message(Y_LOG_LEVEL_INFO, "Start gareth on port %d, prefix: %s", config->instance->port, config->url_prefix);
  if (ulfius_start_framework(config->instance) == U_OK) {
    while (global_handler_variable == GARETH_RUNNING) {
      sleep(1);
    }
  } else {
    y_log_message(Y_LOG_LEVEL_ERROR, "Error starting gareth webserver");
    exit_server(&config, GARETH_ERROR);
  }
  exit_server(&config, GARETH_STOP);
  return 0;
}
Beispiel #24
0
static size_t smtp_payload_source(void * ptr, size_t size, size_t nmemb, void * userp) {
  struct upload_status *upload_ctx = (struct upload_status *)userp;
  char * data = NULL;
  size_t len = 0;

  if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
    return 0;
  }

  if (upload_ctx->lines_read == MAIL_DATE) {
    time_t now;
    time(&now);
    data = malloc(128*sizeof(char));
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_DATE\n");
      return 0;
    } else {
      strftime(data, 128, "Date: %a, %d %b %Y %T %z\r\n", gmtime(&now));
      len = strlen(data);
    }
  } else if (upload_ctx->lines_read == MAIL_TO) {
    data = msprintf("To: %s\r\n", upload_ctx->to);
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_TO\n");
      return 0;
    }
    len = strlen(data);
  } else if (upload_ctx->lines_read == MAIL_FROM) {
    data = msprintf("From: %s\r\n", upload_ctx->from);
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_FROM\n");
      return 0;
    }
    len = strlen(data);
  } else if (upload_ctx->lines_read == MAIL_CC && upload_ctx->cc) {
    data = msprintf("Cc: %s\r\n", upload_ctx->cc);
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_CC\n");
      return 0;
    }
    len = strlen(data);
  } else if (upload_ctx->lines_read == MAIL_SUBJECT) {
    data = msprintf("Subject: %s\r\n", upload_ctx->subject);
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_SUBJECT\n");
      return 0;
    }
    len = strlen(data);
  } else if (upload_ctx->lines_read == MAIL_DATA) {
    data = msprintf("Content-Type: text/plain; charset=utf-8\r\n\r\n%s\r\n", upload_ctx->data);
    if (data == NULL) {
      y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for MAIL_DATA\n");
      return 0;
    }
    len = strlen(data);
  }

  if (upload_ctx->lines_read != MAIL_END) {
    memcpy(ptr, data, (len+1));
    upload_ctx->lines_read++;
    
    // Skip next if it's cc and there is no cc
    if (upload_ctx->lines_read == MAIL_CC && !upload_ctx->cc) {
      upload_ctx->lines_read++;
    }
    free(data);
 
    return len;
  } else if (upload_ctx->lines_read == MAIL_END) {
    return 0;
  }

  y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting mail payload, len is %d, lines_read is %d", len, upload_ctx->lines_read);
  return 0;
}