/**
* @internal
+ * @brief Enumeration for transfer pause state
+ * @since_tizen 3.0
+ */
+typedef enum {
+ HTTP_PAUSE_RECV = 1 << 0, /**< Pause receiving data */
+ HTTP_PAUSE_SEND = 1 << 2, /**< Pause sending data */
+ HTTP_PAUSE_ALL = HTTP_PAUSE_RECV | HTTP_PAUSE_SEND /**< %Pause both directions */
+} http_pause_state_e;
+
+/**
+ * @internal
* @brief Enumeration for the http error code.
* @since_tizen 3.0
*/
* @param[in] header header information of Http Transaction
* @param[in] header_len length of the Http Transaction header
*/
-typedef void (*http_transaction_header_cb)(char *header, size_t header_len);
+typedef void (*http_transaction_header_cb)(http_transaction_h transaction, char *header, size_t header_len, void *user_data);
/**
* @internal
* @param[in] size Size in bytes of each element to be written
* @param[in] count Number of elements, each one with a size of size bytes
*/
-typedef void (*http_transaction_body_cb)(char *body, size_t size, size_t count);
+typedef void (*http_transaction_body_cb)(http_transaction_h transaction, char *body, size_t size, size_t count, void *user_data);
/**
* @internal
* @details Called when the http ready to write event is received.
* @param[in] recommended_chunk_size recommended chunk length of the Http transaction
*/
-typedef void (*http_transaction_write_cb)(int recommended_chunk_size);
+typedef void (*http_transaction_write_cb)(http_transaction_h transaction, int recommended_chunk_size, void *user_data);
/**
* @internal
* @since_tizen 3.0
* @details Called when the http transaction is completed.
*/
-typedef void (*http_transaction_completed_cb)(void);
+typedef void (*http_transaction_completed_cb)(http_transaction_h transaction, void *user_data);
/**
* @internal
* @details Called when the http transaction is aborted.
* @param[in] reason aborted reason code
*/
-typedef void (*http_transaction_aborted_cb)(int reason);
+typedef void (*http_transaction_aborted_cb)(http_transaction_h transaction, int reason);
/**
* @internal
* @retval #HTTP_ERROR_NONE Successful
* @retval #HTTP_ERROR_INVALID_PARAMETER Invalid parameter
*/
-int http_open_transaction(http_session_h http_session, http_method_e method, http_transaction_header_cb transaction_header_callback,
- http_transaction_body_cb transaction_body_callback, http_transaction_write_cb transaction_write_callback,
- http_transaction_completed_cb transaction_completed_cb, http_transaction_aborted_cb transaction_aborted_cb, http_transaction_h *http_transaction);
+int http_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction);
/**
* @internal
*/
int http_transaction_close(http_transaction_h http_transaction);
+int http_transaction_set_received_header_cb(http_transaction_h transaction, http_transaction_header_cb header_cb, void* user_data);
+
+int http_transaction_set_received_body_cb(http_transaction_h transaction, http_transaction_body_cb body_cb, void* user_data);
+
+int http_transaction_set_uploaded_cb(http_transaction_h transaction, http_transaction_write_cb write_cb, void* user_data);
+
+int http_transaction_set_completed_cb(http_transaction_h transaction, http_transaction_completed_cb completed_cb, void* user_data);
+
+int http_transaction_close_all(http_session_h session);
+
+
/**
* @internal
* @brief Sets the progress callbacks.
* @retval #HTTP_ERROR_NONE Successful
* @retval #HTTP_ERROR_INVALID_PARAMETER Invalid parameter
*/
-int http_transaction_pause(http_transaction_h http_transaction);
+int http_transaction_pause(http_transaction_h http_transaction, http_pause_state_e pause_state);
/**
* @internal
/**
* @internal
+ * @brief Sets the flag to verify a server certificate.
+ * @since_tizen 3.0
+ * @privlevel platform
+ * @privilege http://tizen.org/privilege/http.admin
+ * @details Get the interface name.
+ * @param[in] http_transaction The http transaction handle
+ * @param[in] verify flag to verify a server certificate.
+ * @return 0 on success, otherwise negative error value
+ * @retval #HTTP_ERROR_NONE Successful
+ * @retval #HTTP_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int http_transaction_set_server_certificate_verification(http_transaction_h http_transaction, bool verify);
+
+/**
+ * @internal
+ * @brief Gets the flag to verify a server certificate.
+ * @since_tizen 3.0
+ * @privlevel platform
+ * @privilege http://tizen.org/privilege/http.admin
+ * @details Get the interface name.
+ * @param[in] http_transaction The http transaction handle
+ * @param[out] verify flag to verify a server certificate.
+ * @return 0 on success, otherwise negative error value
+ * @retval #HTTP_ERROR_NONE Successful
+ * @retval #HTTP_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int http_transaction_get_server_certificate_verification(http_transaction_h http_transaction, bool* verify);
+
+/**
+ * @internal
* @brief Adds a named field, which is a <@c fieldName, @c fieldValue> pair, to the current instance of Http Transaction.
* @since_tizen 3.0
* @privlevel platform
} \
} while (0)
+#define HTTP_PREFIX_SIZE 5
+#define HTTP_VERSION_SIZE 3
+#define HTTP_STATUS_CODE_SIZE 3
+#define HTTP_REASON_PHRASE_SIZE 1024
+
+#define HTTP_DEFAULT_CA_PATH "/etc/ssl/certs"
+
static const int _HTTP_DEFAULT_CONNECTION_TIMEOUT = 30;
static const int _HTTP_DEFAULT_HEADER_SIZE = 1024;
static const int _MAX_HTTP_TRANSACTIONS_PER_SESSION_NORMAL = 1;
gchar *host_uri;
gchar *method;
gchar *encoding;
+ gchar *cookie;
GQueue* body_queue;
gint tot_size;
http_version_e http_version;
typedef struct {
gchar *status_text;
http_status_code_e status_code;
+ http_version_e version;
} __http_response_h;
typedef struct {
CURLM *multi_handle;
+ int session_id;
guint timer_event;
int still_running;
int active_transaction_count;
typedef struct {
CURL *easy_handle;
+ int session_id;
+ int transaction_id;
gchar *interface_name;
int timeout;
int write_event;
+ bool verify_peer;
+ gchar *ca_path;
gchar error[CURL_ERROR_SIZE];
int socket_fd;
- /*Transaction Callbacks */
+ /*Transaction Callbacks and User data*/
http_transaction_header_cb header_cb;
+ void *header_user_data;
http_transaction_body_cb body_cb;
+ void *body_user_data;
http_transaction_write_cb write_cb;
+ void *write_user_data;
http_transaction_completed_cb completed_cb;
+ void *completed_user_data;
http_transaction_aborted_cb aborted_cb;
+
/*Progress Callbacks */
http_transaction_upload_progress_cb upload_progress_cb;
http_transaction_download_progress_cb download_progress_cb;
int _get_request_body_size(http_transaction_h http_transaction, int *body_size);
int _read_request_body(http_transaction_h http_transaction, char **body);
+void __parse_response_header(char *buffer, size_t written, gpointer user_data);
+int _generate_session_id(void);
+int _generate_transaction_id(void);
+void _add_transaction_to_list(http_transaction_h http_transaction);
+void _remove_transaction_from_list(http_transaction_h http_transaction);
+void _remove_transaction_list(void);
#ifdef __cplusplus
}
Name: capi-network-http
Summary: Http Framework
-Version: 0.0.2
+Version: 0.0.3
Release: 0
Group: System/Network
License: Apache-2.0
return proxy_addr;
}
+
+API int http_init()
+{
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ DBG("curl_global_init failed, so returning!\n");
+ return HTTP_ERROR_OPERATION_FAILED;
+ }
+
+ return HTTP_ERROR_NONE;
+}
+
+API void http_deinit()
+{
+ curl_global_cleanup();
+}
g_hash_table_iter_init(&iter, header->hash_table);
- while(g_hash_table_iter_next (&iter, &key, &value)) {
- header_str = (gchar *)malloc(sizeof(gchar) * (strlen(key) + 1 + 1 + strlen(value) + 1) );
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ header_str = (gchar *)malloc(sizeof(gchar) * (strlen(key) + 1 + 1 + strlen(value) + 1));
sprintf(header_str, "%s: %s", (gchar*)key, (gchar*)value);
DBG("Header Field: %s\n", header_str);
header->header_list = curl_slist_append(header->header_list, header_str);
ERR("strdup is failed\n");
return HTTP_ERROR_OUT_OF_MEMORY;
}
+ DBG("-");
return HTTP_ERROR_NONE;
}
return HTTP_ERROR_NONE;
}
+API int http_request_set_cookie(http_transaction_h http_transaction, const char* cookie)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(cookie == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(cookie) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+ __http_request_h *request = transaction->request;
+
+ request->cookie = g_strdup(cookie);
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_request_get_cookie(http_transaction_h http_transaction, const char** cookie)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(cookie == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(cookie) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+ __http_request_h *request = transaction->request;
+
+ *cookie = g_strdup(request->cookie);
+ if (*cookie == NULL) {
+ ERR("strdup is failed\n");
+ return HTTP_ERROR_OUT_OF_MEMORY;
+ }
+
+ return HTTP_ERROR_NONE;
+}
+
API int http_request_write_body(http_transaction_h http_transaction, const char *body)
{
_retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
* limitations under the License.
*/
+#include <math.h>
+
#include "http.h"
#include "http_private.h"
+static int __convert_status_code(char* status_code)
+{
+ int i = 0;
+ int converted_digit = 0;
+ int converted_status_code = 0;
+
+ for (i = HTTP_STATUS_CODE_SIZE - 1; i >= 0; i--) {
+ converted_digit = g_ascii_digit_value(status_code[i]);
+ converted_status_code += converted_digit * pow(10, HTTP_STATUS_CODE_SIZE - i - 1);
+ }
+
+ return converted_status_code;
+}
+
+void __parse_response_header(char* buffer, size_t written, gpointer user_data)
+{
+ __http_transaction_h* transaction = (__http_transaction_h *)user_data;
+ __http_response_h*response = (__http_response_h *)transaction->response;
+
+ char status_code[HTTP_STATUS_CODE_SIZE] = {0, };
+ //char reason_phrase[HTTP_REASON_PHRASE_SIZE] = {0, };
+ char* start = NULL;
+ char* end = NULL;
+
+ if (strncmp(buffer, "HTTP/", HTTP_PREFIX_SIZE) == 0) {
+ if (strncmp(buffer + HTTP_PREFIX_SIZE, "1.0", HTTP_VERSION_SIZE) == 0)
+ response->version = HTTP_VERSION_1_0;
+ else if (strncmp(buffer + HTTP_PREFIX_SIZE, "1.1", HTTP_VERSION_SIZE) == 0)
+ response->version = HTTP_VERSION_1_1;
+
+ start = buffer + HTTP_PREFIX_SIZE + HTTP_VERSION_SIZE + 1;
+ strncpy(status_code, start, HTTP_STATUS_CODE_SIZE);
+
+ start += HTTP_STATUS_CODE_SIZE + 1;
+ end = start + strcspn(start, "\n");
+
+ while (end > start && (end[-1] == '\r' || end[-1] == ' ' || end[-1] == '\t'))
+ end--;
+
+ response->status_code = __convert_status_code(status_code);
+ response->status_text = g_strndup(start, end - start);
+
+ DBG("[Seonah] reason_pharse: %s", response->status_text);
+ }
+}
+
+API int http_response_get_status_code(http_transaction_h http_transaction, http_status_code_e* status_code)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(status_code == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(status_code) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+ __http_response_h* response = (__http_response_h *)transaction->response;
+
+ *status_code = response->status_code;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_response_get_status_text(http_transaction_h http_transaction, char** status_text)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(status_text == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(status_text) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+ __http_response_h* response = (__http_response_h *)transaction->response;
+
+ *status_text = g_strdup(response->status_text);
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_response_get_version(http_transaction_h http_transaction, http_version_e* version)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(version == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(version) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+ __http_response_h* response = (__http_response_h *)transaction->response;
+
+ *version = response->version;
+
+ return HTTP_ERROR_NONE;
+}
DBG("Completed -%s: result(%d)\n", url, curl_code);
if (curl_code == CURLE_OK) {
- transaction->completed_cb();
+ transaction->completed_cb(transaction, transaction->completed_user_data);
} else {
}
}
}
+int _generate_session_id(void)
+{
+ int session_id = 0;
+
+ return session_id;
+}
+
gboolean timer_expired_callback(gpointer user_data)
{
__http_session_h* session = (__http_session_h *)user_data;
ret = curl_multi_socket_action(session->multi_handle, fd, action, &running_handles);
if (ret == CURLM_OK) {
//DBG("CURLM_OK: Called curl_multi_socket_action(%d)\n", action);
- }
- else {
+ } else {
print_curl_multi_errorCode(ret);
}
static void _set_socket_info(__http_socket_info_h *sock_info, curl_socket_t fd, CURL *curl_easy, int action, void *user_data)
{
__http_session_h *session = (__http_session_h *)user_data;
- GIOCondition condition = (action & CURL_POLL_IN ? G_IO_IN : 0) | (action & CURL_POLL_OUT ? G_IO_OUT: 0);
+ GIOCondition condition = (action & CURL_POLL_IN ? G_IO_IN : 0) | (action & CURL_POLL_OUT ? G_IO_OUT : 0);
sock_info->sockfd = fd;
sock_info->action = action;
__http_session_h *session = (__http_session_h *)user_data;
__http_socket_info_h *sock_info = (__http_socket_info_h*) socketp;
- static const char *actionstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
+ static const char *actionstr[] = { "none", "IN", "OUT", "INOUT", "REMOVE"};
DBG("__handle_socket_cb: fd=%d easy_handle=%p action=%s ", fd, curl_easy, actionstr[action]);
if (action == CURL_POLL_REMOVE) {
_remove_socket_info(sock_info);
} else {
if (!sock_info) {
- DBG("Adding data: %s%s\n", action & CURL_POLL_IN ? "READ":"", action & CURL_POLL_OUT ? "WRITE":"" );
+ DBG("Adding data: %s%s\n", action & CURL_POLL_IN ? "READ" : "", action & CURL_POLL_OUT ? "WRITE" : "");
_add_socket_info(fd, curl_easy, action, session);
- }
- else {
+ } else {
DBG("Changing action from %d to %d\n", sock_info->action, action);
_set_socket_info(sock_info, fd, curl_easy, action, session);
}
return 0;
}
-API int http_init()
-{
- if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
- DBG("curl_global_init failed, so returning!\n");
- return HTTP_ERROR_OPERATION_FAILED;
- }
-
- return HTTP_ERROR_NONE;
-}
-
-API void http_deinit()
-{
- curl_global_cleanup();
-}
-
API int http_create_session(http_session_h *http_session, http_session_mode_e mode)
{
_retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER,
session = (__http_session_h *)malloc(sizeof(__http_session_h));
session->multi_handle = curl_multi_init();
+ session->session_id = _generate_session_id();
session->active_transaction_count = 0;
session->session_mode = mode;
session->auto_redirect = FALSE;
#include "http.h"
#include "http_private.h"
+static __thread GSList *transaction_list = NULL;
+
+void _add_transaction_to_list(http_transaction_h http_transaction)
+{
+ transaction_list = g_slist_append(transaction_list, http_transaction);
+}
+
+void _remove_transaction_from_list(http_transaction_h http_transaction)
+{
+ transaction_list = g_slist_remove(transaction_list, http_transaction);
+ //g_free(http_transaction);
+}
+
+void _remove_transaction_list(void)
+{
+ g_slist_free_full(transaction_list, g_free);
+ transaction_list = NULL;
+}
+
+int _generate_transaction_id(void)
+{
+ int transaction_id = 0;
+
+ return transaction_id;
+}
+
curl_socket_t __handle_opensocket_cb(void *client_fd, curlsocktype purpose, struct curl_sockaddr *address)
{
int fd = socket(address->family, address->socktype, address->protocol);
__http_transaction_h *transaction = (__http_transaction_h *)user_data;
size_t written = size * nmemb;
- transaction->header_cb(buffer, written);
+ __parse_response_header(buffer, written, user_data);
+ transaction->header_cb(transaction, buffer, written, transaction->header_user_data);
return written;
}
__http_transaction_h *transaction = (__http_transaction_h *)user_data;
size_t written = size * nmemb;
- transaction->body_cb(ptr, size, nmemb);
+ transaction->body_cb(transaction, ptr, size, nmemb, transaction->body_user_data);
return written;
}
size_t recommended_size = size * nmemb;
size_t body_size = 0;
- transaction->write_cb(recommended_size);
+ transaction->write_cb(transaction, recommended_size, transaction->write_user_data);
ptr = (gchar*)g_queue_pop_head(request->body_queue);
if (ptr == NULL) {
char log_buffer[_HTTP_DEFAULT_HEADER_SIZE];
int log_size = 0;
- if (_HTTP_DEFAULT_HEADER_SIZE > size) {
+ if (_HTTP_DEFAULT_HEADER_SIZE > size)
log_size = size;
- }
- else {
+ else
log_size = _HTTP_DEFAULT_HEADER_SIZE - 1;
- }
if (type == CURLINFO_TEXT) {
strncpy(log_buffer, byte, log_size);
log_buffer[log_size] = '\0';
DBG("[DEBUG] %s", log_buffer);
- }
- else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT) {
- //Ignore the body message.
+ } else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT) {
+ /* Ignore the body message. */
if (size >= 2 && byte[0] == 0x0D && byte[1] == 0x0A) {
return 0;
- }
- else {
+ } else {
strncpy(log_buffer, byte, log_size);
log_buffer[log_size] = '\0';
DBG("[DEBUG] %s", log_buffer);
transaction->easy_handle = curl_easy_init();
- if (request->http_version == HTTP_VERSION_1_0) {
+ if (request->http_version == HTTP_VERSION_1_0)
curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- } else {
+ else
curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- }
if (request->host_uri)
curl_easy_setopt(transaction->easy_handle, CURLOPT_URL, request->host_uri);
if (request->encoding)
curl_easy_setopt(transaction->easy_handle, CURLOPT_ENCODING, request->encoding);
+ if (request->cookie)
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_COOKIE, request->cookie);
+
//The connection timeout is 30s. (default)
curl_easy_setopt(transaction->easy_handle, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_TIME, 30L);
}
+ if (!transaction->verify_peer) {
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 0);
+
+ } else {
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_CAPATH, transaction->ca_path);
+ DBG("CA path is (%s)", transaction->ca_path);
+
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_CIPHER_LIST, "HIGH");
+ }
+
if (session->auto_redirect) {
curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
if (content_len > 0) {
curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
DBG("Set the Content-Length(%d).", content_len);
- }
- else if (content_len == 0) {
+ } else if (content_len == 0) {
curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, NULL);
DBG("Set the Content-Length(%d).", content_len);
_get_request_body_size(transaction, &body_size);
if (transaction->write_event) {
- if (content_len >= 0 && content_len <= body_size) {
+ if (content_len >= 0 && content_len <= body_size)
write_event = FALSE;
- }
- else {
+ else
write_event = TRUE;
- }
DBG("The write_event is %d.\n", write_event);
}
return NULL;
}
-API int http_open_transaction(http_session_h http_session, http_method_e method, http_transaction_header_cb transaction_header_callback,
- http_transaction_body_cb transaction_body_callback, http_transaction_write_cb transaction_write_callback,
- http_transaction_completed_cb transaction_completed_cb, http_transaction_aborted_cb transaction_aborted_cb, http_transaction_h *http_transaction)
+API int http_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction)
{
_retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER,
"parameter(http_session) is NULL\n");
- _retvm_if(transaction_header_callback == NULL, HTTP_ERROR_INVALID_PARAMETER,
- "parameter(transaction_header_callback) is NULL\n");
- _retvm_if(transaction_body_callback == NULL, HTTP_ERROR_INVALID_PARAMETER,
- "parameter(transaction_body_callback) is NULL\n");
- _retvm_if(transaction_write_callback == NULL, HTTP_ERROR_INVALID_PARAMETER,
- "parameter(transaction_write_callback) is NULL\n");
- _retvm_if(transaction_completed_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
- "parameter(transaction_completed_cb) is NULL\n");
- _retvm_if(transaction_aborted_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
- "parameter(transaction_aborted_cb) is NULL\n");
__http_transaction_h *transaction = NULL;
- transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
+ DBG("[Seonah] + ");
+ transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
transaction->easy_handle = NULL;
transaction->interface_name = NULL;
transaction->timeout = 0;
+ transaction->verify_peer = 1;
+ transaction->ca_path = g_strdup(HTTP_DEFAULT_CA_PATH);
transaction->error[0] = '\0';
- transaction->header_cb = transaction_header_callback;
- transaction->body_cb = transaction_body_callback;
- transaction->write_cb = transaction_write_callback;
- transaction->completed_cb = transaction_completed_cb;
- transaction->aborted_cb = transaction_aborted_cb;
+ transaction->header_cb = NULL;
+ transaction->body_cb = NULL;
+ transaction->write_cb = NULL;
+ transaction->completed_cb = NULL;
+ transaction->aborted_cb = NULL;
transaction->upload_progress_cb = NULL;
transaction->download_progress_cb = NULL;
transaction->session = http_session;
transaction->session->active_transaction_count++;
+ transaction->session_id = 0;
transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
transaction->request->host_uri = NULL;
-
transaction->request->method = _get_http_method(method);
-
transaction->request->encoding = NULL;
+ transaction->request->cookie = NULL;
transaction->request->http_version = HTTP_VERSION_1_1;
-
transaction->request->body_queue = g_queue_new();
transaction->header->header_list = NULL;
transaction->thread = NULL;
*http_transaction = (http_transaction_h)transaction;
+ _add_transaction_to_list(transaction);
+ DBG("[Seonah] - ");
return HTTP_ERROR_NONE;
}
response = transaction->response;
header = transaction->header;
- if (session) {
+ if (session)
session->active_transaction_count--;
- }
if (transaction) {
-
g_thread_join(transaction->thread);
transaction->thread = NULL;
}
transaction->timeout = 0;
+ transaction->verify_peer = 0;
+ transaction->ca_path = '\0';
transaction->error[0] = '\0';
transaction->header_cb = NULL;
request->encoding = NULL;
}
- if (request->body_queue != NULL) {
- g_queue_free(request->body_queue);
+ if (request->cookie != NULL) {
+ free(request->cookie);
+ request->cookie = NULL;
}
+ if (request->body_queue != NULL)
+ g_queue_free(request->body_queue);
+
free(request);
}
free(response);
return HTTP_ERROR_NONE;
}
+API int http_transaction_pause(http_transaction_h http_transaction, http_pause_state_e pause_state)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(pause_state < HTTP_PAUSE_RECV || pause_state > HTTP_PAUSE_ALL, HTTP_ERROR_INVALID_PARAMETER,
+ "Wrong pause state \n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ curl_easy_pause(transaction->easy_handle, pause_state);
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_resume(http_transaction_h http_transaction)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ curl_easy_pause(transaction->easy_handle, CURLPAUSE_CONT);
+
+ return HTTP_ERROR_NONE;
+}
+
+
API int http_transaction_set_progress_cb(http_transaction_h http_transaction, http_transaction_upload_progress_cb upload_progress_cb,
http_transaction_download_progress_cb download_progress_cb)
{
return HTTP_ERROR_NONE;
}
+API int http_transaction_set_received_header_cb(http_transaction_h http_transaction, http_transaction_header_cb header_cb, void* user_data)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(header_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(header_cb) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->header_cb = header_cb;
+ transaction->header_user_data = user_data;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_set_received_body_cb(http_transaction_h http_transaction, http_transaction_body_cb body_cb, void* user_data)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(body_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(body_cb) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->body_cb = body_cb;
+ transaction->body_user_data = user_data;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_set_uploaded_cb(http_transaction_h http_transaction, http_transaction_write_cb write_cb, void* user_data)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(write_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(write_cb) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->write_cb = write_cb;
+ transaction->write_user_data = user_data;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_set_completed_cb(http_transaction_h http_transaction, http_transaction_completed_cb completed_cb, void* user_data)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+ _retvm_if(completed_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(completed_cb) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->completed_cb = completed_cb;
+ transaction->completed_user_data = user_data;
+
+ return HTTP_ERROR_NONE;
+}
+
+
+API int http_transaction_unset_progress_cb(http_transaction_h http_transaction)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->upload_progress_cb = NULL;
+ transaction->download_progress_cb = NULL;
+
+ return HTTP_ERROR_NONE;
+}
+
API int http_transaction_set_timeout(http_transaction_h http_transaction, int timeout)
{
_retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
return HTTP_ERROR_NONE;
}
+
+API int http_transaction_get_server_certificate_verification(http_transaction_h http_transaction, bool* verify)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ *verify = transaction->verify_peer;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_set_server_certificate_verification(http_transaction_h http_transaction, bool verify)
+{
+ _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_transaction) is NULL\n");
+
+ __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
+
+ transaction->verify_peer = verify;
+
+ return HTTP_ERROR_NONE;
+}
+
+API int http_transaction_close_all(http_session_h http_session)
+{
+ _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER,
+ "parameter(http_session) is NULL\n");
+
+ GSList *list = NULL;
+ __http_session_h *session = (__http_session_h *)http_session;
+
+ for (list = transaction_list; list; list = list->next) {
+ __http_transaction_h *transaction = (__http_transaction_h *)list->data;
+ if (session->session_id == transaction->session_id) {
+ DBG("[Seonah]Close.. (%p)", list->data);
+ _remove_transaction_from_list(list->data);
+ DBG("[Seonah]Close..1");
+ http_transaction_close((http_transaction_h) transaction);
+ DBG("[Seonah]Close..11");
+ }
+ }
+
+ return HTTP_ERROR_NONE;
+}
+
FILE* fp1 = NULL;
FILE* fp2 = NULL;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////Request 1 Callbacks////////////////////////////////////////////////////////////////////////////
-void transaction_header_cb(char *header, size_t header_len)
-{
- DBG("########################## 1:transaction_header_cb#########################################\n");
-
- if (!fp1)
- fp1 = fopen ("./google.html", "w+");
+http_session_h session_handle = NULL;
+http_transaction_h transaction_handle1 = NULL;
+http_transaction_h transaction_handle2 = NULL;
+int count = 0;
-}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void transaction_body_cb(char *body, size_t size, size_t nmemb)
+int add_http_header(http_transaction_h transaction_handle)
{
- DBG("########################## 1:transaction_body_cb#########################################\n");
- //DBG("Body:%s\n", body);
- int written = size * nmemb;
+ http_header_add_field(transaction_handle, "Connection", "close");
+ //http_header_add_field(transaction_handle, "Accept-Charset", "ISO-8859-1,UTF-8;q=0.7,*;q=0.7");
+ //http_header_add_field(transaction_handle, "Cache-Control", "no-cache");
+ //http_header_add_field(transaction_handle, "Accept-Language", "en-us;q=0.3");
- if (written) {
- fwrite(body, size, nmemb, fp1);
- }
+ return 0;
}
-void transaction_write_cb(int recommended_chunk_size)
+int remove_http_header(http_transaction_h transaction_handle)
{
- DBG("########################## 1:transaction_write_cb#########################################\n");
+ http_header_remove_field(transaction_handle, "Connection");
+ //http_header_remove_field(transaction_handle, "Accept-Charset");
+ //http_header_remove_field(transaction_handle, "Cache-Control");
+ //http_header_remove_field(transaction_handle, "Accept-Language");
- DBG("recommended_chunk_size:%d\n", recommended_chunk_size);
+ return 0;
}
-void transaction_completed_cb(void)
+void print_response_header(http_transaction_h transaction_handle)
{
- DBG("########################## 1:transaction_completed_cb#########################################\n");
+ char* uri = NULL;
+ char* status_text = NULL;
+ http_status_code_e status_code;
+ http_version_e version;
- fclose(fp1);
+ DBG("########################## Result #########################################\n");
- //g_main_loop_quit((GMainLoop*)mainloop);
-}
-
-void transaction_aborted_cb(int reason)
-{
- DBG("########################## 1:transaction_aborted_cb#########################################\n");
+ http_request_get_uri(transaction_handle, &uri);
+ http_response_get_version(transaction_handle, &version);
+ http_response_get_status_code(transaction_handle, &status_code);
+ http_response_get_status_text(transaction_handle, &status_text);
+ DBG("URI(%s) HTTP version (%d) Status Code (%d) Status message (%s)\n", uri, version, status_code, status_text);
}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////Request 2 Callbacks////////////////////////////////////////////////////////////////////////////
-void transaction_header_callback(char *header, size_t header_len)
+/////////////////Callbacks////////////////////////////////////////////////////////////////////////////
+void transaction_header_cb(http_transaction_h transaction_handle, char *header, size_t header_len, void *user_data)
{
- DBG("########################## 2: transaction_header_callback#########################################\n");
-
- if (!fp2)
- fp2 = fopen ("./ibnlive.html", "w+");
+ DBG("########################## transaction_header_cb#########################################\n");
}
-void transaction_body_callback(char *body, size_t size, size_t nmemb)
+void transaction_body_cb(http_transaction_h transaction_handle, char *body, size_t size, size_t nmemb, void *user_data)
{
- DBG("########################## 2: transaction_body_callback#########################################\n");
- //DBG("Body:%s\n", body);
+ DBG("########################## transaction_body_cb#########################################\n");
int written = size * nmemb;
-
- if (written) {
- fwrite(body, size, nmemb, fp2);
- }
+ DBG("Received: %d\n", written);
+ //if (written) {
+ //fwrite(body, size, nmemb, fp1);
+ //}
}
-void transaction_write_callback(int recommended_chunk_size)
+void transaction_write_cb(http_transaction_h transaction_handle, int recommended_chunk_size, void *user_data)
{
- DBG("########################## 2:transaction_write_callback#########################################\n");
+ DBG("########################## transaction_write_cb#########################################\n");
DBG("recommended_chunk_size:%d\n", recommended_chunk_size);
}
-void transaction_completed_callback(void)
-{
- DBG("########################## 2:transaction_completed_callback #########################################\n");
-
- fclose(fp2);
-
- g_main_loop_quit((GMainLoop*)mainloop);
-}
-
-void transaction_aborted_callback(int reason)
+void transaction_completed_cb(http_transaction_h transaction_handle, void *user_data)
{
- DBG("########################## 2:transaction_aborted_callback#########################################\n");
+ DBG("########################## transaction_completed_cb#########################################\n");
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ char *uri = NULL;
-int add_http_header(http_transaction_h transaction_handle)
-{
- http_header_add_field(transaction_handle, "Connection", "close");
- http_header_add_field(transaction_handle, "Accept-Charset", "ISO-8859-1,UTF-8;q=0.7,*;q=0.7");
- http_header_add_field(transaction_handle, "Cache-Control", "no-cache");
- http_header_add_field(transaction_handle, "Accept-Language", "en-us;q=0.3");
+ http_request_get_uri(transaction_handle, &uri);
+ DBG("Completed uri: %s\n", uri);
+ print_response_header(transaction_handle);
+ count--;
- return 0;
+ if (count == 0)
+ g_main_loop_quit((GMainLoop*)mainloop);
}
-int remove_http_header(http_transaction_h transaction_handle)
+void transaction_aborted_cb(int reason)
{
- http_header_remove_field(transaction_handle, "Connection");
- http_header_remove_field(transaction_handle, "Accept-Charset");
- http_header_remove_field(transaction_handle, "Cache-Control");
- http_header_remove_field(transaction_handle, "Accept-Language");
+ DBG("########################## transaction_aborted_cb#########################################\n");
- return 0;
}
-http_transaction_h create_http_request(http_session_h session_handle, gchar* host_url, http_transaction_header_cb header_cb, http_transaction_body_cb body_cb, http_transaction_write_cb write_cb,
- http_transaction_completed_cb completed_cb, http_transaction_aborted_cb aborted_cb)
+http_transaction_h create_http_request(http_session_h session_handle, gchar* host_url)
{
http_transaction_h transaction_handle = NULL;
- http_session_set_auto_redirection(session_handle, TRUE);
+ //http_session_set_auto_redirection(session_handle, TRUE);
- http_open_transaction(session_handle, HTTP_METHOD_GET, (http_transaction_header_cb)header_cb,
- (http_transaction_body_cb)body_cb, (http_transaction_write_cb)write_cb, (http_transaction_completed_cb)completed_cb,
- (http_transaction_aborted_cb)aborted_cb, &transaction_handle);
+ http_open_transaction(session_handle, HTTP_METHOD_GET, &transaction_handle);
http_request_set_uri(transaction_handle, host_url);
add_http_header(transaction_handle);
+ count++;
return transaction_handle;
}
int main()
{
- http_session_h session_handle = NULL;
- http_transaction_h transaction_handle1 = NULL;
- http_transaction_h transaction_handle2 = NULL;
-
DBG("########################## main:Enter#########################################\n");
mainloop = g_main_loop_new(NULL, FALSE);
http_create_session(&session_handle, HTTP_SESSION_MODE_NORMAL);
- transaction_handle1 = create_http_request(session_handle, "http://www.google.com", transaction_header_cb, transaction_body_cb,
- transaction_write_cb, transaction_completed_cb, transaction_aborted_cb);
- transaction_handle2 = create_http_request(session_handle, "http://www.ibnlive.com", transaction_header_callback, transaction_body_callback,
- transaction_write_callback, transaction_completed_callback, transaction_aborted_callback);
+ transaction_handle1 = create_http_request(session_handle, "https://www.google.com");
+ transaction_handle2 = create_http_request(session_handle, "http://www.naver.com");
+
+ http_transaction_set_server_certificate_verification(transaction_handle1, 0);
+ http_transaction_set_received_header_cb(transaction_handle1, transaction_header_cb, NULL);
+ http_transaction_set_received_body_cb(transaction_handle1, transaction_body_cb, NULL);
+ http_transaction_set_uploaded_cb(transaction_handle1, transaction_write_cb, NULL);
+ http_transaction_set_completed_cb(transaction_handle1, transaction_completed_cb, NULL);
+ http_transaction_set_received_header_cb(transaction_handle2, transaction_header_cb, NULL);
+ http_transaction_set_received_body_cb(transaction_handle2, transaction_body_cb, NULL);
+ http_transaction_set_uploaded_cb(transaction_handle2, transaction_write_cb, NULL);
+ http_transaction_set_completed_cb(transaction_handle2, transaction_completed_cb, NULL);
+
+ DBG("transaction1(%p), transaction2(%p)\n", transaction_handle1, transaction_handle2);
submit_http_request(transaction_handle1);
submit_http_request(transaction_handle2);
g_main_loop_run(mainloop);
remove_http_header(transaction_handle1);
+ //http_transaction_close(transaction_handle1);
+
remove_http_header(transaction_handle2);
+ //http_transaction_close(transaction_handle2);
+ http_transaction_close_all(session_handle);
+
+ if (transaction_handle1) DBG("transaction_handle1 remained(%p)\n", transaction_handle1);
+ if (transaction_handle2) DBG("transaction_handle2 remained(%p)\n", transaction_handle2);
- http_transaction_close(transaction_handle1);
- transaction_handle1 = NULL;
- http_transaction_close(transaction_handle2);
transaction_handle1 = NULL;
+ transaction_handle2 = NULL;
+
http_delete_session(session_handle);
session_handle = NULL;
http_deinit();