[capi-http] Fixed crashes in http_transaction_destroy & http_session_destroy
[platform/core/api/http.git] / src / http_transaction.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "http.h"
18 #include "http_private.h"
19
20 static __thread GSList *transaction_list = NULL;
21
22 void _add_transaction_to_list(http_transaction_h http_transaction)
23 {
24         transaction_list = g_slist_append(transaction_list, http_transaction);
25 }
26
27 void _remove_transaction_from_list(http_transaction_h http_transaction)
28 {
29         transaction_list = g_slist_remove(transaction_list, http_transaction);
30 }
31
32 void _remove_transaction_list(void)
33 {
34         g_slist_free_full(transaction_list, g_free);
35         transaction_list = NULL;
36 }
37
38 int _generate_transaction_id(void)
39 {
40         int transaction_id = 0;
41
42         return transaction_id;
43 }
44
45 curl_socket_t __handle_opensocket_cb(void *client_fd, curlsocktype purpose, struct curl_sockaddr *address)
46 {
47         int fd = socket(address->family, address->socktype, address->protocol);
48         DBG("socket opened:%d\n", fd);
49
50         return fd;
51 }
52
53 size_t __handle_header_cb(char *buffer, size_t size, size_t nmemb, gpointer user_data)
54 {
55         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
56         size_t written = size * nmemb;
57
58         __parse_response_header(buffer, written, user_data);
59         transaction->header_cb(transaction, buffer, written, transaction->header_user_data);
60
61         return written;
62 }
63
64 size_t __handle_body_cb(char *ptr, size_t size, size_t nmemb, gpointer user_data)
65 {
66         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
67         size_t written = size * nmemb;
68
69         transaction->body_cb(transaction, ptr, size, nmemb, transaction->body_user_data);
70
71         return written;
72 }
73
74 size_t __handle_write_cb(char *ptr, size_t size, size_t nmemb, gpointer user_data)
75 {
76         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
77         __http_request_h *request = transaction->request;
78         size_t recommended_size = size * nmemb;
79         size_t body_size = 0;
80
81         transaction->write_cb(transaction, recommended_size, transaction->write_user_data);
82
83         ptr = (gchar*)g_queue_pop_head(request->body_queue);
84         if (ptr == NULL) {
85                 DBG("Sent the last chunk.\n");
86                 return 0;
87         }
88         body_size = strlen(ptr);
89
90         return body_size;
91 }
92
93 size_t __http_debug_received(CURL* easy_handle, curl_infotype type, char* byte, size_t size, void *user_data)
94 {
95         char log_buffer[_HTTP_DEFAULT_HEADER_SIZE];
96         int log_size = 0;
97
98         if (_HTTP_DEFAULT_HEADER_SIZE > size)
99                 log_size = size;
100         else
101                 log_size = _HTTP_DEFAULT_HEADER_SIZE - 1;
102
103         if (type == CURLINFO_TEXT) {
104                 strncpy(log_buffer, byte, log_size);
105                 log_buffer[log_size] = '\0';
106                 DBG("[DEBUG] %s", log_buffer);
107         } else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT) {
108                 /* Ignore the body message. */
109                 if (size >= 2 && byte[0] == 0x0D && byte[1] == 0x0A) {
110                         return 0;
111                 } else {
112                         strncpy(log_buffer, byte, log_size);
113                         log_buffer[log_size] = '\0';
114                         DBG("[DEBUG] %s", log_buffer);
115                 }
116         }
117
118         return 0;
119 }
120
121 int _transaction_submit(gpointer user_data)
122 {
123         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
124         __http_session_h *session = transaction->session;
125         __http_request_h *request = transaction->request;
126
127         CURLMcode ret = CURLM_OK;
128         gchar *proxy_addr = NULL;
129         struct curl_slist* header_list = NULL;
130         gchar *field_value = NULL;
131         gboolean write_event = FALSE;
132         gint body_size = 0;
133         gint content_len = 0;
134
135         transaction->easy_handle = curl_easy_init();
136
137         if (request->http_version == HTTP_VERSION_1_0)
138                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
139         else
140                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
141
142         if (request->host_uri)
143                 curl_easy_setopt(transaction->easy_handle, CURLOPT_URL, request->host_uri);
144
145         proxy_addr = _get_proxy();
146         if (proxy_addr) {
147                 DBG("Proxy address:%s\n", proxy_addr);
148                 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXY, proxy_addr);
149                 free(proxy_addr);
150         }
151
152         if (request->method)
153                 curl_easy_setopt(transaction->easy_handle, CURLOPT_CUSTOMREQUEST, request->method);
154
155         if (transaction->interface_name)
156                 curl_easy_setopt(transaction->easy_handle, CURLOPT_INTERFACE, transaction->interface_name);
157
158         header_list = _get_header_list(transaction);
159         if (header_list)
160                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPHEADER, header_list);
161
162         if (request->encoding)
163                 curl_easy_setopt(transaction->easy_handle, CURLOPT_ACCEPT_ENCODING, request->encoding);
164
165         if (request->cookie)
166                 curl_easy_setopt(transaction->easy_handle, CURLOPT_COOKIE, request->cookie);
167
168         /* The connection timeout is 30s. (default) */
169         curl_easy_setopt(transaction->easy_handle, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
170
171         if (transaction->timeout > 0) {
172                 curl_easy_setopt(transaction->easy_handle, CURLOPT_TIMEOUT, transaction->timeout);
173         } else if (transaction->timeout == 0) {
174                 /* Set the transaction timeout. The timeout includes connection timeout. */
175                 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_LIMIT, 1L);
176                 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_TIME, 30L);
177         }
178
179         if (!transaction->verify_peer) {
180                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
181                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 0);
182
183         } else {
184                         curl_easy_setopt(transaction->easy_handle, CURLOPT_CAPATH, transaction->ca_path);
185                         DBG("CA path is (%s)", transaction->ca_path);
186
187                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
188                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 2);
189                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_CIPHER_LIST, "HIGH");
190         }
191
192         if (session->auto_redirect) {
193                 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
194                 curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
195                 DBG("Enabled Auto-Redirection\n");
196         } else {
197                 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 0L);
198                 DBG("Disabled Auto-Redirection\n");
199         }
200
201         curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERFUNCTION, __handle_header_cb);
202         curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERDATA, transaction);
203
204         curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEFUNCTION, __handle_body_cb);
205         curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEDATA, transaction);
206
207         if (http_transaction_header_get_field_value(transaction, "Content-Length", &field_value) == HTTP_ERROR_NONE) {
208                 content_len = atoi(field_value);
209                 if (content_len > 0) {
210                         curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
211                         DBG("Set the Content-Length(%d).", content_len);
212                 } else if (content_len == 0) {
213                         curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
214                         curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, NULL);
215                         DBG("Set the Content-Length(%d).", content_len);
216                 }
217         } else {
218                 DBG("The Content-Length is not set.\n");
219         }
220
221         _get_request_body_size(transaction, &body_size);
222
223         if (transaction->write_event) {
224                 if (content_len >= 0 && content_len <= body_size)
225                         write_event = FALSE;
226                 else
227                         write_event = TRUE;
228                 DBG("The write_event is %d.\n", write_event);
229         }
230
231         if ((_get_method(request->method) == HTTP_METHOD_POST) && !write_event) {
232                 gchar *body = NULL;
233
234                 _read_request_body(transaction, &body);
235
236                 if (body) {
237                         curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, body);
238                         free(body);
239                 }
240         }
241
242         if (write_event) {
243                 curl_easy_setopt(transaction->easy_handle, CURLOPT_POST, 1);
244                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READFUNCTION, __handle_write_cb);
245                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READDATA, transaction);
246         }
247
248         curl_easy_setopt(transaction->easy_handle, CURLOPT_VERBOSE, 1L);
249         curl_easy_setopt(transaction->easy_handle, CURLOPT_DEBUGFUNCTION, __http_debug_received);
250         curl_easy_setopt(transaction->easy_handle, CURLOPT_ERRORBUFFER, transaction->error);
251
252         curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETDATA, &transaction->socket_fd);
253         curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETFUNCTION, __handle_opensocket_cb);
254
255         curl_easy_setopt(transaction->easy_handle, CURLOPT_PRIVATE, transaction);
256
257         ret = curl_multi_add_handle(session->multi_handle, transaction->easy_handle);
258         if (ret == CURLM_OK) {
259                 DBG("CURLM_OK: Called curl_multi_add_handle().");
260         } else {
261                 print_curl_multi_errorCode(ret);
262                 ERR("Failed to add easy_handle to curl_multi_add_handle()");
263         }
264
265         return HTTP_ERROR_NONE;
266 }
267
268 void* thread_callback(void *user_data)
269 {
270         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
271
272         transaction->thread_loop = g_main_loop_new(NULL, FALSE);
273
274         _transaction_submit(transaction);
275
276         g_main_loop_run(transaction->thread_loop);
277
278         DBG("thread exited.\n");
279
280         return NULL;
281 }
282
283 API int http_session_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction)
284 {
285         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION, "http isn't initialized");
286         _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER, "parameter(http_session) is NULL\n");
287
288         __http_transaction_h *transaction = NULL;
289
290         transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
291         if (transaction == NULL) {
292                 ERR("Fail to allocate transaction memory!!");
293                 return HTTP_ERROR_OUT_OF_MEMORY;
294         }
295
296         transaction->easy_handle = NULL;
297         transaction->interface_name = NULL;
298         transaction->timeout = 0;
299         transaction->verify_peer = 1;
300         transaction->ca_path = g_strdup(HTTP_DEFAULT_CA_PATH);
301         transaction->error[0] = '\0';
302
303         transaction->header_cb = NULL;
304         transaction->body_cb = NULL;
305         transaction->write_cb = NULL;
306         transaction->completed_cb = NULL;
307         transaction->aborted_cb = NULL;
308         transaction->progress_cb = NULL;
309
310         transaction->session = http_session;
311         transaction->session->active_transaction_count++;
312         transaction->session_id = 0;
313
314         transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
315         if (transaction->request == NULL) {
316                 ERR("Fail to allocate request memory!!");
317                 return HTTP_ERROR_OUT_OF_MEMORY;
318         }
319
320         transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
321         if (transaction->response == NULL) {
322                 ERR("Fail to allocate response memory!!");
323                 return HTTP_ERROR_OUT_OF_MEMORY;
324         }
325
326         transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
327         if (transaction->header == NULL) {
328                 ERR("Fail to allocate header memory!!");
329                 return HTTP_ERROR_OUT_OF_MEMORY;
330         }
331
332         transaction->request->host_uri = NULL;
333         transaction->request->method = _get_http_method(method);
334         transaction->request->encoding = NULL;
335         transaction->request->cookie = NULL;
336         transaction->request->http_version = HTTP_VERSION_1_1;
337         transaction->request->body_queue = g_queue_new();
338         transaction->request->tot_size = 0;
339
340         transaction->response->status_text = NULL;
341
342         transaction->header->header_list = NULL;
343         transaction->header->hash_table = NULL;
344
345         transaction->thread = NULL;
346         transaction->thread_loop = NULL;
347
348         *http_transaction = (http_transaction_h)transaction;
349         _add_transaction_to_list(transaction);
350
351         return HTTP_ERROR_NONE;
352 }
353
354 API int http_transaction_submit(http_transaction_h http_transaction)
355 {
356         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
357                         "http isn't initialized");
358         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
359                         "parameter(http_transaction) is NULL");
360
361         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
362
363         _retvm_if(transaction->request->host_uri == NULL, HTTP_ERROR_INVALID_OPERATION, "URI isn't set!!");
364
365         transaction->thread = g_thread_new("transaction_thread", thread_callback, transaction);
366
367         return HTTP_ERROR_NONE;
368 }
369
370 API int http_transaction_destroy(http_transaction_h http_transaction)
371 {
372         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
373                         "http isn't initialized");
374         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
375                         "parameter(http_transaction) is NULL\n");
376
377         __http_transaction_h *transaction = NULL;
378         __http_session_h *session = NULL;
379         __http_header_h *header = NULL;
380         __http_request_h *request = NULL;
381         __http_response_h *response = NULL;
382
383         transaction = (__http_transaction_h *)http_transaction;
384         session = transaction->session;
385         request = transaction->request;
386         response = transaction->response;
387         header = transaction->header;
388
389         if (session)
390                 session->active_transaction_count--;
391
392         if (transaction) {
393                 if (transaction->easy_handle != NULL) {
394                         curl_easy_cleanup(transaction->easy_handle);
395                         transaction->easy_handle = NULL;
396                 }
397
398                 if (transaction->interface_name != NULL) {
399                         free(transaction->interface_name);
400                         transaction->interface_name = NULL;
401                 }
402
403                 transaction->timeout = 0;
404                 transaction->verify_peer = 0;
405
406                 if (transaction->ca_path) {
407                         free(transaction->ca_path);
408                         transaction->ca_path = NULL;
409                 }
410                 transaction->error[0] = '\0';
411
412                 transaction->header_cb = NULL;
413                 transaction->body_cb = NULL;
414                 transaction->write_cb = NULL;
415                 transaction->completed_cb = NULL;
416                 transaction->aborted_cb = NULL;
417                 transaction->progress_cb = NULL;
418
419                 if (request) {
420                         if (request->host_uri != NULL) {
421                                 free(request->host_uri);
422                                 request->host_uri = NULL;
423                         }
424
425                         if (request->method != NULL) {
426                                 free(request->method);
427                                 request->method = NULL;
428                         }
429
430                         if (request->encoding != NULL) {
431                                 free(request->encoding);
432                                 request->encoding = NULL;
433                         }
434
435                         if (request->cookie != NULL) {
436                                 free(request->cookie);
437                                 request->cookie = NULL;
438                         }
439
440                         if (request->body_queue != NULL)
441                                 g_queue_free(request->body_queue);
442
443                         free(request);
444                 }
445
446                 if (response) {
447
448                         if (response->status_text != NULL) {
449                                 free(response->status_text);
450                                 response->status_text = NULL;
451                         }
452
453                         free(response);
454
455                 }
456
457                 if (header) {
458                         if (header->header_list != NULL) {
459                                 curl_slist_free_all(header->header_list);
460                                 header->header_list = NULL;
461                         }
462
463                         if (header->hash_table != NULL) {
464                                 g_hash_table_destroy(header->hash_table);
465                                 header->hash_table = NULL;
466                         }
467
468                         free(header);
469                 }
470
471                 _remove_transaction_from_list(transaction);
472
473                 if (transaction->thread_loop != NULL) {
474                         g_main_loop_quit((GMainLoop*)transaction->thread_loop);
475
476                         g_main_loop_unref(transaction->thread_loop);
477                         transaction->thread_loop = NULL;
478                 }
479
480                 if (transaction->thread != NULL) {
481                         g_thread_join(transaction->thread);
482                         transaction->thread = NULL;
483                 }
484
485                 free(transaction);
486                 transaction = NULL;
487         }
488
489         return HTTP_ERROR_NONE;
490 }
491
492 API int http_transaction_pause(http_transaction_h http_transaction, http_pause_type_e pause_type)
493 {
494         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
495                         "http isn't initialized");
496         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
497                         "parameter(http_transaction) is NULL\n");
498         _retvm_if(pause_type < HTTP_PAUSE_RECV || pause_type > HTTP_PAUSE_ALL, HTTP_ERROR_INVALID_PARAMETER,
499                         "Wrong pause state \n");
500
501         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
502         int ret = 0;
503
504         ret = curl_easy_pause(transaction->easy_handle, pause_type);
505         if (ret != 0) {
506                 ERR("Fail to pause!(%d)", ret);
507                 return HTTP_ERROR_OPERATION_FAILED;
508         }
509
510         return HTTP_ERROR_NONE;
511 }
512
513 API int http_transaction_resume(http_transaction_h http_transaction)
514 {
515         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
516                         "http isn't initialized");
517         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
518                         "parameter(http_transaction) is NULL\n");
519
520         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
521         int ret = 0;
522
523         ret = curl_easy_pause(transaction->easy_handle, CURLPAUSE_CONT);
524         if (ret != 0) {
525                 ERR("Fail to resume!(%d)", ret);
526                 return HTTP_ERROR_OPERATION_FAILED;
527         }
528
529         return HTTP_ERROR_NONE;
530 }
531
532
533 API int http_transaction_set_progress_cb(http_transaction_h http_transaction, http_transaction_progress_cb progress_cb, void* user_data)
534 {
535         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
536                         "http isn't initialized");
537         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
538                         "parameter(http_transaction) is NULL\n");
539         _retvm_if(progress_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
540                         "parameter(progress_cb) is NULL\n");
541
542         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
543
544         transaction->progress_cb = progress_cb;
545         transaction->progress_user_data = user_data;
546
547         return HTTP_ERROR_NONE;
548 }
549
550 API int http_transaction_set_received_header_cb(http_transaction_h http_transaction, http_transaction_header_cb header_cb, void* user_data)
551 {
552         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
553                         "http isn't initialized");
554         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
555                         "parameter(http_transaction) is NULL\n");
556         _retvm_if(header_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
557                         "parameter(header_cb) is NULL\n");
558
559         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
560
561         transaction->header_cb = header_cb;
562         transaction->header_user_data = user_data;
563
564         return HTTP_ERROR_NONE;
565 }
566
567 API int http_transaction_set_received_body_cb(http_transaction_h http_transaction, http_transaction_body_cb body_cb, void* user_data)
568 {
569         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
570                         "http isn't initialized");
571         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
572                         "parameter(http_transaction) is NULL\n");
573         _retvm_if(body_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
574                         "parameter(body_cb) is NULL\n");
575
576         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
577
578         transaction->body_cb = body_cb;
579         transaction->body_user_data = user_data;
580
581         return HTTP_ERROR_NONE;
582 }
583
584 API int http_transaction_set_uploaded_cb(http_transaction_h http_transaction, http_transaction_write_cb write_cb, void* user_data)
585 {
586         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
587                         "http isn't initialized");
588         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
589                         "parameter(http_transaction) is NULL\n");
590         _retvm_if(write_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
591                         "parameter(write_cb) is NULL\n");
592
593         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
594
595         transaction->write_cb = write_cb;
596         transaction->write_user_data = user_data;
597
598         return HTTP_ERROR_NONE;
599 }
600
601 API int http_transaction_set_completed_cb(http_transaction_h http_transaction, http_transaction_completed_cb completed_cb, void* user_data)
602 {
603         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
604                         "http isn't initialized");
605         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
606                         "parameter(http_transaction) is NULL\n");
607         _retvm_if(completed_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
608                         "parameter(completed_cb) is NULL\n");
609
610         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
611
612         transaction->completed_cb = completed_cb;
613         transaction->completed_user_data = user_data;
614
615         return HTTP_ERROR_NONE;
616 }
617
618 API int http_transaction_set_aborted_cb(http_transaction_h http_transaction, http_transaction_aborted_cb aborted_cb,  void* user_data)
619 {
620         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
621                         "http isn't initialized");
622         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
623                          "parameter(http_transaction) is NULL\n");
624         _retvm_if(aborted_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
625                         "parameter(aborted_cb) is NULL\n");
626
627         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
628
629         transaction->aborted_cb = aborted_cb;
630
631         return HTTP_ERROR_NONE;
632 }
633
634 API int http_transaction_unset_progress_cb(http_transaction_h http_transaction)
635 {
636         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
637                         "http isn't initialized");
638         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
639                         "parameter(http_transaction) is NULL\n");
640
641         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
642         transaction->progress_cb = NULL;
643
644         return HTTP_ERROR_NONE;
645 }
646
647 API int http_transaction_set_timeout(http_transaction_h http_transaction, int timeout)
648 {
649         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
650                         "http isn't initialized");
651         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
652                         "parameter(http_transaction) is NULL\n");
653
654         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
655
656         transaction->timeout = timeout;
657
658         return HTTP_ERROR_NONE;
659 }
660
661 API int http_transaction_get_timeout(http_transaction_h http_transaction, int *timeout)
662 {
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(timeout == NULL, HTTP_ERROR_INVALID_PARAMETER,
668                         "parameter(timeout) is NULL\n");
669
670         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
671
672         *timeout =  transaction->timeout;
673
674         return HTTP_ERROR_NONE;
675 }
676
677 API int http_transaction_set_interface_name(http_transaction_h http_transaction, const char *interface_name)
678 {
679         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
680                         "http isn't initialized");
681         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
682                         "parameter(http_transaction) is NULL\n");
683         _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
684                         "parameter(interface_name) is NULL\n");
685
686         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
687
688         transaction->interface_name = g_strdup(interface_name);
689
690         return HTTP_ERROR_NONE;
691 }
692
693 API int http_transaction_get_interface_name(http_transaction_h http_transaction, char **interface_name)
694 {
695         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
696                         "http isn't initialized");
697         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
698                         "parameter(http_transaction) is NULL\n");
699         _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
700                         "parameter(interface_name) is NULL\n");
701
702         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
703
704         *interface_name = g_strdup(transaction->interface_name);
705         if (*interface_name == NULL) {
706                 ERR("strdup is failed\n");
707                 return HTTP_ERROR_OUT_OF_MEMORY;
708         }
709
710         return HTTP_ERROR_NONE;
711 }
712
713 API int http_transaction_set_ready_to_write(http_transaction_h http_transaction, bool read_to_write)
714 {
715         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
716                         "http isn't initialized");
717         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
718                         "parameter(http_transaction) is NULL\n");
719
720         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
721
722         transaction->write_event = read_to_write;
723
724         return HTTP_ERROR_NONE;
725 }
726
727 API int http_transaction_get_server_certificate_verification(http_transaction_h http_transaction, bool* verify)
728 {
729         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
730                         "http isn't initialized");
731         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
732                         "parameter(http_transaction) is NULL\n");
733
734         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
735
736         *verify = transaction->verify_peer;
737
738         return HTTP_ERROR_NONE;
739 }
740
741 API int http_transaction_set_server_certificate_verification(http_transaction_h http_transaction, bool verify)
742 {
743         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
744                         "http isn't initialized");
745         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
746                         "parameter(http_transaction) is NULL\n");
747
748         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
749
750         transaction->verify_peer = verify;
751
752         return HTTP_ERROR_NONE;
753 }
754
755 API int http_session_destroy_all_transactions(http_session_h http_session)
756 {
757         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
758                         "http isn't initialized");
759         _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER,
760                         "parameter(http_session) is NULL\n");
761
762         int ret = 0;
763         GSList *list = NULL;
764         __http_session_h *session = (__http_session_h *)http_session;
765
766         for (list = transaction_list; list; list = list->next) {
767                 __http_transaction_h *transaction = (__http_transaction_h *)list->data;
768                 if (session->session_id == transaction->session_id) {
769                         _remove_transaction_from_list(list->data);
770                         ret = http_transaction_destroy((http_transaction_h) transaction);
771                         if (ret != HTTP_ERROR_NONE) {
772                                 ERR("Fail to destroy transaction!!");
773                                 return HTTP_ERROR_OPERATION_FAILED;
774                         }
775                 }
776         }
777
778         return HTTP_ERROR_NONE;
779 }
780