2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "http_private.h"
20 static __thread GSList *transaction_list = NULL;
22 void _add_transaction_to_list(http_transaction_h http_transaction)
24 transaction_list = g_slist_append(transaction_list, http_transaction);
27 void _remove_transaction_from_list(http_transaction_h http_transaction)
29 transaction_list = g_slist_remove(transaction_list, http_transaction);
32 void _remove_transaction_list(void)
34 g_slist_free_full(transaction_list, g_free);
35 transaction_list = NULL;
38 int _generate_transaction_id(void)
40 int transaction_id = 0;
42 return transaction_id;
45 curl_socket_t __handle_opensocket_cb(void *client_fd, curlsocktype purpose, struct curl_sockaddr *address)
47 int fd = socket(address->family, address->socktype, address->protocol);
48 DBG("socket opened:%d\n", fd);
53 size_t __handle_header_cb(gchar *buffer, size_t size, size_t nmemb, gpointer user_data)
55 __http_transaction_h *transaction = (__http_transaction_h *)user_data;
56 __http_header_h *header = transaction->header;
58 gchar *temp_header = NULL;
59 size_t written = size * nmemb;
60 size_t new_len = header->rsp_header_len + written;
62 temp_header = header->rsp_header;
63 header->rsp_header = realloc(header->rsp_header, new_len + 1);
64 if (header->rsp_header == NULL) {
66 ERR("realloc() failed\n");
70 memcpy(header->rsp_header + header->rsp_header_len, buffer, written);
71 header->rsp_header[new_len] = '\0';
72 header->rsp_header_len = new_len;
74 __parse_response_header(buffer, written, user_data);
79 size_t __handle_body_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_data)
81 __http_transaction_h *transaction = (__http_transaction_h *)user_data;
82 __http_header_h *header = transaction->header;
83 size_t written = size * nmemb;
85 if (!transaction->header_event) {
86 transaction->header_event = TRUE;
87 transaction->header_cb(transaction, header->rsp_header, header->rsp_header_len, transaction->header_user_data);
90 transaction->body_cb(transaction, ptr, size, nmemb, transaction->body_user_data);
95 size_t __handle_write_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_data)
97 __http_transaction_h *transaction = (__http_transaction_h *)user_data;
98 __http_request_h *request = transaction->request;
99 size_t recommended_size = size * nmemb;
100 size_t body_size = 0;
102 transaction->write_cb(transaction, recommended_size, transaction->write_user_data);
104 ptr = (gchar*)g_queue_pop_head(request->body_queue);
106 DBG("Sent the last chunk.\n");
109 body_size = strlen(ptr);
114 size_t __http_debug_received(CURL* easy_handle, curl_infotype type, gchar* byte, size_t size, void *user_data)
116 char log_buffer[_HTTP_DEFAULT_HEADER_SIZE];
119 if (_HTTP_DEFAULT_HEADER_SIZE > size)
122 log_size = _HTTP_DEFAULT_HEADER_SIZE - 1;
124 if (type == CURLINFO_TEXT) {
125 strncpy(log_buffer, byte, log_size);
126 log_buffer[log_size] = '\0';
127 DBG("[DEBUG] %s", log_buffer);
128 } else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT) {
129 /* Ignore the body message. */
130 if (size >= 2 && byte[0] == 0x0D && byte[1] == 0x0A) {
133 strncpy(log_buffer, byte, log_size);
134 log_buffer[log_size] = '\0';
135 DBG("[DEBUG] %s", log_buffer);
142 int http_transaction_set_authentication_info(http_transaction_h http_transaction)
144 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
145 "parameter(http_transaction) is NULL\n");
147 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
149 http_auth_scheme_e auth_scheme = HTTP_AUTH_NONE;
151 http_transaction_get_http_auth_scheme(transaction, &auth_scheme);
153 switch (auth_scheme) {
154 case HTTP_AUTH_PROXY_BASIC:
155 case HTTP_AUTH_PROXY_MD5:
156 case HTTP_AUTH_PROXY_NTLM:
157 http_transaction_header_get_field_value(transaction, _HTTP_PROXY_AUTHENTICATE_HEADER_NAME, &transaction->realm);
159 transaction->proxy_auth_type = TRUE;
162 case HTTP_AUTH_WWW_BASIC:
163 case HTTP_AUTH_WWW_MD5:
164 case HTTP_AUTH_WWW_NEGOTIATE:
165 case HTTP_AUTH_WWW_NTLM:
166 http_transaction_header_get_field_value(transaction, _HTTP_WWW_AUTHENTICATE_HEADER_NAME, &transaction->realm);
168 transaction->proxy_auth_type = FALSE;
175 return HTTP_ERROR_NONE;
178 int _transaction_submit(gpointer user_data)
180 __http_transaction_h *transaction = (__http_transaction_h *)user_data;
181 __http_session_h *session = transaction->session;
182 __http_request_h *request = transaction->request;
184 CURLMcode ret = CURLM_OK;
185 gchar *proxy_addr = NULL;
186 struct curl_slist* header_list = NULL;
187 gchar *field_value = NULL;
188 gboolean write_event = FALSE;
190 gint content_len = 0;
191 http_auth_scheme_e auth_scheme = HTTP_AUTH_NONE;
193 if (!transaction->easy_handle)
194 transaction->easy_handle = curl_easy_init();
196 if (request->http_version == HTTP_VERSION_1_0)
197 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
199 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
201 if (request->host_uri)
202 curl_easy_setopt(transaction->easy_handle, CURLOPT_URL, request->host_uri);
204 proxy_addr = _get_proxy();
206 DBG("Proxy address:%s\n", proxy_addr);
207 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXY, proxy_addr);
212 curl_easy_setopt(transaction->easy_handle, CURLOPT_CUSTOMREQUEST, request->method);
214 if (transaction->interface_name)
215 curl_easy_setopt(transaction->easy_handle, CURLOPT_INTERFACE, transaction->interface_name);
217 header_list = _get_header_list(transaction);
219 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPHEADER, header_list);
221 if (request->encoding)
222 curl_easy_setopt(transaction->easy_handle, CURLOPT_ACCEPT_ENCODING, request->encoding);
225 curl_easy_setopt(transaction->easy_handle, CURLOPT_COOKIE, request->cookie);
227 /* The connection timeout is 30s. (default) */
228 curl_easy_setopt(transaction->easy_handle, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
230 if (transaction->timeout > 0) {
231 curl_easy_setopt(transaction->easy_handle, CURLOPT_TIMEOUT, transaction->timeout);
232 } else if (transaction->timeout == 0) {
233 /* Set the transaction timeout. The timeout includes connection timeout. */
234 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_LIMIT, 1L);
235 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_TIME, 30L);
238 if (!transaction->verify_peer) {
239 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
240 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 0);
243 curl_easy_setopt(transaction->easy_handle, CURLOPT_CAPATH, transaction->ca_path);
244 DBG("CA path is (%s)", transaction->ca_path);
246 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
247 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 2);
248 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_CIPHER_LIST, "HIGH");
251 if (session->auto_redirect) {
252 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
253 curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
254 DBG("Enabled Auto-Redirection\n");
256 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 0L);
257 DBG("Disabled Auto-Redirection\n");
261 if (transaction->auth_required) {
263 curl_http_auth_scheme_e curl_auth_scheme;
264 gchar *user_name = NULL;
265 gchar *password = NULL;
266 gchar *credentials = NULL;
268 http_transaction_get_credentials(transaction, &user_name, &password);
269 credentials = (gchar *)malloc(sizeof(gchar) * (strlen(user_name) + 1 + strlen(password) + 1));
270 sprintf(credentials, "%s:%s", (gchar*)user_name, (gchar*)password);
274 http_transaction_get_http_auth_scheme(transaction, &auth_scheme);
276 curl_auth_scheme = _get_http_curl_auth_scheme(auth_scheme);
278 if (transaction->proxy_auth_type) {
280 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXYAUTH, curl_auth_scheme);
281 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXYUSERPWD, credentials);
284 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPAUTH, curl_auth_scheme);
285 curl_easy_setopt(transaction->easy_handle, CURLOPT_USERPWD, credentials);
290 curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERFUNCTION, __handle_header_cb);
291 curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERDATA, transaction);
293 curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEFUNCTION, __handle_body_cb);
294 curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEDATA, transaction);
296 if (http_transaction_header_get_field_value(transaction, "Content-Length", &field_value) == HTTP_ERROR_NONE) {
297 content_len = atoi(field_value);
298 if (content_len > 0) {
299 curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
300 DBG("Set the Content-Length(%d).", content_len);
301 } else if (content_len == 0) {
302 curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
303 curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, NULL);
304 DBG("Set the Content-Length(%d).", content_len);
307 DBG("The Content-Length is not set.\n");
310 _get_request_body_size(transaction, &body_size);
312 if (transaction->write_event) {
313 if (content_len >= 0 && content_len <= body_size)
317 DBG("The write_event is %d.\n", write_event);
320 if ((_get_method(request->method) == HTTP_METHOD_POST) && !write_event) {
323 _read_request_body(transaction, &body);
326 curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, body);
332 curl_easy_setopt(transaction->easy_handle, CURLOPT_POST, 1);
333 curl_easy_setopt(transaction->easy_handle, CURLOPT_READFUNCTION, __handle_write_cb);
334 curl_easy_setopt(transaction->easy_handle, CURLOPT_READDATA, transaction);
337 curl_easy_setopt(transaction->easy_handle, CURLOPT_VERBOSE, 1L);
338 curl_easy_setopt(transaction->easy_handle, CURLOPT_DEBUGFUNCTION, __http_debug_received);
339 curl_easy_setopt(transaction->easy_handle, CURLOPT_ERRORBUFFER, transaction->error);
341 curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETDATA, &transaction->socket_fd);
342 curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETFUNCTION, __handle_opensocket_cb);
344 curl_easy_setopt(transaction->easy_handle, CURLOPT_PRIVATE, transaction);
346 ret = curl_multi_add_handle(session->multi_handle, transaction->easy_handle);
347 if (ret == CURLM_OK) {
348 DBG("CURLM_OK: Called curl_multi_add_handle().");
350 print_curl_multi_errorCode(ret);
351 ERR("Failed to add easy_handle to curl_multi_add_handle()");
354 return HTTP_ERROR_NONE;
357 void* thread_callback(void *user_data)
359 __http_transaction_h *transaction = (__http_transaction_h *)user_data;
361 transaction->thread_loop = g_main_loop_new(NULL, FALSE);
363 _transaction_submit(transaction);
365 g_main_loop_run(transaction->thread_loop);
367 DBG("thread exited.\n");
372 API int http_session_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction)
374 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION, "http isn't initialized");
375 _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER, "parameter(http_session) is NULL\n");
377 __http_transaction_h *transaction = NULL;
379 transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
380 if (transaction == NULL) {
381 ERR("Fail to allocate transaction memory!!");
382 return HTTP_ERROR_OUT_OF_MEMORY;
385 transaction->easy_handle = NULL;
386 transaction->interface_name = NULL;
387 transaction->timeout = 0;
388 transaction->verify_peer = 1;
389 transaction->ca_path = g_strdup(HTTP_DEFAULT_CA_PATH);
390 transaction->error[0] = '\0';
392 transaction->auth_required = FALSE;
393 transaction->realm = NULL;
394 transaction->user_name = NULL;
395 transaction->password = NULL;
396 transaction->proxy_auth_type = FALSE;
397 transaction->auth_scheme = HTTP_AUTH_NONE;
399 transaction->header_cb = NULL;
400 transaction->body_cb = NULL;
401 transaction->write_cb = NULL;
402 transaction->completed_cb = NULL;
403 transaction->aborted_cb = NULL;
404 transaction->progress_cb = NULL;
406 transaction->session = http_session;
407 transaction->session->active_transaction_count++;
408 transaction->session_id = 0;
410 transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
411 if (transaction->request == NULL) {
412 ERR("Fail to allocate request memory!!");
413 return HTTP_ERROR_OUT_OF_MEMORY;
416 transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
417 if (transaction->response == NULL) {
418 ERR("Fail to allocate response memory!!");
419 return HTTP_ERROR_OUT_OF_MEMORY;
422 transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
423 if (transaction->header == NULL) {
424 ERR("Fail to allocate header memory!!");
425 return HTTP_ERROR_OUT_OF_MEMORY;
428 transaction->header->rsp_header_len = 0;
429 transaction->header->rsp_header = malloc(transaction->header->rsp_header_len + 1);
430 transaction->header->rsp_header[0] = '\0';
431 transaction->header_event = FALSE;
433 transaction->request->host_uri = NULL;
434 transaction->request->method = _get_http_method(method);
435 transaction->request->encoding = NULL;
436 transaction->request->cookie = NULL;
437 transaction->request->http_version = HTTP_VERSION_1_1;
438 transaction->request->body_queue = g_queue_new();
439 transaction->request->tot_size = 0;
441 transaction->response->status_text = NULL;
443 transaction->header->header_list = NULL;
444 transaction->header->hash_table = NULL;
446 transaction->thread = NULL;
447 transaction->thread_loop = NULL;
449 *http_transaction = (http_transaction_h)transaction;
450 _add_transaction_to_list(transaction);
452 return HTTP_ERROR_NONE;
455 API int http_transaction_submit(http_transaction_h http_transaction)
457 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
458 "http isn't initialized");
459 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
460 "parameter(http_transaction) is NULL");
462 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
464 _retvm_if(transaction->request->host_uri == NULL, HTTP_ERROR_INVALID_OPERATION, "URI isn't set!!");
466 transaction->thread = g_thread_new("transaction_thread", thread_callback, transaction);
468 return HTTP_ERROR_NONE;
471 API int http_transaction_destroy(http_transaction_h http_transaction)
473 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
474 "http isn't initialized");
475 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
476 "parameter(http_transaction) is NULL\n");
478 __http_transaction_h *transaction = NULL;
479 __http_session_h *session = NULL;
480 __http_header_h *header = NULL;
481 __http_request_h *request = NULL;
482 __http_response_h *response = NULL;
484 transaction = (__http_transaction_h *)http_transaction;
485 session = transaction->session;
486 request = transaction->request;
487 response = transaction->response;
488 header = transaction->header;
491 session->active_transaction_count--;
494 if (transaction->easy_handle != NULL) {
495 curl_easy_cleanup(transaction->easy_handle);
496 transaction->easy_handle = NULL;
499 if (transaction->interface_name != NULL) {
500 free(transaction->interface_name);
501 transaction->interface_name = NULL;
504 transaction->timeout = 0;
505 transaction->verify_peer = 0;
507 if (transaction->ca_path) {
508 free(transaction->ca_path);
509 transaction->ca_path = NULL;
511 transaction->error[0] = '\0';
513 if (transaction->user_name) {
514 free(transaction->user_name);
515 transaction->user_name = NULL;
518 if (transaction->password) {
519 free(transaction->password);
520 transaction->password = NULL;
523 if (transaction->realm) {
524 free(transaction->realm);
525 transaction->realm = NULL;
528 transaction->auth_required = FALSE;
529 transaction->proxy_auth_type = FALSE;
530 transaction->auth_scheme = HTTP_AUTH_NONE;
532 transaction->header_cb = NULL;
533 transaction->body_cb = NULL;
534 transaction->write_cb = NULL;
535 transaction->completed_cb = NULL;
536 transaction->aborted_cb = NULL;
537 transaction->progress_cb = NULL;
540 if (request->host_uri != NULL) {
541 free(request->host_uri);
542 request->host_uri = NULL;
545 if (request->method != NULL) {
546 free(request->method);
547 request->method = NULL;
550 if (request->encoding != NULL) {
551 free(request->encoding);
552 request->encoding = NULL;
555 if (request->cookie != NULL) {
556 free(request->cookie);
557 request->cookie = NULL;
560 if (request->body_queue != NULL)
561 g_queue_free(request->body_queue);
568 if (response->status_text != NULL) {
569 free(response->status_text);
570 response->status_text = NULL;
578 if (header->header_list != NULL) {
579 curl_slist_free_all(header->header_list);
580 header->header_list = NULL;
583 if (header->hash_table != NULL) {
585 g_hash_table_remove_all(header->hash_table);
587 g_hash_table_destroy(header->hash_table);
588 header->hash_table = NULL;
591 if (header->rsp_header != NULL) {
592 free(header->rsp_header);
593 header->rsp_header = NULL;
594 header->rsp_header_len = 0;
599 _remove_transaction_from_list(transaction);
601 if (transaction->thread_loop != NULL) {
602 g_main_loop_quit((GMainLoop*)transaction->thread_loop);
604 g_main_loop_unref(transaction->thread_loop);
605 transaction->thread_loop = NULL;
608 if (transaction->thread != NULL) {
609 g_thread_join(transaction->thread);
610 transaction->thread = NULL;
617 return HTTP_ERROR_NONE;
620 API int http_transaction_pause(http_transaction_h http_transaction, http_pause_type_e pause_type)
622 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
623 "http isn't initialized");
624 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
625 "parameter(http_transaction) is NULL\n");
626 _retvm_if(pause_type < HTTP_PAUSE_RECV || pause_type > HTTP_PAUSE_ALL, HTTP_ERROR_INVALID_PARAMETER,
627 "Wrong pause state \n");
629 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
632 ret = curl_easy_pause(transaction->easy_handle, pause_type);
634 ERR("Fail to pause!(%d)", ret);
635 return HTTP_ERROR_OPERATION_FAILED;
638 return HTTP_ERROR_NONE;
641 API int http_transaction_resume(http_transaction_h http_transaction)
643 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
644 "http isn't initialized");
645 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
646 "parameter(http_transaction) is NULL\n");
648 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
651 ret = curl_easy_pause(transaction->easy_handle, CURLPAUSE_CONT);
653 ERR("Fail to resume!(%d)", ret);
654 return HTTP_ERROR_OPERATION_FAILED;
657 return HTTP_ERROR_NONE;
661 API int http_transaction_set_progress_cb(http_transaction_h http_transaction, http_transaction_progress_cb progress_cb, void* user_data)
663 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
664 "http isn't initialized");
665 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
666 "parameter(http_transaction) is NULL\n");
667 _retvm_if(progress_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
668 "parameter(progress_cb) is NULL\n");
670 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
672 transaction->progress_cb = progress_cb;
673 transaction->progress_user_data = user_data;
675 return HTTP_ERROR_NONE;
678 API int http_transaction_set_received_header_cb(http_transaction_h http_transaction, http_transaction_header_cb header_cb, void* user_data)
680 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
681 "http isn't initialized");
682 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
683 "parameter(http_transaction) is NULL\n");
684 _retvm_if(header_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
685 "parameter(header_cb) is NULL\n");
687 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
689 transaction->header_cb = header_cb;
690 transaction->header_user_data = user_data;
692 return HTTP_ERROR_NONE;
695 API int http_transaction_set_received_body_cb(http_transaction_h http_transaction, http_transaction_body_cb body_cb, void* user_data)
697 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
698 "http isn't initialized");
699 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
700 "parameter(http_transaction) is NULL\n");
701 _retvm_if(body_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
702 "parameter(body_cb) is NULL\n");
704 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
706 transaction->body_cb = body_cb;
707 transaction->body_user_data = user_data;
709 return HTTP_ERROR_NONE;
712 API int http_transaction_set_uploaded_cb(http_transaction_h http_transaction, http_transaction_write_cb write_cb, void* user_data)
714 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
715 "http isn't initialized");
716 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
717 "parameter(http_transaction) is NULL\n");
718 _retvm_if(write_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
719 "parameter(write_cb) is NULL\n");
721 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
723 transaction->write_cb = write_cb;
724 transaction->write_user_data = user_data;
726 return HTTP_ERROR_NONE;
729 API int http_transaction_set_completed_cb(http_transaction_h http_transaction, http_transaction_completed_cb completed_cb, void* user_data)
731 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
732 "http isn't initialized");
733 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
734 "parameter(http_transaction) is NULL\n");
735 _retvm_if(completed_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
736 "parameter(completed_cb) is NULL\n");
738 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
740 transaction->completed_cb = completed_cb;
741 transaction->completed_user_data = user_data;
743 return HTTP_ERROR_NONE;
746 API int http_transaction_set_aborted_cb(http_transaction_h http_transaction, http_transaction_aborted_cb aborted_cb, void* user_data)
748 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
749 "http isn't initialized");
750 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
751 "parameter(http_transaction) is NULL\n");
752 _retvm_if(aborted_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
753 "parameter(aborted_cb) is NULL\n");
755 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
757 transaction->aborted_cb = aborted_cb;
759 return HTTP_ERROR_NONE;
762 API int http_transaction_unset_progress_cb(http_transaction_h http_transaction)
764 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
765 "http isn't initialized");
766 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
767 "parameter(http_transaction) is NULL\n");
769 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
770 transaction->progress_cb = NULL;
772 return HTTP_ERROR_NONE;
775 API int http_transaction_set_timeout(http_transaction_h http_transaction, int timeout)
777 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
778 "http isn't initialized");
779 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
780 "parameter(http_transaction) is NULL\n");
782 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
784 transaction->timeout = timeout;
786 return HTTP_ERROR_NONE;
789 API int http_transaction_get_timeout(http_transaction_h http_transaction, int *timeout)
791 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
792 "http isn't initialized");
793 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
794 "parameter(http_transaction) is NULL\n");
795 _retvm_if(timeout == NULL, HTTP_ERROR_INVALID_PARAMETER,
796 "parameter(timeout) is NULL\n");
798 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
800 *timeout = transaction->timeout;
802 return HTTP_ERROR_NONE;
805 API int http_transaction_set_interface_name(http_transaction_h http_transaction, const char *interface_name)
807 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
808 "http isn't initialized");
809 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
810 "parameter(http_transaction) is NULL\n");
811 _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
812 "parameter(interface_name) is NULL\n");
814 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
816 transaction->interface_name = g_strdup(interface_name);
818 return HTTP_ERROR_NONE;
821 API int http_transaction_get_interface_name(http_transaction_h http_transaction, char **interface_name)
823 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
824 "http isn't initialized");
825 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
826 "parameter(http_transaction) is NULL\n");
827 _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
828 "parameter(interface_name) is NULL\n");
830 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
832 *interface_name = g_strdup(transaction->interface_name);
833 if (*interface_name == NULL) {
834 ERR("strdup is failed\n");
835 return HTTP_ERROR_OUT_OF_MEMORY;
838 return HTTP_ERROR_NONE;
841 API int http_transaction_set_ready_to_write(http_transaction_h http_transaction, bool read_to_write)
843 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
844 "http isn't initialized");
845 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
846 "parameter(http_transaction) is NULL\n");
848 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
850 transaction->write_event = read_to_write;
852 return HTTP_ERROR_NONE;
855 API int http_transaction_get_server_certificate_verification(http_transaction_h http_transaction, bool* verify)
857 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
858 "http isn't initialized");
859 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
860 "parameter(http_transaction) is NULL\n");
862 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
864 *verify = transaction->verify_peer;
866 return HTTP_ERROR_NONE;
869 API int http_transaction_set_server_certificate_verification(http_transaction_h http_transaction, bool verify)
871 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
872 "http isn't initialized");
873 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
874 "parameter(http_transaction) is NULL\n");
876 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
878 transaction->verify_peer = verify;
880 return HTTP_ERROR_NONE;
883 API int http_session_destroy_all_transactions(http_session_h http_session)
885 _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
886 "http isn't initialized");
887 _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER,
888 "parameter(http_session) is NULL\n");
892 __http_session_h *session = (__http_session_h *)http_session;
894 for (list = transaction_list; list; list = list->next) {
895 __http_transaction_h *transaction = (__http_transaction_h *)list->data;
896 if (session->session_id == transaction->session_id) {
897 _remove_transaction_from_list(list->data);
898 ret = http_transaction_destroy((http_transaction_h) transaction);
899 if (ret != HTTP_ERROR_NONE) {
900 ERR("Fail to destroy transaction!!");
901 return HTTP_ERROR_OPERATION_FAILED;
906 return HTTP_ERROR_NONE;
909 API int http_transaction_set_http_auth_scheme(http_transaction_h http_transaction, http_auth_scheme_e auth_scheme)
911 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
912 "parameter(http_transaction) is NULL\n");
914 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
916 transaction->auth_scheme = auth_scheme;
918 return HTTP_ERROR_NONE;
921 API int http_transaction_get_http_auth_scheme(http_transaction_h http_transaction, http_auth_scheme_e *auth_scheme)
923 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
924 "parameter(http_transaction) is NULL\n");
925 _retvm_if(auth_scheme == NULL, HTTP_ERROR_INVALID_PARAMETER,
926 "parameter(auth_scheme) is NULL\n");
928 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
930 *auth_scheme = transaction->auth_scheme;
932 return HTTP_ERROR_NONE;
935 API int http_transaction_get_realm(http_transaction_h http_transaction, char **realm)
937 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
938 "parameter(http_transaction) is NULL\n");
939 _retvm_if(realm == NULL, HTTP_ERROR_INVALID_PARAMETER,
940 "parameter(realm) is NULL\n");
942 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
944 if (transaction->realm == NULL)
945 return HTTP_ERROR_INVALID_OPERATION;
947 *realm = g_strdup(transaction->realm);
948 if (*realm == NULL) {
949 ERR("strdup is failed\n");
950 return HTTP_ERROR_OUT_OF_MEMORY;
953 return HTTP_ERROR_NONE;
956 API int http_transaction_set_credentials(http_transaction_h http_transaction, const char *user_name, const char *password)
958 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
959 "parameter(http_transaction) is NULL\n");
960 _retvm_if(user_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
961 "parameter(user_name) is NULL\n");
962 _retvm_if(password == NULL, HTTP_ERROR_INVALID_PARAMETER,
963 "parameter(password) is NULL\n");
965 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
967 transaction->user_name = g_strdup(user_name);
968 transaction->password = g_strdup(password);
970 return HTTP_ERROR_NONE;
973 API int http_transaction_get_credentials(http_transaction_h http_transaction, char **user_name, char **password)
975 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
976 "parameter(http_transaction) is NULL\n");
977 _retvm_if(user_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
978 "parameter(user_name) is NULL\n");
979 _retvm_if(password == NULL, HTTP_ERROR_INVALID_PARAMETER,
980 "parameter(password) is NULL\n");
982 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
984 *user_name = g_strdup(transaction->user_name);
985 if (*user_name == NULL) {
986 ERR("strdup is failed\n");
987 return HTTP_ERROR_OUT_OF_MEMORY;
990 *password = g_strdup(transaction->password);
991 if (*password == NULL) {
992 ERR("strdup is failed\n");
993 return HTTP_ERROR_OUT_OF_MEMORY;
995 return HTTP_ERROR_NONE;
998 API int http_transaction_open_authentication(http_transaction_h http_transaction, http_transaction_h *http_auth_transaction)
1000 _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1001 "parameter(http_transaction) is NULL\n");
1003 __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1004 __http_transaction_h *auth_transaction = NULL;
1006 auth_transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
1007 if (auth_transaction == NULL) {
1008 ERR("Fail to allocate transaction memory!!");
1009 return HTTP_ERROR_OUT_OF_MEMORY;
1012 auth_transaction->easy_handle = NULL;
1013 auth_transaction->interface_name = NULL;
1014 auth_transaction->ca_path = NULL;
1015 auth_transaction->error[0] = '\0';
1017 if (transaction->interface_name)
1018 auth_transaction->interface_name = g_strdup(transaction->interface_name);
1019 auth_transaction->timeout = 0;
1020 auth_transaction->verify_peer = transaction->verify_peer;
1021 if (transaction->ca_path)
1022 auth_transaction->ca_path = g_strdup(transaction->ca_path);
1024 auth_transaction->auth_required = transaction->auth_required;
1025 auth_transaction->realm = NULL;
1026 auth_transaction->user_name = NULL;
1027 auth_transaction->password = NULL;
1028 auth_transaction->proxy_auth_type = FALSE;
1029 auth_transaction->auth_scheme = transaction->auth_scheme;
1030 auth_transaction->write_event = FALSE;
1032 auth_transaction->header_cb = NULL;
1033 auth_transaction->header_user_data = NULL;
1034 auth_transaction->body_cb = NULL;
1035 auth_transaction->body_user_data = NULL;
1036 auth_transaction->write_cb = NULL;
1037 auth_transaction->write_user_data = NULL;
1038 auth_transaction->completed_cb = NULL;
1039 auth_transaction->completed_user_data = NULL;
1040 auth_transaction->aborted_cb = NULL;
1041 auth_transaction->progress_cb = NULL;
1042 auth_transaction->progress_user_data = NULL;
1044 auth_transaction->session = transaction->session;
1045 auth_transaction->session->active_transaction_count = transaction->session->active_transaction_count;
1046 auth_transaction->session_id = transaction->session_id;
1048 auth_transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
1049 if (auth_transaction->request == NULL) {
1050 free(auth_transaction->interface_name);
1051 free(auth_transaction->ca_path);
1052 free(auth_transaction);
1053 ERR("Fail to allocate request memory!!");
1054 return HTTP_ERROR_OUT_OF_MEMORY;
1057 auth_transaction->request->host_uri = NULL;
1058 auth_transaction->request->method = NULL;
1060 auth_transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
1061 if (auth_transaction->response == NULL) {
1062 free(auth_transaction->interface_name);
1063 free(auth_transaction->ca_path);
1064 free(auth_transaction->request);
1065 free(auth_transaction);
1066 ERR("Fail to allocate response memory!!");
1067 return HTTP_ERROR_OUT_OF_MEMORY;
1070 auth_transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
1071 if (auth_transaction->header == NULL) {
1072 free(auth_transaction->interface_name);
1073 free(auth_transaction->ca_path);
1074 free(auth_transaction->request);
1075 free(auth_transaction->response);
1076 free(auth_transaction);
1077 ERR("Fail to allocate header memory!!");
1078 return HTTP_ERROR_OUT_OF_MEMORY;
1081 auth_transaction->header->rsp_header_len = 0;
1082 auth_transaction->header->rsp_header = malloc(auth_transaction->header->rsp_header_len + 1);
1083 auth_transaction->header->rsp_header[0] = '\0';
1084 auth_transaction->header_event = FALSE;
1086 if (transaction->request->host_uri)
1087 auth_transaction->request->host_uri = g_strdup(transaction->request->host_uri);
1088 if (transaction->request->method)
1089 auth_transaction->request->method = g_strdup(transaction->request->method);
1090 auth_transaction->request->encoding = NULL;
1091 auth_transaction->request->cookie = NULL;
1092 auth_transaction->request->http_version = HTTP_VERSION_1_1;
1093 auth_transaction->request->body_queue = g_queue_new();
1094 auth_transaction->request->tot_size = 0;
1096 auth_transaction->header->header_list = NULL;
1097 auth_transaction->header->hash_table = NULL;
1099 auth_transaction->thread = NULL;
1101 *http_auth_transaction = (http_transaction_h)auth_transaction;
1102 _add_transaction_to_list(auth_transaction);
1104 http_transaction_set_authentication_info((http_transaction_h)auth_transaction);
1106 return HTTP_ERROR_NONE;