[SATIZENVUL-1601] Fix incorrect use of free
[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 <linux/version.h>
18
19 #include "http.h"
20 #include "http_private.h"
21
22 static __thread GList *transaction_list = NULL;
23
24 //LCOV_EXCL_START
25 void _add_transaction_to_list(http_transaction_h http_transaction)
26 {
27         transaction_list = g_list_append(transaction_list, http_transaction);
28 }
29
30 void _remove_transaction_from_list(http_transaction_h http_transaction)
31 {
32         transaction_list = g_list_remove(transaction_list, http_transaction);
33 }
34
35 void _remove_transaction_list(void)
36 {
37         g_list_free_full(transaction_list, g_free);
38         transaction_list = NULL;
39 }
40
41 void _destroy_transactions(int session_id)
42 {
43         int ret = 0;
44         GList *list = transaction_list;
45
46         while (list) {
47                 __http_transaction_h *transaction = (__http_transaction_h *)list->data;
48                 if (session_id == transaction->session->session_id) {
49                         DBG("PREV[%p] NEXT[%p]", list->prev, list->next);
50                         if (list->prev)
51                                 list = list->prev;
52                         else
53                                 list = list->next;
54
55                         ret = http_transaction_destroy((http_transaction_h) transaction);
56                         if (ret != HTTP_ERROR_NONE)
57                                 ERR("Fail to destroy transaction!!");
58
59                         continue;
60                 }
61                 list = list->next;
62         }
63 }
64 //LCOV_EXCL_STOP
65
66 curl_socket_t __handle_opensocket_cb(void *client_fd, curlsocktype purpose, struct curl_sockaddr *address)
67 {
68         int fd = socket(address->family, address->socktype, address->protocol);
69         DBG("socket opened:%d\n", fd);
70
71         return fd;
72 }
73
74 size_t __handle_header_cb(gchar *buffer, size_t size, size_t nmemb, gpointer user_data)
75 {
76         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
77         __http_header_h *header = transaction->header;
78
79         gchar *tmp = NULL;
80         size_t written = size * nmemb;
81         size_t new_len = header->rsp_header_len + written;
82
83         tmp = (gchar *)realloc(header->rsp_header, new_len + 1);
84         if (tmp == NULL) {
85                 ERR("realloc() failed\n");
86                 return -1;
87         } else {
88                 header->rsp_header = tmp;
89         }
90
91         memcpy(header->rsp_header + header->rsp_header_len, buffer, written);
92         header->rsp_header[new_len] = '\0';
93         header->rsp_header_len = new_len;
94
95         __parse_response_header(buffer, written, user_data);
96
97         return written;
98 }
99
100 size_t __handle_body_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_data)
101 {
102         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
103         __http_header_h *header = transaction->header;
104         size_t written = size * nmemb;
105
106         if (!transaction->header_event) {
107                 transaction->header_event = TRUE;
108                 if (transaction->header_cb)
109                         transaction->header_cb(transaction, header->rsp_header, header->rsp_header_len, transaction->header_user_data);
110         }
111
112         if (transaction->body_cb)
113                 transaction->body_cb(transaction, ptr, size, nmemb, transaction->body_user_data);
114
115         return written;
116 }
117
118 //LCOV_EXCL_START
119 size_t __handle_write_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_data)
120 {
121         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
122         __http_request_h *request = transaction->request;
123         size_t body_size = 0;
124         size_t max_size = size * nmemb;
125         char *data = NULL;
126
127         data = (char *)g_queue_pop_head(request->body_queue);
128         if (data) {
129                 body_size = strlen(data);
130                 memcpy(ptr, data, (max_size > body_size) ? body_size : max_size);
131         } else {
132                 DBG("Sent the last chunk.\n");
133                 return 0;
134         }
135
136         if (transaction->write_cb)
137                 transaction->write_cb(transaction, body_size, transaction->write_user_data);
138
139         return body_size;
140 }
141
142 size_t __handle_upload_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_data)
143 {
144         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
145         size_t recommended_size;
146         curl_off_t nread;
147         FILE *fp = _get_upload_file(transaction);
148
149         recommended_size = fread(ptr, size, nmemb, fp);
150         nread = (curl_off_t)recommended_size;
151         DBG("Read %" CURL_FORMAT_CURL_OFF_T " bytes from file", nread);
152
153         if (transaction->write_cb)
154                 transaction->write_cb(transaction, recommended_size, transaction->write_user_data);
155
156         return recommended_size;
157 }
158 //LCOV_EXCL_STOP
159
160 size_t __http_debug_received(CURL *easy_handle, curl_infotype type, gchar *byte, size_t size, void *user_data)
161 {
162         char log_buffer[_HTTP_DEFAULT_HEADER_SIZE];
163         int log_size = 0;
164
165         if (_HTTP_DEFAULT_HEADER_SIZE > size)
166                 log_size = size;
167         else
168                 log_size = _HTTP_DEFAULT_HEADER_SIZE - 1;
169
170         if (type == CURLINFO_TEXT) {
171                 strncpy(log_buffer, byte, log_size);
172                 log_buffer[log_size] = '\0';
173                 DBG("[DEBUG] %s", log_buffer);
174         } else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT) {
175                 /* Ignore the body message. */
176                 if (size >= 2 && byte[0] == 0x0D && byte[1] == 0x0A) {
177                         return 0;
178                 } else {
179                         strncpy(log_buffer, byte, log_size);
180                         log_buffer[log_size] = '\0';
181                         DBG("[DEBUG] %s", log_buffer);
182                 }
183         }
184
185         return 0;
186 }
187
188 int __progress_cb(void *user_data, double dltotal, double dlnow, double ultotal, double ulnow)
189 {
190         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
191
192         double total_download = dltotal;
193         double current_download = dlnow;
194         double total_upload = ultotal;
195         double current_upload = ulnow;
196
197         if (transaction->progress_cb)
198                 transaction->progress_cb(transaction, total_download, current_download,
199                                                         total_upload, current_upload, transaction->progress_user_data);
200
201         return transaction->cancel;
202 }
203
204 //LCOV_EXCL_START
205 int _set_authentication_info(http_transaction_h http_transaction)
206 {
207         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
208                         "parameter(http_transaction) is NULL\n");
209
210         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
211
212         http_auth_scheme_e auth_scheme = HTTP_AUTH_NONE;
213
214         http_transaction_get_http_auth_scheme(transaction, &auth_scheme);
215
216         switch (auth_scheme) {
217         case HTTP_AUTH_PROXY_BASIC:
218         case HTTP_AUTH_PROXY_MD5:
219         case HTTP_AUTH_PROXY_NTLM:
220                 http_transaction_header_get_field_value(transaction, _HTTP_PROXY_AUTHENTICATE_HEADER_NAME, &transaction->realm);
221
222                 transaction->proxy_auth_type = TRUE;
223                 break;
224
225         case HTTP_AUTH_WWW_BASIC:
226         case HTTP_AUTH_WWW_MD5:
227         case HTTP_AUTH_WWW_NEGOTIATE:
228         case HTTP_AUTH_WWW_NTLM:
229                 http_transaction_header_get_field_value(transaction, _HTTP_WWW_AUTHENTICATE_HEADER_NAME, &transaction->realm);
230
231                 transaction->proxy_auth_type = FALSE;
232                 break;
233
234         default:
235                 break;
236         }
237
238         return HTTP_ERROR_NONE;
239 }
240 //LCOV_EXCL_STOP
241
242 void _http_transaction_start_timer(guint msecs, gboolean(*callback) (gpointer), void *user_data)
243 {
244         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
245         guint t_id = 0;
246
247         if (callback == NULL)
248                 return;
249
250         if (transaction->timer_event != 0) {
251                 ERR("timer is already registered[%u]", transaction->timer_event);
252                 return;
253         }
254
255         t_id = g_timeout_add(msecs, callback, user_data);
256         if (t_id == 0) {
257                 ERR("Failed to add timer");
258                 return;
259         }
260
261         DBG("g_timeout_add[%u]", t_id);
262
263         transaction->timer_event = t_id;
264 }
265
266 void _http_transaction_stop_timer(__http_transaction_h *transaction)
267 {
268         if (transaction->timer_event <= 0)
269                 return;
270
271         if (transaction->timer_event) {
272            DBG("g_source_remove[%u]", transaction->timer_event);
273                 g_source_remove(transaction->timer_event);
274                 transaction->timer_event = 0;
275         }
276 }
277
278 int _transaction_submit(gpointer user_data)
279 {
280         __http_transaction_h *transaction = (__http_transaction_h *)user_data;
281         __http_session_h *session = transaction->session;
282         __http_request_h *request = transaction->request;
283
284         int ret = HTTP_ERROR_NONE;
285         gchar *proxy_addr = NULL;
286         struct curl_slist* header_list = NULL;
287         gchar *field_value = NULL;
288         gboolean write_event = FALSE;
289         gint body_size = 0;
290         gint content_len = 0;
291         http_auth_scheme_e auth_scheme = HTTP_AUTH_NONE;
292
293         if (!transaction->easy_handle)
294                 transaction->easy_handle = curl_easy_init();
295
296         if (request->http_version == HTTP_VERSION_1_0)
297                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
298         else
299                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
300
301         if (request->host_uri)
302                 curl_easy_setopt(transaction->easy_handle, CURLOPT_URL, request->host_uri);
303
304         proxy_addr = _get_proxy();
305         if (proxy_addr) {
306                 DBG("Proxy address:%s\n", proxy_addr);
307                 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXY, proxy_addr);
308                 free(proxy_addr);
309         }
310
311         if (request->method)
312                 curl_easy_setopt(transaction->easy_handle, CURLOPT_CUSTOMREQUEST, request->method);
313
314         if (transaction->interface_name)
315                 curl_easy_setopt(transaction->easy_handle, CURLOPT_INTERFACE, transaction->interface_name);
316
317         header_list = _get_header_list(transaction);
318         if (header_list)
319                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPHEADER, header_list);
320
321         if (request->encoding)
322                 curl_easy_setopt(transaction->easy_handle, CURLOPT_ACCEPT_ENCODING, request->encoding);
323
324         if (request->cookie)
325                 curl_easy_setopt(transaction->easy_handle, CURLOPT_COOKIE, request->cookie);
326
327         /* The connection timeout is 30s. (default) */
328         curl_easy_setopt(transaction->easy_handle, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
329
330         if (transaction->timeout > 0) {
331                 curl_easy_setopt(transaction->easy_handle, CURLOPT_TIMEOUT, transaction->timeout);
332         } else if (transaction->timeout == 0) {
333                 /* Set the transaction timeout. The timeout includes connection timeout. */
334                 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_LIMIT, 1L);
335                 curl_easy_setopt(transaction->easy_handle, CURLOPT_LOW_SPEED_TIME, 30L);
336         }
337
338         if (!transaction->verify_peer) {
339                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 0);
340                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 0);
341
342         } else {
343                 curl_easy_setopt(transaction->easy_handle, CURLOPT_CAPATH, transaction->ca_path);
344                 DBG("CA path is (%s)", transaction->ca_path);
345                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYPEER, 1L);
346                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_VERIFYHOST, 2L);
347                 curl_easy_setopt(transaction->easy_handle, CURLOPT_SSL_CIPHER_LIST, "HIGH");
348         }
349
350         if (session->auto_redirect) {
351                 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
352                 curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
353                 DBG("Enabled Auto-Redirection\n");
354         } else {
355                 curl_easy_setopt(transaction->easy_handle, CURLOPT_FOLLOWLOCATION, 0L);
356                 DBG("Disabled Auto-Redirection\n");
357         }
358
359         //LCOV_EXCL_START
360         /* Authentication */
361         if (transaction->auth_required) {
362
363                 curl_http_auth_scheme_e curl_auth_scheme;
364                 gchar *user_name = NULL;
365                 gchar *password = NULL;
366                 gchar *credentials = NULL;
367                 int credentials_len = 0;
368
369                 ret = http_transaction_get_credentials(transaction, &user_name, &password);
370                 if (ret != HTTP_ERROR_NONE)
371                         return ret;
372
373                 credentials_len = sizeof(gchar) * (strlen(user_name) + 1 + strlen(password) + 1);
374                 credentials = (gchar *)malloc(credentials_len);
375                 if (credentials) {
376                         snprintf(credentials, credentials_len, "%s:%s", (gchar*)user_name, (gchar*)password);
377
378                         http_transaction_get_http_auth_scheme(transaction, &auth_scheme);
379
380                         curl_auth_scheme = _get_http_curl_auth_scheme(auth_scheme);
381
382                         if (transaction->proxy_auth_type) {
383                                 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXYAUTH, curl_auth_scheme);
384                                 curl_easy_setopt(transaction->easy_handle, CURLOPT_PROXYUSERPWD, credentials);
385
386                         } else {
387                                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPAUTH, curl_auth_scheme);
388                                 curl_easy_setopt(transaction->easy_handle, CURLOPT_USERPWD, credentials);
389                         }
390                         free(credentials);
391                 }
392                 free(user_name);
393                 free(password);
394         }
395         //LCOV_EXCL_STOP
396
397         if (transaction->tcp_fastopen)
398                 curl_easy_setopt(transaction->easy_handle, CURLOPT_TCP_FASTOPEN, 1L);
399
400         curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERFUNCTION, __handle_header_cb);
401         curl_easy_setopt(transaction->easy_handle, CURLOPT_HEADERDATA, transaction);
402
403         curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEFUNCTION, __handle_body_cb);
404         curl_easy_setopt(transaction->easy_handle, CURLOPT_WRITEDATA, transaction);
405
406         if (http_transaction_header_get_field_value(transaction, "Content-Length", &field_value) == HTTP_ERROR_NONE) {
407                 content_len = atoi(field_value);
408                 if (content_len > 0) {
409                         curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
410                         DBG("Set the Content-Length(%d).", content_len);
411                 } else if (content_len == 0) {
412                         curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)(content_len));
413                         curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, NULL);
414                         DBG("Set the Content-Length(%d).", content_len);
415                 }
416                 free(field_value);
417         } else {
418                 DBG("The Content-Length is not set.\n");
419         }
420
421         _get_request_body_size(transaction, &body_size);
422
423         /* Setup for POST method */
424         if (transaction->write_event)
425                 write_event = TRUE;
426
427         DBG("The write_event[%d/%d] formpost[%d] upload_event[%d]\n",
428                         transaction->write_event,
429                         write_event, (request->formpost) ? 1 : 0,
430                         transaction->upload_event);
431
432         if ((_get_method(request->method) == HTTP_METHOD_POST) && !write_event && !request->formpost) {
433                 gchar *body = NULL;
434
435                 ret = _read_request_body(transaction, &body);
436                 if (ret != HTTP_ERROR_NONE) {
437                         g_free(body);
438                         return ret;
439                 }
440
441                 if (body) {
442                         curl_easy_setopt(transaction->easy_handle, CURLOPT_COPYPOSTFIELDS, body);
443                         free(body);
444                 }
445         }
446
447         if (write_event) {
448                 curl_easy_setopt(transaction->easy_handle, CURLOPT_POST, 1);
449                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READFUNCTION, __handle_write_cb);
450                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READDATA, transaction);
451         }
452
453         /* Mulipart POST */
454         if (request->formpost)
455                 curl_easy_setopt(transaction->easy_handle, CURLOPT_HTTPPOST, request->formpost);
456
457         /* Setup for PUT method */
458         if (transaction->upload_event) {
459                 if (_open_upload_file(transaction) != HTTP_ERROR_NONE)
460                         return CURLM_INTERNAL_ERROR;
461
462                 curl_easy_setopt(transaction->easy_handle, CURLOPT_UPLOAD, 1L);
463                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READFUNCTION, __handle_upload_cb);
464                 curl_easy_setopt(transaction->easy_handle, CURLOPT_READDATA, transaction);
465                 curl_easy_setopt(transaction->easy_handle, CURLOPT_INFILESIZE_LARGE, _get_upload_file_size(transaction));
466         }
467
468         curl_easy_setopt(transaction->easy_handle, CURLOPT_NOPROGRESS, FALSE);
469         curl_easy_setopt(transaction->easy_handle, CURLOPT_PROGRESSFUNCTION, __progress_cb);
470         curl_easy_setopt(transaction->easy_handle, CURLOPT_PROGRESSDATA, transaction);
471
472         curl_easy_setopt(transaction->easy_handle, CURLOPT_VERBOSE, 1L);
473         curl_easy_setopt(transaction->easy_handle, CURLOPT_DEBUGFUNCTION, __http_debug_received);
474         curl_easy_setopt(transaction->easy_handle, CURLOPT_ERRORBUFFER, transaction->error);
475
476         curl_easy_setopt(transaction->easy_handle, CURLOPT_PRIVATE, transaction);
477
478         ret = curl_multi_add_handle(session->multi_handle, transaction->easy_handle);
479         if (ret == CURLM_OK) {
480                 DBG("CURLM_OK: Called curl_multi_add_handle().");
481         } else {
482                 print_curl_multi_errorCode(ret);
483                 ERR("Failed to add easy_handle to curl_multi_add_handle()");
484         }
485
486         ret = curl_multi_perform(session->multi_handle, &session->still_running);
487         if (ret == CURLM_OK) {
488                 _http_transaction_start_timer(5, curl_request_check, transaction);
489         } else {
490                 print_curl_multi_errorCode(ret);
491                 ret = HTTP_ERROR_OPERATION_FAILED;
492         }
493
494         return ret;
495 }
496
497 API int http_session_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction)
498 {
499         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION, "http isn't initialized");
500         _retvm_if(http_session == NULL, HTTP_ERROR_INVALID_PARAMETER, "parameter(http_session) is NULL\n");
501
502         __http_transaction_h *transaction = NULL;
503
504         transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
505         if (transaction == NULL) {
506                 ERR("Fail to allocate transaction memory!!");
507                 return HTTP_ERROR_OUT_OF_MEMORY;
508         }
509
510         transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
511         if (transaction->request == NULL) {
512                 ERR("Fail to allocate request memory!!");
513                 free(transaction);
514                 return HTTP_ERROR_OUT_OF_MEMORY;
515         }
516
517         transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
518         if (transaction->response == NULL) {
519                 ERR("Fail to allocate response memory!!");
520                 free(transaction->request);
521                 free(transaction);
522                 return HTTP_ERROR_OUT_OF_MEMORY;
523         }
524
525         transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
526         if (transaction->header == NULL) {
527                 ERR("Fail to allocate header memory!!");
528                 free(transaction->response);
529                 free(transaction->request);
530                 free(transaction);
531                 return HTTP_ERROR_OUT_OF_MEMORY;
532         }
533
534         transaction->easy_handle = NULL;
535         transaction->timer_event = 0;
536         transaction->interface_name = NULL;
537         transaction->timeout = 0;
538         transaction->write_event = 0;
539         transaction->upload_event = FALSE;
540         transaction->verify_peer = TRUE;
541         transaction->ca_path = g_strdup(HTTP_DEFAULT_CA_PATH);
542         transaction->tcp_fastopen = 0;
543         transaction->error[0] = '\0';
544         transaction->cancel = 0;
545
546         transaction->auth_required = FALSE;
547         transaction->realm = NULL;
548         transaction->user_name = NULL;
549         transaction->password = NULL;
550         transaction->proxy_auth_type = FALSE;
551         transaction->auth_scheme = HTTP_AUTH_NONE;
552
553         transaction->header_cb = NULL;
554         transaction->body_cb = NULL;
555         transaction->write_cb = NULL;
556         transaction->completed_cb = NULL;
557         transaction->aborted_cb = NULL;
558         transaction->progress_cb = NULL;
559
560         transaction->session = http_session;
561         transaction->session->active_transaction_count++;
562
563         /* Header */
564         transaction->header->rsp_header_len = 0;
565         transaction->header->rsp_header = malloc(transaction->header->rsp_header_len + 1);
566         if (transaction->header->rsp_header)
567                 transaction->header->rsp_header[0] = '\0';
568         transaction->header->header_list = NULL;
569         transaction->header->hash_table = NULL;
570         transaction->header_event = FALSE;
571
572         /* Request */
573         transaction->request->host_uri = NULL;
574         transaction->request->method = _get_http_method(method);
575         if (method == HTTP_METHOD_PUT)
576                 transaction->upload_event = TRUE;
577         else
578                 transaction->upload_event = FALSE;
579
580         transaction->request->encoding = NULL;
581         transaction->request->cookie = NULL;
582         transaction->request->http_version = HTTP_VERSION_1_1;
583         transaction->request->body_queue = g_queue_new();
584         transaction->request->tot_size = 0;
585         transaction->request->upload_size = 0;
586         transaction->request->upload_file = NULL;
587         transaction->request->fp = NULL;
588         transaction->request->formpost = NULL;
589         transaction->request->lastptr = NULL;
590
591         /* Response */
592         transaction->response->status_text = NULL;
593
594         *http_transaction = (http_transaction_h)transaction;
595         _add_transaction_to_list(transaction);
596
597         return HTTP_ERROR_NONE;
598 }
599
600 API int http_transaction_submit(http_transaction_h http_transaction)
601 {
602         _retvm_if(_http_check_permission(HTTP_PRIVILEGE_INTERNET) == false,
603                         HTTP_ERROR_PERMISSION_DENIED, "Permission denied");
604         _retvm_if(_http_check_permission(HTTP_PRIVILEGE_NETWORK_GET) == false,
605                         HTTP_ERROR_PERMISSION_DENIED, "Permission denied");
606         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
607                         "http isn't initialized");
608         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
609                         "parameter(http_transaction) is NULL");
610
611         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
612
613         _retvm_if(transaction->request->host_uri == NULL, HTTP_ERROR_INVALID_OPERATION, "URI isn't set!!");
614
615         int ret = HTTP_ERROR_NONE;
616
617         if (_transaction_submit(transaction) != CURLM_OK)
618                 ret = HTTP_ERROR_OPERATION_FAILED;
619
620         return ret;
621 }
622
623 API int http_transaction_destroy(http_transaction_h http_transaction)
624 {
625         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
626                         "http isn't initialized");
627         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
628                         "parameter(http_transaction) is NULL\n");
629
630         __http_transaction_h *transaction = NULL;
631         __http_session_h *session = NULL;
632         __http_header_h *header = NULL;
633         __http_request_h *request = NULL;
634         __http_response_h *response = NULL;
635
636         transaction = (__http_transaction_h *)http_transaction;
637         session = transaction->session;
638         request = transaction->request;
639         response = transaction->response;
640         header = transaction->header;
641
642         if (session)
643                 session->active_transaction_count--;
644
645         if (transaction) {
646                 if (transaction->easy_handle != NULL) {
647                         curl_easy_cleanup(transaction->easy_handle);
648                         transaction->easy_handle = NULL;
649                 }
650
651                 if (transaction->interface_name != NULL) {
652                         free(transaction->interface_name);
653                         transaction->interface_name = NULL;
654                 }
655
656                 if (transaction->timer_event) {
657                         g_source_remove(transaction->timer_event);
658                         transaction->timer_event = 0;
659                 }
660
661                 transaction->timeout = 0;
662                 transaction->verify_peer = 0;
663                 transaction->tcp_fastopen = 0;
664
665                 if (transaction->ca_path) {
666                         free(transaction->ca_path);
667                         transaction->ca_path = NULL;
668                 }
669                 transaction->error[0] = '\0';
670
671                 if (transaction->user_name) {
672                         free(transaction->user_name);
673                         transaction->user_name = NULL;
674                 }
675
676                 if (transaction->password) {
677                         free(transaction->password);
678                         transaction->password = NULL;
679                 }
680
681                 if (transaction->realm) {
682                         free(transaction->realm);
683                         transaction->realm = NULL;
684                 }
685
686                 transaction->auth_required = FALSE;
687                 transaction->proxy_auth_type = FALSE;
688                 transaction->auth_scheme = HTTP_AUTH_NONE;
689
690                 transaction->progress_cb = NULL;
691                 transaction->header_cb = NULL;
692                 transaction->body_cb = NULL;
693                 transaction->write_cb = NULL;
694                 transaction->completed_cb = NULL;
695                 transaction->aborted_cb = NULL;
696
697                 transaction->progress_user_data = NULL;
698                 transaction->header_user_data = NULL;
699                 transaction->body_user_data = NULL;
700                 transaction->write_user_data = NULL;
701                 transaction->completed_user_data = NULL;
702                 transaction->aborted_user_data = NULL;
703
704                 if (request) {
705                         if (request->host_uri != NULL) {
706                                 free(request->host_uri);
707                                 request->host_uri = NULL;
708                         }
709
710                         if (request->method != NULL) {
711                                 free(request->method);
712                                 request->method = NULL;
713                         }
714
715                         if (request->encoding != NULL) {
716                                 free(request->encoding);
717                                 request->encoding = NULL;
718                         }
719
720                         if (request->cookie != NULL) {
721                                 free(request->cookie);
722                                 request->cookie = NULL;
723                         }
724
725                         if (request->body_queue != NULL)
726                                 g_queue_free(request->body_queue);
727
728                         if (request->formpost) {
729                                 curl_formfree(request->formpost);
730                                 request->formpost = NULL;
731                         }
732
733                         if (request->upload_file != NULL) {
734                                 free(request->upload_file);
735                                 request->upload_file = NULL;
736                         }
737
738                         free(request);
739                 }
740
741                 if (response) {
742                         if (response->status_text != NULL) {
743                                 free(response->status_text);
744                                 response->status_text = NULL;
745                         }
746                         free(response);
747                 }
748
749                 if (header) {
750                         if (header->header_list != NULL) {
751                                 curl_slist_free_all(header->header_list);
752                                 header->header_list = NULL;
753                         }
754
755                         if (header->hash_table != NULL) {
756                                 g_hash_table_remove_all(header->hash_table);
757                                 g_hash_table_destroy(header->hash_table);
758                                 header->hash_table = NULL;
759                         }
760
761                         if (header->rsp_header != NULL) {
762                                 free(header->rsp_header);
763                                 header->rsp_header = NULL;
764                                 header->rsp_header_len = 0;
765                         }
766                         free(header);
767                 }
768
769                 _remove_transaction_from_list(transaction);
770
771                 transaction->session = NULL;
772                 transaction->request = NULL;
773                 transaction->response = NULL;
774                 transaction->header = NULL;
775
776                 free(transaction);
777                 transaction = NULL;
778         }
779
780         return HTTP_ERROR_NONE;
781 }
782
783 //LCOV_EXCL_START
784 API int http_transaction_pause(http_transaction_h http_transaction, http_pause_type_e pause_type)
785 {
786         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
787                         "http isn't initialized");
788         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
789                         "parameter(http_transaction) is NULL\n");
790         _retvm_if(pause_type < HTTP_PAUSE_RECV || pause_type > HTTP_PAUSE_ALL, HTTP_ERROR_INVALID_PARAMETER,
791                         "Wrong pause state \n");
792
793         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
794         int ret = 0;
795
796         ret = curl_easy_pause(transaction->easy_handle, pause_type);
797         if (ret != 0) {
798                 ERR("Fail to pause!(%d)", ret);
799                 return HTTP_ERROR_OPERATION_FAILED;
800         }
801
802         return HTTP_ERROR_NONE;
803 }
804
805 API int http_transaction_resume(http_transaction_h http_transaction)
806 {
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
812         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
813         int ret = 0;
814
815         ret = curl_easy_pause(transaction->easy_handle, CURLPAUSE_CONT);
816         if (ret != 0) {
817                 ERR("Fail to resume!(%d)", ret);
818                 return HTTP_ERROR_OPERATION_FAILED;
819         }
820
821         return HTTP_ERROR_NONE;
822 }
823 //LCOV_EXCL_STOP
824
825 API int http_transaction_cancel(http_transaction_h http_transaction)
826 {
827         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
828                         "http isn't initialized");
829         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
830                         "parameter(http_transaction) is NULL\n");
831
832         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
833
834         transaction->cancel = true;
835
836         return HTTP_ERROR_NONE;
837 }
838
839 API int http_transaction_set_progress_cb(http_transaction_h http_transaction, http_transaction_progress_cb progress_cb, void* user_data)
840 {
841         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
842                         "http isn't initialized");
843         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
844                         "parameter(http_transaction) is NULL\n");
845         _retvm_if(progress_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
846                         "parameter(progress_cb) is NULL\n");
847
848         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
849
850         transaction->progress_cb = progress_cb;
851         transaction->progress_user_data = user_data;
852
853         return HTTP_ERROR_NONE;
854 }
855
856 API int http_transaction_set_received_header_cb(http_transaction_h http_transaction, http_transaction_header_cb header_cb, void* user_data)
857 {
858         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
859                         "http isn't initialized");
860         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
861                         "parameter(http_transaction) is NULL\n");
862         _retvm_if(header_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
863                         "parameter(header_cb) is NULL\n");
864
865         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
866
867         transaction->header_cb = header_cb;
868         transaction->header_user_data = user_data;
869
870         return HTTP_ERROR_NONE;
871 }
872
873 API int http_transaction_set_received_body_cb(http_transaction_h http_transaction, http_transaction_body_cb body_cb, void* user_data)
874 {
875         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
876                         "http isn't initialized");
877         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
878                         "parameter(http_transaction) is NULL\n");
879         _retvm_if(body_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
880                         "parameter(body_cb) is NULL\n");
881
882         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
883
884         transaction->body_cb = body_cb;
885         transaction->body_user_data = user_data;
886
887         return HTTP_ERROR_NONE;
888 }
889
890 API int http_transaction_set_uploaded_cb(http_transaction_h http_transaction, http_transaction_write_cb write_cb, void* user_data)
891 {
892         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
893                         "http isn't initialized");
894         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
895                         "parameter(http_transaction) is NULL\n");
896         _retvm_if(write_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
897                         "parameter(write_cb) is NULL\n");
898
899         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
900
901         transaction->write_cb = write_cb;
902         transaction->write_user_data = user_data;
903
904         return HTTP_ERROR_NONE;
905 }
906
907 API int http_transaction_set_completed_cb(http_transaction_h http_transaction, http_transaction_completed_cb completed_cb, void* user_data)
908 {
909         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
910                         "http isn't initialized");
911         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
912                         "parameter(http_transaction) is NULL\n");
913         _retvm_if(completed_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
914                         "parameter(completed_cb) is NULL\n");
915
916         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
917
918         transaction->completed_cb = completed_cb;
919         transaction->completed_user_data = user_data;
920
921         return HTTP_ERROR_NONE;
922 }
923
924 API int http_transaction_set_aborted_cb(http_transaction_h http_transaction, http_transaction_aborted_cb aborted_cb,  void* user_data)
925 {
926         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
927                         "http isn't initialized");
928         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
929                          "parameter(http_transaction) is NULL\n");
930         _retvm_if(aborted_cb == NULL, HTTP_ERROR_INVALID_PARAMETER,
931                         "parameter(aborted_cb) is NULL\n");
932
933         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
934
935         transaction->aborted_cb = aborted_cb;
936         transaction->aborted_user_data = user_data;
937
938         return HTTP_ERROR_NONE;
939 }
940
941 API int http_transaction_set_timeout(http_transaction_h http_transaction, int timeout)
942 {
943         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
944                         "http isn't initialized");
945         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
946                         "parameter(http_transaction) is NULL\n");
947
948         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
949
950         transaction->timeout = timeout;
951
952         return HTTP_ERROR_NONE;
953 }
954
955 API int http_transaction_get_timeout(http_transaction_h http_transaction, int *timeout)
956 {
957         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
958                         "http isn't initialized");
959         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
960                         "parameter(http_transaction) is NULL\n");
961         _retvm_if(timeout == NULL, HTTP_ERROR_INVALID_PARAMETER,
962                         "parameter(timeout) is NULL\n");
963
964         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
965
966         *timeout =  transaction->timeout;
967
968         return HTTP_ERROR_NONE;
969 }
970
971 API int http_transaction_set_interface_name(http_transaction_h http_transaction, const char *interface_name)
972 {
973         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
974                         "http isn't initialized");
975         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
976                         "parameter(http_transaction) is NULL\n");
977         _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
978                         "parameter(interface_name) is NULL\n");
979
980         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
981
982         transaction->interface_name = g_strdup(interface_name);
983
984         return HTTP_ERROR_NONE;
985 }
986
987 API int http_transaction_get_interface_name(http_transaction_h http_transaction, char **interface_name)
988 {
989         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
990                         "http isn't initialized");
991         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
992                         "parameter(http_transaction) is NULL\n");
993         _retvm_if(interface_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
994                         "parameter(interface_name) is NULL\n");
995
996         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
997
998         *interface_name = g_strdup(transaction->interface_name);
999         if (*interface_name == NULL) {
1000                 ERR("strdup is failed\n");
1001                 return HTTP_ERROR_OUT_OF_MEMORY;
1002         }
1003
1004         return HTTP_ERROR_NONE;
1005 }
1006
1007 API int http_transaction_set_ready_to_write(http_transaction_h http_transaction, bool read_to_write)
1008 {
1009         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
1010                         "http isn't initialized");
1011         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1012                         "parameter(http_transaction) is NULL\n");
1013
1014         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1015
1016         transaction->write_event = read_to_write;
1017
1018         return HTTP_ERROR_NONE;
1019 }
1020
1021 API int http_transaction_get_server_certificate_verification(http_transaction_h http_transaction, bool* verify)
1022 {
1023         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
1024                         "http isn't initialized");
1025         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1026                         "parameter(http_transaction) is NULL\n");
1027
1028         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1029
1030         *verify = transaction->verify_peer;
1031
1032         return HTTP_ERROR_NONE;
1033 }
1034
1035 API int http_transaction_set_server_certificate_verification(http_transaction_h http_transaction, bool verify)
1036 {
1037         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
1038                         "http isn't initialized");
1039         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1040                         "parameter(http_transaction) is NULL\n");
1041
1042         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1043
1044         transaction->verify_peer = verify;
1045
1046         return HTTP_ERROR_NONE;
1047 }
1048
1049 API int http_transaction_get_tcp_fastopen(http_transaction_h http_transaction, bool *enable)
1050 {
1051         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
1052                         "http isn't initialized");
1053         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1054                         "parameter(http_transaction) is NULL\n");
1055
1056 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
1057         return HTTP_ERROR_NOT_SUPPORTED;
1058 #else
1059         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1060         *enable = transaction->tcp_fastopen;
1061         return HTTP_ERROR_NONE;
1062 #endif
1063 }
1064
1065 API int http_transaction_set_tcp_fastopen(http_transaction_h http_transaction, bool enable)
1066 {
1067         _retvm_if(_http_is_init() == false, HTTP_ERROR_INVALID_OPERATION,
1068                         "http isn't initialized");
1069         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1070                         "parameter(http_transaction) is NULL\n");
1071
1072 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
1073         return HTTP_ERROR_NOT_SUPPORTED;
1074 #else
1075         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1076         transaction->tcp_fastopen = enable;
1077         return HTTP_ERROR_NONE;
1078 #endif
1079 }
1080
1081 //LCOV_EXCL_START
1082 API int http_transaction_set_http_auth_scheme(http_transaction_h http_transaction, http_auth_scheme_e auth_scheme)
1083 {
1084         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1085                         "parameter(http_transaction) is NULL\n");
1086
1087         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1088
1089         transaction->auth_scheme = auth_scheme;
1090
1091         return HTTP_ERROR_NONE;
1092 }
1093
1094 API int http_transaction_get_http_auth_scheme(http_transaction_h http_transaction, http_auth_scheme_e *auth_scheme)
1095 {
1096         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1097                         "parameter(http_transaction) is NULL\n");
1098         _retvm_if(auth_scheme == NULL, HTTP_ERROR_INVALID_PARAMETER,
1099                         "parameter(auth_scheme) is NULL\n");
1100
1101         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1102
1103         *auth_scheme =  transaction->auth_scheme;
1104
1105         return HTTP_ERROR_NONE;
1106 }
1107
1108 API int http_transaction_get_realm(http_transaction_h http_transaction, char **realm)
1109 {
1110         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1111                         "parameter(http_transaction) is NULL\n");
1112         _retvm_if(realm == NULL, HTTP_ERROR_INVALID_PARAMETER,
1113                         "parameter(realm) is NULL\n");
1114
1115         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1116
1117         if (transaction->realm == NULL)
1118                 return HTTP_ERROR_INVALID_OPERATION;
1119
1120         *realm = g_strdup(transaction->realm);
1121         if (*realm == NULL) {
1122                 ERR("strdup is failed\n");
1123                 return HTTP_ERROR_OUT_OF_MEMORY;
1124         }
1125
1126         return HTTP_ERROR_NONE;
1127 }
1128
1129 API int http_transaction_set_credentials(http_transaction_h http_transaction, const char *user_name, const char *password)
1130 {
1131         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1132                         "parameter(http_transaction) is NULL\n");
1133         _retvm_if(user_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
1134                         "parameter(user_name) is NULL\n");
1135         _retvm_if(password == NULL, HTTP_ERROR_INVALID_PARAMETER,
1136                         "parameter(password) is NULL\n");
1137
1138         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1139
1140         transaction->user_name = g_strdup(user_name);
1141         transaction->password = g_strdup(password);
1142
1143         return HTTP_ERROR_NONE;
1144 }
1145
1146 API int http_transaction_get_credentials(http_transaction_h http_transaction, char **user_name, char **password)
1147 {
1148         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1149                         "parameter(http_transaction) is NULL\n");
1150         _retvm_if(user_name == NULL, HTTP_ERROR_INVALID_PARAMETER,
1151                         "parameter(user_name) is NULL\n");
1152         _retvm_if(password == NULL, HTTP_ERROR_INVALID_PARAMETER,
1153                         "parameter(password) is NULL\n");
1154
1155         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1156
1157         *user_name = g_strdup(transaction->user_name);
1158         if (*user_name == NULL) {
1159                 ERR("strdup is failed\n");
1160                 return HTTP_ERROR_OUT_OF_MEMORY;
1161         }
1162
1163         *password = g_strdup(transaction->password);
1164         if (*password == NULL) {
1165                 ERR("strdup is failed\n");
1166                 g_free(*user_name);
1167                 *user_name = NULL;
1168                 return HTTP_ERROR_OUT_OF_MEMORY;
1169         }
1170         return HTTP_ERROR_NONE;
1171 }
1172
1173 API int http_transaction_open_authentication(http_transaction_h http_transaction, http_transaction_h *http_auth_transaction)
1174 {
1175         _retvm_if(http_transaction == NULL, HTTP_ERROR_INVALID_PARAMETER,
1176                         "parameter(http_transaction) is NULL\n");
1177
1178         __http_transaction_h *transaction = (__http_transaction_h *)http_transaction;
1179         __http_transaction_h *auth_transaction = NULL;
1180
1181         auth_transaction = (__http_transaction_h *)malloc(sizeof(__http_transaction_h));
1182         if (auth_transaction == NULL) {
1183                 ERR("Fail to allocate transaction memory!!");
1184                 return HTTP_ERROR_OUT_OF_MEMORY;
1185         }
1186
1187         auth_transaction->easy_handle = NULL;
1188         auth_transaction->timer_event = 0;
1189         auth_transaction->interface_name = NULL;
1190         auth_transaction->ca_path = NULL;
1191         auth_transaction->error[0] = '\0';
1192
1193         if (transaction->interface_name)
1194                 auth_transaction->interface_name = g_strdup(transaction->interface_name);
1195         auth_transaction->timeout = 0;
1196         auth_transaction->verify_peer = transaction->verify_peer;
1197         if (transaction->ca_path)
1198                 auth_transaction->ca_path = g_strdup(transaction->ca_path);
1199
1200         auth_transaction->auth_required = transaction->auth_required;
1201         auth_transaction->user_name = NULL;
1202         auth_transaction->password = NULL;
1203         auth_transaction->proxy_auth_type = FALSE;
1204         auth_transaction->auth_scheme = transaction->auth_scheme;
1205         if (transaction->realm)
1206                 auth_transaction->realm = g_strdup(transaction->realm);
1207
1208         auth_transaction->write_event = FALSE;
1209         auth_transaction->upload_event = FALSE;
1210
1211         auth_transaction->header_cb = NULL;
1212         auth_transaction->header_user_data = NULL;
1213         auth_transaction->body_cb = NULL;
1214         auth_transaction->body_user_data = NULL;
1215         auth_transaction->write_cb = NULL;
1216         auth_transaction->write_user_data = NULL;
1217         auth_transaction->completed_cb = NULL;
1218         auth_transaction->completed_user_data = NULL;
1219         auth_transaction->aborted_cb = NULL;
1220         auth_transaction->progress_cb = NULL;
1221         auth_transaction->progress_user_data = NULL;
1222
1223         auth_transaction->session = transaction->session;
1224         auth_transaction->session->active_transaction_count = transaction->session->active_transaction_count;
1225
1226         auth_transaction->request = (__http_request_h *)malloc(sizeof(__http_request_h));
1227         if (auth_transaction->request == NULL) {
1228                 g_free(auth_transaction->interface_name);
1229                 g_free(auth_transaction->ca_path);
1230                 g_free(auth_transaction->realm);
1231                 free(auth_transaction);
1232                 ERR("Fail to allocate request memory!!");
1233                 return HTTP_ERROR_OUT_OF_MEMORY;
1234         }
1235
1236         auth_transaction->request->host_uri = NULL;
1237         auth_transaction->request->method = NULL;
1238
1239         auth_transaction->response = (__http_response_h *)malloc(sizeof(__http_response_h));
1240         if (auth_transaction->response == NULL) {
1241                 g_free(auth_transaction->interface_name);
1242                 g_free(auth_transaction->ca_path);
1243                 g_free(auth_transaction->realm);
1244                 free(auth_transaction->request);
1245                 free(auth_transaction);
1246                 ERR("Fail to allocate response memory!!");
1247                 return HTTP_ERROR_OUT_OF_MEMORY;
1248         }
1249
1250         auth_transaction->header = (__http_header_h *)malloc(sizeof(__http_header_h));
1251         if (auth_transaction->header == NULL) {
1252                 g_free(auth_transaction->interface_name);
1253                 g_free(auth_transaction->ca_path);
1254                 g_free(auth_transaction->realm);
1255                 free(auth_transaction->request);
1256                 free(auth_transaction->response);
1257                 free(auth_transaction);
1258                 ERR("Fail to allocate header memory!!");
1259                 return HTTP_ERROR_OUT_OF_MEMORY;
1260         }
1261
1262         auth_transaction->header->rsp_header_len = 0;
1263         auth_transaction->header->rsp_header = malloc(auth_transaction->header->rsp_header_len + 1);
1264         if (auth_transaction->header->rsp_header)
1265                 auth_transaction->header->rsp_header[0] = '\0';
1266         auth_transaction->header_event = FALSE;
1267
1268         if (transaction->request->host_uri)
1269                 auth_transaction->request->host_uri = g_strdup(transaction->request->host_uri);
1270         if (transaction->request->method)
1271                 auth_transaction->request->method = g_strdup(transaction->request->method);
1272         auth_transaction->request->encoding = NULL;
1273         auth_transaction->request->cookie = NULL;
1274         auth_transaction->request->http_version = HTTP_VERSION_1_1;
1275         auth_transaction->request->body_queue = g_queue_new();
1276         auth_transaction->request->tot_size = 0;
1277
1278         auth_transaction->header->header_list = NULL;
1279         auth_transaction->header->hash_table = NULL;
1280
1281         *http_auth_transaction = (http_transaction_h)auth_transaction;
1282         _add_transaction_to_list(auth_transaction);
1283
1284         return HTTP_ERROR_NONE;
1285 }
1286 //LCOV_EXCL_STOP