[Internal: merge sync-agent]
[platform/core/system/sync-agent.git] / src / fw-plugins / common-public / http / src / plugin_interface.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <glib/gprintf.h>
23
24 //#define USING_LIBSOUP
25 /* #define time_check */
26 //#define CBA
27
28 #ifdef USING_LIBSOUP
29 #include <libsoup/soup-uri.h>
30 #include <libsoup/soup.h>
31 #else
32 #include <curl/curl.h>
33 #include <ctype.h>
34 #endif
35
36 #include <time.h>
37
38 //#include <dlog.h>
39
40 #include "na_external.h"
41 #include "http_status.h"
42
43 /* for log */
44 #include "utility/sync_util.h"
45
46 #include "plugin/network_access_interface.h"
47
48 #ifdef CBA
49 #include <openssl/ssl.h>
50 #include <errno.h>
51 #endif
52
53 #define SEMI_COLON_LEN                  1
54 #define NULL_LEN                                                1
55
56 #ifndef EXPORT_API
57 #define EXPORT_API __attribute__ ((visibility("default")))
58 #endif
59
60 #ifndef SYNC_AGENT_LOG
61 #undef LOG_TAG
62 #define LOG_TAG "PLUGIN_NA_HTTP"
63 #endif
64
65 #ifdef USING_LIBSOUP
66 typedef struct {
67         SoupSession *session;
68         CURL *session;
69         char *id;
70         char *password;
71 } auth_info_s;
72
73 static int _add_auth_info(SoupSession * session, char *user_id, char *user_pw);
74                                                                                                                                                                      /*static int remove_auth_info(SoupSession *session); *//*      not used        */
75 static int _find_auth_info(SoupSession * session, auth_info_s ** auth_info);
76 static void authenticate_cb(SoupSession * session, SoupMessage * msg, SoupAuth * auth, gboolean retrying, gpointer user_data);
77
78 static GList *auth_info_list = NULL;
79 #else
80 typedef enum {
81         LIBCURL_HTTP_GET = 0,
82         LIBCURL_HTTP_PUT,
83         LIBCURL_HTTP_POST,
84         LIBCURL_HTTP_TRACE,
85         LIBCURL_HTTP_CONNECT,
86         LIBCURL_HTTP_HEAD,
87         LIBCURL_HTTP_DELETE,
88         LIBCURL_HTTP_OPTIONS
89 } libcurl_http_method_e;
90
91 typedef struct {
92         char *buff;
93         int length;
94         int block_size;
95 } http_buffer_s;
96
97 #ifdef CBA
98 typedef struct {
99         int accept_all_certs;
100         char *privatekey_password;
101         char *certificate_path;
102         unsigned char *privatekey;
103 } certificate_info_s;
104 #endif
105
106 typedef struct {
107         libcurl_http_method_e method;
108         char *uri;
109         char *accept_encoding;
110         struct curl_slist *send_header;
111         http_buffer_s *response_header;
112         http_buffer_s *response_body;
113         int http_status;
114         int abort;
115         void *session;
116 #ifdef CBA
117         certificate_info_s *cert_info;
118 #endif
119 } http_message_s;
120
121 typedef struct {
122         CURL *session;
123         http_message_s *msg;
124 } curl_session_s;
125
126 #define HEADER_BLOCK_SIZE               (1024)
127 #define CONTENT_BLOCK_SIZE              (16*1024)
128
129 static int curl_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
130
131 static int _curl_session_abort(curl_session_s * session);
132
133 static http_buffer_s *__create_http_buffer(int block_size);
134 static int __delete_http_buffer(http_buffer_s * buff);
135 static size_t write_http_buffer_cb(void *ptr, size_t size, size_t nmemb, void *userdata);
136
137 #ifdef CBA
138 static http_message_s *_create_http_message(libcurl_http_method_e method, char *uri, char *accept_encoding, int is_cert);
139 #else
140 static http_message_s *_create_http_message(libcurl_http_method_e method, char *uri, char *accept_encoding);
141 #endif
142
143 static int _add_http_header(http_message_s * msg, char *key, char *value);
144 static int _delete_http_message(http_message_s * msg);
145
146 static int _parse_http_header(http_buffer_s * header, GList ** header_list);
147
148 static common_header_info_s *__create_header_info(char *key, char *value);
149
150 #ifdef CBA
151 static void _add_certificate_option(CURL * curl, http_message_s * msg);
152 static CURLcode ssl_context_cb(CURL * curl, SSL_CTX * sslctx, void *param);
153 static int verify_peer_cb(int preverify_ok, X509_STORE_CTX * x509_ctx);
154 #endif
155
156 #endif
157
158 #ifdef USING_LIBSOUP
159 EXPORT_API int sync_agent_plugin_open_connection(void **session, char *proxy, int timeout)
160 {
161 #ifdef time_check
162         /* function Start Time */
163         clock_t start_t, end_t;
164         double proc_t = 0.0;
165         start_t = clock();
166 #endif
167
168         int res = 1;
169
170         /*
171          *      create session
172          */
173         SoupSession *ss = (SoupSession *) (*session);
174         SoupURI *proxy_uri = NULL;
175
176         _DEBUG_INFO("proxy : %s", proxy);
177
178         /*
179          *      proxy setting
180          */
181         if (proxy != NULL) {
182                 proxy_uri = soup_uri_new(proxy);
183                 ss = soup_session_sync_new_with_options(SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
184         } else {
185                 ss = soup_session_sync_new();
186         }
187
188         g_object_set(ss, SOUP_SESSION_TIMEOUT, timeout, NULL);
189         _DEBUG_INFO("[na_http_plugIn] set timeout : %d", timeout);
190
191         _DEBUG_INFO("[na_http_plugIn] session : %d\n", ss);
192
193         if (ss != NULL) {
194                 _DEBUG_INFO("[na_http_plugIn] success !! \n");
195         } else {
196                 _DEBUG_ERROR("[na_http_plugIn] fail !! \n");
197                 res = 0;
198         }
199
200         *session = ss;
201
202 #ifdef time_check
203         /* function End Time */
204         end_t = clock();
205         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
206         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
207 #endif
208
209         return res;
210 }
211 #else
212 EXPORT_API int sync_agent_plugin_open_connection(void **session, char *proxy, int timeout)
213 {
214         _EXTERN_FUNC_ENTER;
215
216 #ifdef time_check
217         /* function Start Time */
218         clock_t start_t, end_t;
219         double proc_t = 0.0;
220         start_t = clock();
221 #endif
222
223         int res = 1;
224
225         /*
226          *      create session
227          */
228
229         curl_session_s *curl_session = (curl_session_s *) calloc(1, sizeof(curl_session_s));
230         if (curl_session == NULL) {
231                 _DEBUG_ERROR("CALLOC failed !!!");
232                 return 0;
233         }
234         CURL *curl;
235         CURLcode ret;
236
237         _DEBUG_INFO("proxy : %s", proxy);
238
239         /*
240          *      proxy setting
241          */
242         curl = curl_easy_init();
243         if (proxy != NULL) {
244                 if(strncmp(proxy,"http://0.0.0.0", strlen("http://0.0.0.0")) == 0) {
245                 } else {
246                         ret = curl_easy_setopt(curl, CURLOPT_PROXY, proxy);
247                 }
248         }
249
250         ret = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
251         _DEBUG_INFO("[na_http_plugIn] set timeout : %d", timeout);
252
253         _DEBUG_INFO("[na_http_plugIn] session : %d\n", curl);
254
255         if (curl != NULL) {
256                 _DEBUG_INFO("[na_http_plugIn] success !! \n");
257         } else {
258                 _DEBUG_ERROR("[na_http_plugIn] fail !! \n");
259                 res = 0;
260         }
261
262         curl_session->session = curl;
263
264         *session = curl_session;
265
266 #ifdef time_check
267         /* function End Time */
268         end_t = clock();
269         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
270         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
271 #endif
272
273         _EXTERN_FUNC_EXIT;
274
275         return res;
276 }
277 #endif
278
279 EXPORT_API int sync_agent_plugin_header_binding(GList * header_info, void **header_binding)
280 {
281         _EXTERN_FUNC_ENTER;
282
283         retvm_if(header_info == NULL, 0, "header_info is NULL. FAIL !!!");
284
285 #ifdef time_check
286         /* function Start Time */
287         clock_t start_t, end_t;
288         double proc_t = 0.0;
289         start_t = clock();
290 #endif
291
292 #ifdef USING_LIBSOUP
293         int res = 1;
294         GList *iter = NULL;
295         char *method = NULL;
296         char *uri = NULL;
297         common_header_info_s *iter_data = NULL;
298
299         if (header_info == NULL) {
300                 _DEBUG_ERROR("[na_http_plugIn] Error !! ( not exist header information )\n");
301                 res = 0;
302                 return res;
303         }
304
305         SoupMessage *msg = (SoupMessage *) (*header_binding);
306         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", msg);
307
308 #else
309         char *method = NULL;
310         char *uri = NULL;
311 #ifdef CBA
312         char *is_certificate = NULL;
313 #endif
314         char *accept_encoding = "gzip,deflate";
315
316         int res = 1;
317         GList *iter = NULL;
318         http_message_s *msg = NULL;
319         libcurl_http_method_e libcurl_method = LIBCURL_HTTP_GET;
320
321         /*
322          *      add message body to message header
323          */
324         _DEBUG_INFO("[na_http_plugIn] create whole msg (header + body)\n");
325
326         common_header_info_s *iter_data = NULL;
327
328         if (header_info == NULL) {
329                 _DEBUG_ERROR("[na_http_plugIn] Error !! ( not exist header information )\n");
330                 res = 0;
331                 return res;
332         }
333 #endif
334
335         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
336                 if (((common_header_info_s *) (iter->data))->key != NULL) {
337                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "method")) {
338                                 method = ((common_header_info_s *) (iter->data))->value;
339                                 break;
340                         }
341                 }
342         }
343
344         if (iter == NULL) {
345                 _DEBUG_ERROR("[na_http_plugIn] Iteration is NULL\n");
346                 res = 0;
347                 return res;
348         }
349
350         iter_data = (common_header_info_s *) iter->data;
351         header_info = g_list_remove(header_info, iter_data);
352         free((common_header_info_s *) iter_data);
353         _DEBUG_INFO("[na_http_plugIn] method : %s\n", method);
354
355         iter = NULL;
356         iter_data = NULL;
357         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
358                 if (((common_header_info_s *) (iter->data))->key != NULL) {
359                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "uri")) {
360                                 uri = ((common_header_info_s *) (iter->data))->value;
361                                 break;
362                         }
363                 }
364         }
365
366         if (iter == NULL) {
367                 _DEBUG_ERROR("[na_http_plugIn] Iteration is NULL\n");
368                 res = 0;
369                 return res;
370         }
371
372         iter_data = (common_header_info_s *) iter->data;
373         header_info = g_list_remove(header_info, iter_data);
374         free((common_header_info_s *) iter_data);
375         _DEBUG_INFO("[na_http_plugIn] uri : %s\n", uri);
376
377 #ifdef CBA
378         iter = NULL;
379         iter_data = NULL;
380         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
381                 if (((common_header_info_s *) (iter->data))->key != NULL) {
382                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "certificate")) {
383                                 is_certificate = ((common_header_info_s *) (iter->data))->value;
384                                 break;
385                         }
386                 }
387         }
388
389         if (iter == NULL) {
390                 _DEBUG_ERROR("[na_http_plugIn] 'Certificate' is not existed !!");
391         } else {
392                 iter_data = (common_header_info_s *) iter->data;
393                 header_info = g_list_remove(header_info, iter_data);
394                 free((common_header_info_s *) iter_data);
395                 _DEBUG_INFO("[na_http_plugIn] certificate : %s\n", is_certificate);
396         }
397 #endif
398
399 #ifdef USING_LIBSOUP
400         if (!strcmp(method, "options")) {
401                 msg = soup_message_new(SOUP_METHOD_OPTIONS, uri);
402         } else if (!strcmp(method, "get")) {
403                 msg = soup_message_new(SOUP_METHOD_GET, uri);
404         } else if (!strcmp(method, "head")) {
405                 msg = soup_message_new(SOUP_METHOD_HEAD, uri);
406         } else if (!strcmp(method, "post")) {
407                 msg = soup_message_new(SOUP_METHOD_POST, uri);
408         } else if (!strcmp(method, "put")) {
409                 msg = soup_message_new(SOUP_METHOD_PUT, uri);
410         } else if (!strcmp(method, "delete")) {
411                 msg = soup_message_new(SOUP_METHOD_DELETE, uri);
412         } else if (!strcmp(method, "trace")) {
413                 msg = soup_message_new(SOUP_METHOD_TRACE, uri);
414         } else if (!strcmp(method, "connect")) {
415                 msg = soup_message_new(SOUP_METHOD_CONNECT, uri);
416         }
417
418         if (msg == NULL) {
419                 _DEBUG_ERROR("[na_http_plugIn] Error !! ( wrong uri : %s )\n", uri);
420                 res = 0;
421                 return res;
422         }
423 #else
424         iter = NULL;
425         iter_data = NULL;
426         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
427                 if (((common_header_info_s *) (iter->data))->key != NULL) {
428                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "Accept-Encoding")) {
429                                 accept_encoding = ((common_header_info_s *) (iter->data))->value;
430                                 break;
431                         }
432                 }
433         }
434
435         if (iter != NULL) {
436                 iter_data = (common_header_info_s *) iter->data;
437                 header_info = g_list_remove(header_info, iter_data);
438                 free((common_header_info_s *) iter_data);
439                 _DEBUG_INFO("[na_http_plugIn] accept_encoding : %s\n", accept_encoding);
440         }
441
442         if (method != NULL) {
443                 if (!strcmp(method, "options")) {
444                         libcurl_method = LIBCURL_HTTP_OPTIONS;
445                 } else if (!strcmp(method, "get")) {
446                         libcurl_method = LIBCURL_HTTP_GET;
447                 } else if (!strcmp(method, "head")) {
448                         libcurl_method = LIBCURL_HTTP_HEAD;
449                 } else if (!strcmp(method, "post")) {
450                         libcurl_method = LIBCURL_HTTP_POST;
451                 } else if (!strcmp(method, "put")) {
452                         libcurl_method = LIBCURL_HTTP_PUT;
453                 } else if (!strcmp(method, "delete")) {
454                         libcurl_method = LIBCURL_HTTP_DELETE;
455                 } else if (!strcmp(method, "trace")) {
456                         libcurl_method = LIBCURL_HTTP_TRACE;
457                 } else if (!strcmp(method, "connect")) {
458                         libcurl_method = LIBCURL_HTTP_CONNECT;
459                 }
460                 //free(method);
461         }
462         if (uri != NULL) {
463 #ifdef CBA
464                 if (is_certificate != NULL)
465                         msg = _create_http_message(libcurl_method, uri, accept_encoding, atoi(is_certificate));
466                 else
467 #else
468                 msg = _create_http_message(libcurl_method, uri, accept_encoding);
469 #endif
470                 _DEBUG_INFO("[na_http_plugIn] create_http_message(%s)\n", uri);
471
472 #ifdef CBA
473                 if (msg->cert_info != NULL) {
474                         _DEBUG_INFO("[na_http_plugIn] certificate info is existed !!");
475
476                         iter = NULL;
477                         iter_data = NULL;
478                         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
479                                 if (((common_header_info_s *) (iter->data))->key != NULL) {
480                                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "accept_all_certs")) {
481                                                 msg->cert_info->accept_all_certs = strdup(((common_header_info_s *) (iter->data))->value);
482                                                 break;
483                                         }
484                                 }
485                         }
486
487                         if (iter != NULL) {
488                                 iter_data = (common_header_info_s *) iter->data;
489                                 header_info = g_list_remove(header_info, iter_data);
490                                 free((common_header_info_s *) iter_data);
491                                 _DEBUG_INFO("[na_http_plugIn] privatekey password : %s", msg->cert_info->accept_all_certs);
492                         }
493
494                         iter = NULL;
495                         iter_data = NULL;
496                         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
497                                 if (((common_header_info_s *) (iter->data))->key != NULL) {
498                                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "privatekey_password")) {
499                                                 msg->cert_info->privatekey_password = strdup(((common_header_info_s *) (iter->data))->value);
500                                                 break;
501                                         }
502                                 }
503                         }
504
505                         if (iter != NULL) {
506                                 iter_data = (common_header_info_s *) iter->data;
507                                 header_info = g_list_remove(header_info, iter_data);
508                                 free((common_header_info_s *) iter_data);
509                                 _DEBUG_INFO("[na_http_plugIn] privatekey password : %s", msg->cert_info->privatekey_password);
510                         }
511
512                         iter = NULL;
513                         iter_data = NULL;
514                         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
515                                 if (((common_header_info_s *) (iter->data))->key != NULL) {
516                                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "certificate_path")) {
517                                                 msg->cert_info->certificate_path = strdup(((common_header_info_s *) (iter->data))->value);
518                                                 break;
519                                         }
520                                 }
521                         }
522
523                         if (iter != NULL) {
524                                 iter_data = (common_header_info_s *) iter->data;
525                                 header_info = g_list_remove(header_info, iter_data);
526                                 free((common_header_info_s *) iter_data);
527                                 _DEBUG_INFO("[na_http_plugIn] certificate path : %s", msg->cert_info->certificate_path);
528                         }
529
530                         iter = NULL;
531                         iter_data = NULL;
532                         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
533                                 if (((common_header_info_s *) (iter->data))->key != NULL) {
534                                         if (!strcmp(((common_header_info_s *) (iter->data))->key, "privatekey")) {
535                                                 msg->cert_info->privatekey = strdup(((common_header_info_s *) (iter->data))->value);
536                                                 break;
537                                         }
538                                 }
539                         }
540
541                         if (iter != NULL) {
542                                 iter_data = (common_header_info_s *) iter->data;
543                                 header_info = g_list_remove(header_info, iter_data);
544                                 free((common_header_info_s *) iter_data);
545                                 _DEBUG_INFO("[na_http_plugIn] privatekey : %s", msg->cert_info->privatekey);
546                         }
547                 }
548 #endif
549                 //free(uri);
550         }
551
552         if (msg == NULL) {
553                 _DEBUG_INFO("[na_http_plugIn] create_http_message(%s) Failed\n", uri);
554                 res = 0;
555                 return res;
556         }
557 #endif
558         /*
559          *      perform soup_message_headers_append() using key-value in header_info
560          */
561         iter = NULL;
562         iter_data = NULL;
563         for (iter = header_info; iter != NULL;) {
564                 iter_data = ((common_header_info_s *) (iter->data));
565                 if (iter_data->key != NULL) {
566 #ifdef USING_LIBSOUP
567                         soup_message_headers_append(msg->request_headers, iter_data->key, iter_data->value);
568 #else
569                         _add_http_header(msg, iter_data->key, iter_data->value);
570 #endif
571                         _DEBUG_INFO("[na_http_plugIn] header append\n\t key : %s, value : %s\n", iter_data->key, iter_data->value);
572                         iter = g_list_next(iter);
573                         header_info = g_list_remove(header_info, iter_data);
574                         free((common_header_info_s *) (iter_data));
575                 }
576         }
577
578         *header_binding = msg;
579         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", msg);
580
581         if (header_info != NULL)
582                 g_list_free(header_info);
583
584 #ifdef time_check
585         /* function End Time */
586         end_t = clock();
587         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
588         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
589 #endif
590
591         _EXTERN_FUNC_EXIT;
592
593         return res;
594 }
595
596 EXPORT_API int sync_agent_plugin_send_message(void *session, void **header_binding, char *send_msg, unsigned int send_msg_length, unsigned int *recv_msg_size)
597 {
598         _EXTERN_FUNC_ENTER;
599
600         retvm_if(*header_binding == NULL, 0, "*header_binding is NULL. FAIL !!!");
601
602 #ifdef time_check
603         /* function Start Time */
604         clock_t start_t, end_t;
605         double proc_t = 0.0;
606         start_t = clock();
607 #endif
608
609         int res = 1;
610
611 #ifdef USING_LIBSOUP
612         SoupSession *ss = (SoupSession *) session;
613         _DEBUG_INFO("[na_http_plugIn] session : %d\n", ss);
614         SoupMessage *msg = (SoupMessage *) (*header_binding);
615         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", msg);
616
617 /*      for test
618         SoupMessageHeadersIter iter;
619         const char *name, *value;
620
621         soup_message_headers_iter_init (&iter, msg->request_headers);
622         _DEBUG_INFO(stdout, "1\n");
623         while (soup_message_headers_iter_next (&iter, &name, &value)) {
624                 _DEBUG_INFO(stdout, "header - name : %s   value : %s", name, value);
625                 _DEBUG_INFO(stdout, "2\n");
626         }
627         */
628
629         /*
630          *      add message body to message header
631          */
632         _DEBUG_INFO("[na_http_plugIn] create whole msg (header + body)\n");
633         soup_message_body_append(msg->request_body, SOUP_MEMORY_TEMPORARY, send_msg, send_msg_length);
634
635         /*
636          *      send & receive message
637          */
638         _DEBUG_INFO("[na_http_plugIn] send message & receive message to server \n");
639         int http_status = soup_session_send_message(ss, msg);
640
641         switch (http_status) {  /* todo : Send Message return type must be defined */
642         case REQUEST_TIMEOUT:
643                 res = -408;
644                 break;
645         case OK:
646                 res = 1;
647                 break;
648         case SOUP_CANCELED:
649                 res = -1;
650                 break;
651         case SOUP_TRY_AGAIN:
652                 res = -8;
653                 break;
654         default:
655                 res = 0;
656                 break;
657         }
658
659         _DEBUG_INFO("[na_http_plugIn] http status : %d\n", http_status);
660 #else
661         curl_session_s *curl_session = (curl_session_s *) session;
662         if (curl_session == NULL) {
663                 _DEBUG_ERROR("curl_session is NULL");
664                 res = 0;
665                 return res;
666         }
667
668         CURL *curl = curl_session->session;
669         http_message_s *msg = (http_message_s *) * header_binding;
670
671         _DEBUG_INFO("[na_http_plugIn] session : %d\n", session);
672
673         if (curl_session->msg != NULL) {
674                 _delete_http_message(curl_session->msg);
675                 curl_session->msg = NULL;
676         }
677         msg->session = curl_session;
678         curl_session->msg = msg;
679
680         /*
681          *      add message body to message header
682          */
683         _DEBUG_INFO("[na_http_plugIn] create whole msg (header + body)\n");
684
685         curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
686         curl_easy_setopt(curl, CURLOPT_POST, 0L);
687         curl_easy_setopt(curl, CURLOPT_PUT, 0L);
688         curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L);
689
690         curl_easy_setopt(curl, CURLOPT_ENCODING, msg->accept_encoding);
691
692         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, msg->send_header);
693         switch (msg->method) {
694         case LIBCURL_HTTP_GET:
695                 curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
696                 break;
697         case LIBCURL_HTTP_HEAD:
698                 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
699                 break;
700         case LIBCURL_HTTP_POST:
701                 curl_easy_setopt(curl, CURLOPT_POST, 1L);
702                 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, send_msg_length);
703                 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*)send_msg);
704                 break;
705         case LIBCURL_HTTP_PUT:
706                 curl_easy_setopt(curl, CURLOPT_PUT, 1L);
707                 break;
708         case LIBCURL_HTTP_DELETE:
709                 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
710                 break;
711         case LIBCURL_HTTP_TRACE:
712                 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "TRACE");
713                 break;
714         case LIBCURL_HTTP_OPTIONS:
715                 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS");
716                 break;
717         case LIBCURL_HTTP_CONNECT:
718                 break;
719         }
720         curl_easy_setopt(curl, CURLOPT_URL, msg->uri);
721
722         curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
723         curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_cb);
724         curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, session);
725         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_http_buffer_cb);
726         curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg->response_body);
727         curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_http_buffer_cb);
728         curl_easy_setopt(curl, CURLOPT_WRITEHEADER, msg->response_header);
729
730 #ifdef CBA
731         if (msg->cert_info == NULL) {
732                 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
733                 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
734         } else {
735                 _add_certificate_option(curl, msg);
736         }
737 #else
738         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
739         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
740 #endif
741
742         /*
743          *      send & receive message
744          */
745         _DEBUG_INFO("[na_http_plugIn] send message & receive message to server \n");
746         int http_status = 0;
747         long response_code;
748         http_status = curl_easy_perform(curl);
749
750         switch (http_status) {  /* todo : Send Message return type must be defined */
751         case CURLE_OPERATION_TIMEDOUT:
752                 res = -408;
753                 break;
754         case CURLE_OK:
755                 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
756                 http_status = response_code;
757                 _DEBUG_INFO("[na_http_plugIn] response_code : %d\n", response_code);
758                 if (response_code >= 200 && response_code <= 299) {
759                         res = 1;
760                 } else {
761                         res = 0;
762                 }
763                 break;
764         case CURLE_ABORTED_BY_CALLBACK:
765                 res = -1;
766                 break;
767         case CURLE_AGAIN:
768         case CURLE_GOT_NOTHING:
769                 res = -8;
770                 break;
771 #ifdef CBA
772         case CURLE_SSL_CACERT:
773         case CURLE_PEER_FAILED_VERIFICATION:
774                 if (msg->cert_info->accept_all_certs != 1) {
775                         res = -10;
776                 } else {
777                         res = 1;
778                 }
779                 break;
780 #endif
781         default:
782                 res = 0;
783                 break;
784         }
785         msg->http_status = http_status;
786         _DEBUG_INFO("[na_http_plugIn] http status : %d\n", http_status);
787 #endif
788
789 #ifdef time_check
790         /* function End Time */
791         end_t = clock();
792         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
793         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
794 #endif
795
796         _EXTERN_FUNC_EXIT;
797
798         return res;
799 }
800
801 EXPORT_API int sync_agent_plugin_header_unbinding(void *msg, unsigned int msg_size, GList ** recv_header, unsigned char **recv_msg, unsigned int *recv_msg_length)
802 {
803         _EXTERN_FUNC_ENTER;
804
805 #ifdef time_check
806         /* function Start Time */
807         clock_t start_t, end_t;
808         double proc_t = 0.0;
809         start_t = clock();
810 #endif
811
812         int res = 1;
813 #ifdef USING_LIBSOUP
814         SoupMessage *whole_msg = (SoupMessage *) msg;
815         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", whole_msg);
816
817         SoupMessageHeadersIter iter;
818         const char *name, *value;
819
820         *recv_header = NULL;
821
822         /*
823          *      separate header
824          */
825         soup_message_headers_iter_init(&iter, whole_msg->response_headers);
826         common_header_info_s *header_info = NULL;
827         while (soup_message_headers_iter_next(&iter, &name, &value)) {
828                 header_info = (common_header_info_s *) malloc(sizeof(common_header_info_s));
829                 if (header_info == NULL) {
830                         _DEBUG_ERROR("[na_http_plugIn] header_info malloc fail !!");
831
832                         if (*recv_header != NULL)
833                                 g_list_free(*recv_header);
834
835                         res = 0;
836                         return res;
837                 }
838                 memset(header_info, 0x00, sizeof(common_header_info_s));
839
840                 header_info->key = strdup(name);
841                 header_info->value = strdup(value);
842
843                 *recv_header = g_list_append(*recv_header, header_info);
844         }
845 #else
846         http_message_s *http_message = (http_message_s *) msg;
847         //char *http_status = g_strdup_printf("%d", http_message->http_status);
848         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", msg);
849         *recv_header = NULL;
850         if (_parse_http_header(http_message->response_header, recv_header) == 0) {
851                 res = 0;
852                 return res;
853         }
854
855         /*
856            if (http_status) {
857            *recv_header = g_list_append(*recv_header, create_header_info("Http-Status", http_status));
858            free(http_status);
859            } */
860 #endif
861         /* for test */
862         GList *g_iter = NULL;
863         for (g_iter = *recv_header; g_iter != NULL; g_iter = g_list_next(g_iter)) {
864                 _DEBUG_INFO("[na_http_plugIn] key : %s, value : %s", ((common_header_info_s *) (g_iter->data))->key, ((common_header_info_s *) (g_iter->data))->value);
865         }
866
867         /*
868          *      separate body
869          */
870 #ifdef USING_LIBSOUP
871         if (whole_msg->response_body != NULL) {
872                 if ((whole_msg->response_body->length > 0) && (whole_msg->response_body->data != NULL)) {
873                         _DEBUG_INFO("[na_http_plugIn] recv body length : %d\n", whole_msg->response_body->length);
874                         *recv_msg = (unsigned char *)malloc(whole_msg->response_body->length + 1);
875                         if (*recv_msg == NULL) {
876                                 res = 0;
877                                 return res;
878                         }
879                         memset(*recv_msg, 0x00, whole_msg->response_body->length + 1);
880                         memcpy(*recv_msg, whole_msg->response_body->data, whole_msg->response_body->length);
881
882                         *recv_msg_length = whole_msg->response_body->length;
883                         _DEBUG_INFO("[na_http_plugIn] recv_body : %s\n", *recv_msg);
884                 }
885                 /* else {
886                    _DEBUG_INFO("[na_http_plugIn] recv msg is not exist !!\n");
887
888                    if (*recv_header != NULL)
889                    g_list_free(recv_header);
890
891                    res = 0;
892                    return res;
893                    } */
894         }
895 #else
896         if ((recv_msg_length != NULL) && (recv_msg != NULL)) {
897                 if ((http_message->response_body->length > 0)) {
898                         if (http_message->response_body->buff != NULL) {
899                                 *recv_msg = malloc(http_message->response_body->length + 1);
900                                 if (*recv_msg == NULL) {
901                                         _DEBUG_ERROR("MALLOC failed !!!");
902                                         res = 0;
903                                         return res;
904                                 }
905                                 memcpy(*recv_msg, http_message->response_body->buff, http_message->response_body->length);
906                                 (*recv_msg)[http_message->response_body->length] = 0;
907                                 *recv_msg_length = http_message->response_body->length;
908                         }
909                 } else {
910                         *recv_msg_length = 0;
911                         *recv_msg = NULL;
912                 }
913         }
914 #endif
915
916         _DEBUG_INFO("[na_http_plugIn] msg : %d\n", msg);
917
918 #ifdef time_check
919         /* function End Time */
920         end_t = clock();
921         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
922         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
923 #endif
924
925 #ifdef USING_LIBSOUP
926         g_object_unref(G_OBJECT(msg));
927 #else
928         curl_session_s *session;
929         session = (curl_session_s *) http_message->session;
930         _delete_http_message(http_message);
931         if (session->msg != NULL)
932                 session->msg = NULL;
933 #endif
934
935         _EXTERN_FUNC_EXIT;
936
937         return res;
938 }
939
940 EXPORT_API int sync_agent_plugin_close_connection(void *session)
941 {
942         _EXTERN_FUNC_ENTER;
943
944 #ifdef time_check
945         /* function Start Time */
946         clock_t start_t, end_t;
947         double proc_t = 0.0;
948         start_t = clock();
949 #endif
950
951         int res = 1;
952
953 #ifdef USING_LIBSOUP
954         SoupSession *ss = (SoupSession *) session;
955
956         _DEBUG_INFO("[na_http_plugIn] session : %d", session);
957
958         auth_info_s *auth_info = NULL;
959         res = _find_auth_info(ss, &auth_info);
960         if (res == 0) {
961                 _DEBUG_INFO("[na_http_plugIn] auth_info is NULL !!");
962
963                 /* soup_session_cleanup_connections(ss, TRUE); */
964                 soup_session_abort(ss);
965                 _DEBUG_INFO("[na_http_plugIn] session cleanup connections !!");
966
967                 res = 1;
968         } else if (res == 1) {
969                 _DEBUG_INFO("[na_http_plugIn] fine_auth_info() is success !!");
970
971                 /* soup_session_cleanup_connections(ss, TRUE); */
972                 soup_session_abort(ss);
973                 _DEBUG_INFO("[na_http_plugIn] session cleanup connections !!");
974
975                 if (auth_info != NULL) {
976                         auth_info_list = g_list_remove(auth_info_list, auth_info);
977
978                         if (auth_info->id != NULL)
979                                 free(auth_info->id);
980                         if (auth_info->password != NULL)
981                                 free(auth_info->password);
982                         free(auth_info);
983
984                         _DEBUG_INFO("[na_http_plugIn] remove auth_info success !!");
985                 }
986         } else {                /* res  == -1 */
987                 _DEBUG_INFO("[na_http_plugIn] auth_info_list is NULL !!");
988
989                 /* soup_session_cleanup_connections(ss, TRUE); */
990                 soup_session_abort(ss);
991                 _DEBUG_INFO("[na_http_plugIn] session cleanup connections !!");
992
993                 res = 1;
994         }
995 #else
996         curl_session_s *curl_session = (curl_session_s *) session;
997         CURL *curl = curl_session->session;
998         curl_easy_cleanup(curl);
999
1000         if (curl_session->msg != NULL) {
1001                 _delete_http_message(curl_session->msg);
1002                 curl_session->msg = NULL;
1003         }
1004         free(curl_session);
1005
1006 #endif
1007
1008 #ifdef time_check
1009         /* function End Time */
1010         end_t = clock();
1011         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
1012         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
1013 #endif
1014
1015         _EXTERN_FUNC_EXIT;
1016
1017         return res;
1018 }
1019
1020 EXPORT_API int sync_agent_plugin_cancel_message(void *session)
1021 {
1022         _EXTERN_FUNC_ENTER;
1023
1024 #ifdef time_check
1025         /* function Start Time */
1026         clock_t start_t, end_t;
1027         double proc_t = 0.0;
1028         start_t = clock();
1029 #endif
1030
1031         int res = 1;
1032
1033 #ifdef USING_LIBSOUP
1034         SoupSession *ss = (SoupSession *) session;
1035         _DEBUG_INFO("[na_http_plugIn] session : %d", session);
1036
1037         auth_info_s *auth_info = NULL;
1038         /* SoupMessage *cancel_msg = (SoupMessage*)msg; */
1039
1040         /* if ((ss != NULL) && (cancel_msg != NULL) && (cancel_msg->status_code != SOUP_STATUS_OK && cancel_msg->status_code != SOUP_STATUS_CANCELLED)) {
1041            soup_session_cancel_message(ss, cancel_msg, SOUP_STATUS_CANCELLED);
1042            _DEBUG_INFO("[na_http_plugIn] cancel message !!\n");
1043            } */
1044
1045         res = _find_auth_info(ss, &auth_info);
1046         if (res == 0) {
1047                 _DEBUG_INFO("[na_http_plugIn] auth_info is NULL !!");
1048                 soup_session_abort(ss);
1049                 _DEBUG_INFO("[na_http_plugIn] session abort !! \n");
1050
1051                 res = 1;
1052         } else if (res == 1) {
1053                 _DEBUG_INFO("[na_http_plugIn] fine_auth_info() is success !!");
1054
1055                 /* cancel all pending requests & disconnect connection */
1056                 soup_session_abort(ss);
1057                 _DEBUG_INFO("[na_http_plugIn] session abort !! \n");
1058
1059                 if (auth_info != NULL) {
1060                         auth_info_list = g_list_remove(auth_info_list, auth_info);
1061
1062                         if (auth_info->id != NULL)
1063                                 free(auth_info->id);
1064                         if (auth_info->password != NULL)
1065                                 free(auth_info->password);
1066                         free(auth_info);
1067
1068                         _DEBUG_INFO("[na_http_plugIn] remove auth_info success !!");
1069                 }
1070         } else {                /* res  == -1 */
1071                 _DEBUG_INFO("[na_http_plugIn] auth_info_list is NULL !!");
1072
1073                 /* cancel all pending requests & disconnect connection */
1074                 soup_session_abort(ss);
1075                 _DEBUG_INFO("[na_http_plugIn] session abort !! \n");
1076
1077                 res = 1;
1078         }
1079 #else
1080         curl_session_s *curl_session = (curl_session_s *) session;
1081         _curl_session_abort(curl_session);
1082 #endif
1083
1084 #ifdef time_check
1085         /* function End Time */
1086         end_t = clock();
1087         proc_t = ((double)(end_t - start_t)) / CLOCKS_PER_SEC;
1088         _DEBUG_INFO("[na_http_plugIn] execute time : %0.2f\n", proc_t);
1089 #endif
1090
1091         _EXTERN_FUNC_EXIT;
1092
1093         return res;
1094 }
1095
1096 EXPORT_API int sync_agent_plugin_get_header_info(GList * header_info, char *key, char **value)
1097 {
1098         _EXTERN_FUNC_ENTER;
1099
1100         retvm_if(header_info == NULL, 0, "header_info is NULL. FAIL !!!");
1101         retvm_if(key == NULL, 0, "key is NULL. FAIL !!!");
1102
1103         int res = 1;
1104
1105         GList *iter = NULL;
1106         common_header_info_s *iter_data;
1107         *value = NULL;
1108         int value_len = 0;
1109
1110         if (header_info == NULL) {
1111                 _DEBUG_ERROR("[na_http_plugIn] Error !! ( not exist header information )\n");
1112                 res = 0;
1113                 return res;
1114         }
1115
1116         for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
1117                 iter_data = NULL;
1118                 iter_data = (common_header_info_s *) (iter->data);
1119                 if (iter_data->key != NULL) {
1120                         if (!strcmp(iter_data->key, key)) {
1121                                 if (iter_data->value != NULL) {
1122                                         /* if (*value == NULL) { *//* first 'key - value' pair */
1123                                         if (value_len == 0) {   /* first 'key - value' pair */
1124                                                 *value = (char *)malloc(strlen(iter_data->value) + NULL_LEN + SEMI_COLON_LEN);
1125                                                 if (*value == NULL) {
1126                                                         _DEBUG_ERROR("[na_http_plugIn] malloc error !!");
1127                                                         res = 0;
1128                                                         return res;
1129                                                 }
1130
1131                                                 memset(*value, 0x00, strlen(iter_data->value) + NULL_LEN + SEMI_COLON_LEN);
1132                                                 memcpy(*value, iter_data->value, strlen(iter_data->value));
1133                                                 _DEBUG_INFO("[na_http_plugIn] key : %s, value : %s ( %d )", iter_data->key, *value, strlen(*value));
1134
1135                                                 value_len += strlen(*value);
1136                                         } else {        /* after first 'key - value' pair */
1137                                                 int len = strlen(iter_data->value);
1138                                                 _DEBUG_INFO("value = %s, len = %d", iter_data->value, len);
1139                                                 if (len != 0) {
1140                                                         value_len += (len + NULL_LEN + SEMI_COLON_LEN);
1141                                                         *value = (char *)realloc(*value, value_len);
1142                                                         if (*value == NULL) {
1143                                                                 _DEBUG_ERROR("[na_http_plugIn] realloc error !!");
1144                                                                 res = 0;
1145                                                                 return res;
1146                                                         }
1147                                                         int strcat_check_len = 0;
1148
1149                                                         strcat_check_len = g_strlcat(*value, ";", value_len);
1150                                                         strcat_check_len = g_strlcat(*value, iter_data->value, value_len);
1151
1152                                                         if (strcat_check_len >= value_len) {
1153                                                                 _DEBUG_ERROR("[na_http_plugIn] *value buffer overflow !!");
1154                                                                 res = 0;
1155                                                                 return res;
1156                                                         }
1157                                                         _DEBUG_INFO("[na_http_plugIn] key : %s, value : %s ( %d )", iter_data->key, *value, strlen(*value));
1158                                                 } else {
1159                                                         /*do nothing */
1160                                                 }
1161                                         }
1162                                 } else {
1163                                         _DEBUG_ERROR("[na_http_plugIn] value is NULL !! \n");
1164                                         res = 0;
1165                                         return res;
1166                                 }
1167                         }
1168                 } else {
1169                         _DEBUG_ERROR("[na_http_plugIn] key is NULL !! \n");
1170                         res = 0;
1171                         return res;
1172                 }
1173         }
1174
1175         _EXTERN_FUNC_EXIT;
1176
1177         return res;
1178 }
1179
1180 EXPORT_API int sync_agent_plugin_set_data_download_info(void *http_info, char *current_download_range)
1181 {
1182         _EXTERN_FUNC_ENTER;
1183
1184         retvm_if(http_info == NULL, 0, "http_info is NULL. FAIL !!!");
1185         retvm_if(current_download_range == NULL, 0, "current_download_range is NULL. FAIL !!!");
1186
1187         int ret = 1;
1188
1189         GList *iter = 0;
1190         for (iter = (GList *) http_info; iter != NULL; iter = g_list_next(iter)) {
1191
1192                 if (((common_header_info_s *) (iter->data))->key != NULL && !strcmp(((common_header_info_s *) (iter->data))->key, "Range")) {
1193
1194                         char *value = ((common_header_info_s *) (iter->data))->value;
1195                         if (value != NULL) {
1196                                 free(value);
1197
1198                                 ((common_header_info_s *) (iter->data))->value = g_strdup_printf("bytes=%s", current_download_range);
1199                                 _DEBUG_INFO("[After] key : %s, value : %s\n", ((common_header_info_s *) (iter->data))->key, ((common_header_info_s *) (iter->data))->value);
1200                                 break;
1201                         } else {
1202                                 _DEBUG_ERROR("[na_http_plugIn] value is NULL !! \n");
1203                                 ret = 0;
1204                                 return ret;
1205                         }
1206                 }
1207         }
1208
1209         _DEBUG_INFO("[na_http_plugIn] end");
1210
1211         _EXTERN_FUNC_EXIT;
1212
1213         return ret;
1214 }
1215
1216 EXPORT_API int sync_agent_plugin_get_data_download_info(void *http_req_info, void *http_info, int *total_doanload_size, char **current_download_range, char **download_file_name)
1217 {
1218         _EXTERN_FUNC_ENTER;
1219
1220         retvm_if(http_req_info == NULL, 0, "http_req_info is NULL. FAIL !!!");
1221         retvm_if(http_info == NULL, 0, "http_info is NULL. FAIL !!!");
1222
1223         int ret = 1;
1224
1225         /* Get_Header_Info(http_info, "Content-Disposition", download_file_name);
1226            if (*download_file_name == NULL) {
1227            _DEBUG_INFO("[na_http_plugIn] download_file_name == 0");
1228            return 0;
1229            } else {
1230            _DEBUG_INFO("[na_http_plugIn]  download_file_name = %s\n", *download_file_name);
1231            }
1232
1233            char *content_range_value = 0;
1234            Get_Header_Info(http_info, "Content-Range", &content_range_value);
1235            if (content_range_value == NULL) {
1236            _DEBUG_INFO("[na_http_plugIn] content_range_value == 0");
1237            return 0;
1238            } else {
1239            _DEBUG_INFO("[na_http_plugIn] content range value = %s\n", content_range_value);
1240            } */
1241
1242         /* pasing file name */
1243         char *temp_file_name = 0;       /* strdup("attachment; fileName=\"FW-20110901-13121.bin\""); */
1244         sync_agent_plugin_get_header_info((GList *) http_info, "Content-Disposition", &temp_file_name);
1245         _DEBUG_INFO("temp_file_name = %s\n", temp_file_name);
1246         if (temp_file_name != NULL) {
1247                 char *ptr1 = strstr(temp_file_name, "attachment;");
1248                 if (ptr1 != NULL) {
1249                         ptr1 = strstr(ptr1, "fileName=");
1250                         if (ptr1 != NULL) {
1251
1252                                 char *temp = strdup(ptr1);
1253
1254                                 char *del = "\"";
1255                                 char *temp_ptr = strtok(temp, del);
1256                                 _DEBUG_INFO("1st token = %s\n", temp_ptr);
1257
1258                                 temp_ptr = strtok(NULL, del);
1259                                 _DEBUG_INFO("2nd token = %s\n", temp_ptr);
1260
1261                                 *download_file_name = strdup(temp_ptr);
1262                                 _DEBUG_INFO("*download_file_name = %s\n", *download_file_name);
1263
1264                                 if (temp != NULL)
1265                                         free(temp);
1266                         }
1267                 }
1268         } else {
1269                 char *result_name = NULL;
1270
1271                 sync_agent_plugin_get_header_info((GList *) http_req_info, "uri", &temp_file_name);
1272                 _DEBUG_INFO("temp_file_name = %s\n", temp_file_name);
1273
1274                 result_name = strrchr(temp_file_name, '/');
1275                 _DEBUG_INFO("result_file name : %s", result_name);
1276
1277                 if (result_name != NULL) {
1278                         ++result_name;
1279                         _DEBUG_INFO("remove '/' result_file name : %s", result_name);
1280                 }
1281
1282                 *download_file_name = strdup(result_name);
1283                 _DEBUG_INFO("*download_file_name = %s\n", *download_file_name);
1284
1285         }
1286         /* parsing data range info */
1287         char *temp_range_value = 0;     /* strdup("bytes 0-66303/3192624"); */
1288         sync_agent_plugin_get_header_info((GList *) http_info, "Content-Range", &temp_range_value);
1289         char *temp = strdup(temp_range_value + strlen("bytes "));
1290         _DEBUG_INFO("temp_range = %s\n", temp);
1291
1292         char *del2 = "/";
1293         char *ptr2 = strtok(temp, del2);
1294         if (ptr2 != NULL) {
1295                 _DEBUG_INFO("[na_http_plugIn] range = %s\n", ptr2);
1296                 *current_download_range = strdup(ptr2);
1297
1298                 ptr2 = strtok(NULL, del2);
1299                 _DEBUG_INFO("[na_http_plugIn] total = %s\n", ptr2);
1300                 *total_doanload_size = atoi(ptr2);
1301         }
1302 //      if (temp_file_name != NULL)
1303         free(temp_file_name);
1304         if (temp_range_value != NULL)
1305                 free(temp_range_value);
1306         if (temp != NULL)
1307                 free(temp);
1308
1309         _DEBUG_INFO("[na_http_plugIn] end");
1310
1311         _EXTERN_FUNC_EXIT;
1312
1313         return ret;
1314 }
1315
1316 EXPORT_API int sync_agent_plugin_add_authentication_info(void *session, char *id, char *password)
1317 {
1318         _EXTERN_FUNC_ENTER;
1319
1320         retvm_if(id == NULL, 0, "id is NULL. FAIL !!!");
1321         retvm_if(password == NULL, 0, "password is NULL. FAIL !!!");
1322
1323         int res = 1;
1324
1325 #ifdef USING_LIBSOUP
1326         SoupSession *ss = (SoupSession *) session;
1327
1328         res = _add_auth_info(ss, id, password);
1329 #else
1330         CURL *curl = ((curl_session_s *) session)->session;
1331
1332         char *userpwd;
1333         int id_len, pw_len, userpwd_len;
1334
1335         id_len = strlen(id);
1336         pw_len = strlen(password);
1337
1338         userpwd_len = id_len + pw_len + 2;
1339         userpwd = (char *)malloc(userpwd_len);
1340         if (userpwd != NULL) {
1341                 snprintf(userpwd, userpwd_len, "%s:%s", id, password);
1342         } else {
1343                 _DEBUG_ERROR("[na_http_plugIn] userpwd malloc failed !!");
1344                 res = 0;
1345                 return res;
1346         }
1347
1348         curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
1349
1350         if (userpwd != NULL)
1351                 free(userpwd);
1352 #endif
1353         if (res != 1) {
1354                 _DEBUG_ERROR("[na_http_plugIn] _add_auth_info() is fail !!");
1355                 return res;
1356         } else {
1357                 _DEBUG_INFO("[na_http_plugIn] _add_auth_info() is success !!");
1358                 /* register user authentication callback (for EAS) */
1359 #ifdef USING_LIBSOUP
1360                 g_signal_connect(ss, "authenticate", G_CALLBACK(authenticate_cb), NULL);
1361 #endif
1362         }
1363
1364         _EXTERN_FUNC_EXIT;
1365
1366         return res;
1367 }
1368
1369 EXPORT_API int sync_agent_plugin_set_property(void *session, sync_agent_na_property_e property, va_list va)
1370 {
1371         _EXTERN_FUNC_ENTER;
1372
1373         int ret = 1;
1374         CURL *curl = ((curl_session_s *) session)->session;
1375         if (curl == NULL)
1376                 return 0;
1377
1378         switch (property) {
1379         case SYNC_AGENT_NA_PROP_TIMEOUT:{
1380                         int timeout = va_arg(va, long);
1381                         curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
1382                 }
1383                 break;
1384         default:
1385                 ret = 0;
1386                 break;
1387         }
1388
1389         _EXTERN_FUNC_EXIT;
1390
1391         return ret;
1392 }
1393
1394 EXPORT_API int sync_agent_plugin_get_status(void *session, sync_agent_na_status_e status, va_list va)
1395 {
1396         _EXTERN_FUNC_ENTER;
1397
1398         int ret = 1;
1399         CURL *curl = ((curl_session_s *) session)->session;
1400         if (curl == NULL)
1401                 return 0;
1402
1403         switch (status) {
1404         case SYNC_AGENT_NA_STATUS_ELAPSED_TIME:{
1405                         double *arg = va_arg(va, double *);
1406                         curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, arg);
1407                 }
1408                 break;
1409         case SYNC_AGENT_NA_STATUS_RESPONSE_CODE:{
1410                         long *arg = va_arg(va, long *);
1411                         curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, arg);
1412                 }
1413                 break;
1414         default:
1415                 ret = 0;
1416                 break;
1417         }
1418
1419         _EXTERN_FUNC_EXIT;
1420
1421         return ret;
1422 }
1423
1424 #ifdef USING_LIBSOUP
1425 static int _add_auth_info(SoupSession * session, char *user_id, char *user_pw)
1426 {
1427         int res = 1;
1428
1429         auth_info_s *auth_info;
1430
1431         /* memory alloc - auth_info  */
1432         auth_info = (auth_info_s *) calloc(1, sizeof(auth_info_s));
1433         if (auth_info == NULL) {
1434                 _DEBUG_ERROR("[na_http_plugIn] auth_info calloc fail !!");
1435                 return 0;
1436         }
1437         _DEBUG_TRACE("[na_http_plugIn] auth_info calloc success !!");
1438
1439         auth_info->session = (void *)calloc(1, sizeof(auth_info->session));
1440         if (auth_info->session == NULL) {
1441                 _DEBUG_ERROR("CALLOC failed !!!");
1442                 return 0;
1443         }
1444         auth_info->session = session;
1445         _DEBUG_TRACE("[na_http_plugIn] auth_info : sessoin ( %d )", auth_info->session);
1446         auth_info->id = strdup(user_id);
1447         _DEBUG_TRACE("[na_http_plugIn] auth_info : id ( %s )", auth_info->id);
1448         auth_info->password = strdup(user_pw);
1449         _DEBUG_TRACE("[na_http_plugIn] auth_info : password ( %s )", auth_info->password);
1450
1451         /* append auth_info to auth_info_list */
1452         auth_info_list = g_list_append(auth_info_list, auth_info);
1453         _DEBUG_TRACE("[na_http_plugIn] append auth_info");
1454
1455         return res;
1456 }
1457
1458 /*static int remove_auth_info(SoupSession *session)
1459 {
1460         int res = 1;
1461         auth_info_s *auth_info = NULL;
1462
1463         res = _find_auth_info(session, &auth_info);
1464         if (res == 0) {
1465                 _DEBUG_ERROR("[na_http_plugIn] _find_auth_info() is fail !!");
1466                 res = 0;
1467                 return res;
1468         } else if (res == 1) {
1469                 _DEBUG_INFO("[na_http_plugIn] fine_auth_info() is success !!");
1470
1471                 if (auth_info->id != NULL)
1472                         free(auth_info->id);
1473
1474                 if (auth_info->password != NULL)
1475                         free(auth_info->password);
1476
1477                 if (auth_info != NULL)
1478                         free(auth_info);
1479         }
1480
1481         return res;
1482 }*/
1483
1484 static int _find_auth_info(SoupSession * session, auth_info_s ** auth_info)
1485 {
1486         GList *iter = NULL;
1487         auth_info_s *iter_data;
1488
1489         int res = 1;
1490
1491         if (auth_info_list != NULL) {
1492                 /* find auth_info for session */
1493                 for (iter = auth_info_list; iter != NULL; iter = g_list_next(iter)) {
1494                         iter_data = NULL;
1495                         if (((auth_info_s *) (iter->data))->session != NULL) {
1496                                 if (((auth_info_s *) (iter->data))->session == session) {
1497                                         iter_data = (auth_info_s *) (iter->data);
1498                                         _DEBUG_TRACE("[na_http_plugIn] find session : %d", session);
1499                                         break;
1500                                 }
1501                         }
1502                 }
1503         } else {
1504                 _DEBUG_ERROR("[na_http_plugIn] auth_info_list is NULL !!");
1505                 res = -1;
1506                 return res;
1507         }
1508
1509         if (iter_data != NULL) {
1510                 *auth_info = (auth_info_s *) iter_data;
1511         } else {
1512                 _DEBUG_ERROR("[na_http_plugIn] iter_data is NULL !!");
1513                 res = 0;
1514                 return res;
1515         }
1516
1517         return res;
1518 }
1519
1520 static void authenticate_cb(SoupSession * session, SoupMessage * msg, SoupAuth * auth, gboolean retrying, gpointer user_data)
1521 {
1522         int err = 1;
1523         auth_info_s *auth_info = NULL;
1524
1525         if (!retrying) {
1526                 err = _find_auth_info(session, &auth_info);
1527                 if (err == 0) {
1528                         _DEBUG_ERROR("[na_http_plugIn] _find_auth_info() is fail !!");
1529                         /* todo : error handling */
1530                 } else if (err == 1) {
1531                         _DEBUG_INFO("[na_http_plugIn] _find_auth_info() is success !!");
1532                         /* first authentication */
1533                         if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
1534                                 if ((auth_info->id != NULL) && (auth_info->password != NULL))
1535                                         soup_auth_authenticate(auth, auth_info->id, auth_info->password);
1536                         }
1537                         /* not implement - proxy authentication */
1538                         /* else if (msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED) {
1539                            if (((auth_info_s*)(iter->data))->proxy_id && ((auth_info_s*)(iter->data))->proxy_password)
1540                            soup_auth_authenticate(auth, ((auth_info_s*)(iter->data))->proxy_id, ((auth_info_s*)(iter->data))->proxy_password);
1541                            } */
1542                 } else {        /* err == -1 */
1543                         _DEBUG_INFO("[na_http_plugIn] auth_info_list is NULL !!");
1544                 }
1545         } else {
1546                 /* retry */
1547                 _DEBUG_INFO("[na_http_plugIn] authentication Retry !!");
1548         }
1549
1550 }
1551 #else
1552
1553 static http_buffer_s *__create_http_buffer(int block_size)
1554 {
1555         _INNER_FUNC_ENTER;
1556
1557         http_buffer_s *buff = (http_buffer_s *) calloc(1, sizeof(http_buffer_s));
1558         if (buff == NULL) {
1559                 _DEBUG_ERROR("CALLOC failed !!!");
1560                 return NULL;
1561         }
1562         buff->block_size = block_size;
1563
1564         _INNER_FUNC_EXIT;
1565
1566         return buff;
1567 }
1568
1569 static int __delete_http_buffer(http_buffer_s * buff)
1570 {
1571         _INNER_FUNC_ENTER;
1572
1573         if (buff->buff != NULL) {
1574                 free(buff->buff);
1575         }
1576         free(buff);
1577
1578         _INNER_FUNC_EXIT;
1579
1580         return 0;
1581 }
1582
1583 static size_t write_http_buffer_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
1584 {
1585         _EXTERN_FUNC_ENTER;
1586
1587         http_buffer_s *buff = (http_buffer_s *) userdata;
1588         int len = size * nmemb;
1589         int written_len = buff->length;
1590         int block_size = buff->block_size;
1591         int allocated_block = (written_len + (block_size - 1)) / block_size;
1592
1593         if (written_len + len > allocated_block * block_size) {
1594                 allocated_block = (written_len + len + (block_size - 1)) / block_size;
1595                 buff->buff = realloc(buff->buff, allocated_block * block_size);
1596                 if (buff->buff == NULL) {
1597                         return 0;
1598                 }
1599         }
1600         memcpy(&buff->buff[written_len], ptr, len);
1601         buff->length += len;
1602
1603         _EXTERN_FUNC_EXIT;
1604
1605         return len;
1606 }
1607
1608 #ifdef CBA
1609 static http_message_s *_create_http_message(libcurl_http_method_e method, char *uri, char *accept_encoding, int is_cert)
1610 #else
1611 static http_message_s *_create_http_message(libcurl_http_method_e method, char *uri, char *accept_encoding)
1612 #endif
1613 {
1614         _INNER_FUNC_ENTER;
1615
1616         http_message_s *msg = (http_message_s *) calloc(1, sizeof(http_message_s));
1617         if (msg == NULL)
1618                 return NULL;
1619
1620         msg->method = method;
1621         msg->uri = uri ? strdup(uri) : NULL;
1622         msg->accept_encoding = accept_encoding ? strdup(accept_encoding) : NULL;
1623         msg->response_header = __create_http_buffer(HEADER_BLOCK_SIZE);
1624         msg->response_body = __create_http_buffer(CONTENT_BLOCK_SIZE);
1625 #ifdef CBA
1626         if (is_cert != 0)
1627                 msg->cert_info = (certificate_info_s *) calloc(1, sizeof(certificate_info_s));
1628         if (msg->cert_info == NULL) {
1629                 _DEBUG_ERROR("CALLOC failed !!!");
1630                 return NULL;
1631         }
1632 #endif
1633
1634         _INNER_FUNC_EXIT;
1635
1636         return msg;
1637 }
1638
1639 static int _add_http_header(http_message_s * msg, char *key, char *value)
1640 {
1641         _INNER_FUNC_ENTER;
1642
1643         retvm_if(key == NULL, 0, "key is NULL. FAIL !!!");
1644         retvm_if(value == NULL, 0, "value is NULL. FAIL !!!");
1645
1646         char *key_pair;
1647         int key_len, val_len, key_pair_len;
1648
1649         key_len = strlen(key);
1650         val_len = strlen(value);
1651
1652         key_pair_len = key_len + val_len + 2;
1653         key_pair = (char *)malloc(key_pair_len);
1654         if (key_pair == NULL) {
1655                 _DEBUG_ERROR("[na_http_plugIn] authentication Retry !!");
1656                 return 0;
1657         }
1658
1659         snprintf(key_pair, key_pair_len, "%s:%s", key, value);
1660
1661         msg->send_header = curl_slist_append(msg->send_header, key_pair);
1662         free(key_pair);
1663
1664         _INNER_FUNC_EXIT;
1665
1666         return 1;
1667 }
1668
1669 static int _delete_http_message(http_message_s * msg)
1670 {
1671         _INNER_FUNC_ENTER;
1672
1673         retvm_if(msg == NULL, 0, "msg is NULL. FAIL !!!");
1674
1675         if (msg->uri != NULL) {
1676                 free(msg->uri);
1677         }
1678         if (msg->accept_encoding != NULL) {
1679                 free(msg->accept_encoding);
1680         }
1681         if (msg->send_header != NULL) {
1682                 curl_slist_free_all(msg->send_header);
1683         }
1684         if (msg->response_header != NULL) {
1685                 __delete_http_buffer(msg->response_header);
1686                 msg->response_header = 0;
1687         }
1688         if (msg->response_body != NULL) {
1689                 __delete_http_buffer(msg->response_body);
1690                 msg->response_body = 0;
1691         }
1692         free(msg);
1693
1694         _INNER_FUNC_EXIT;
1695
1696         return 1;
1697 }
1698
1699 static int curl_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
1700 {
1701         _EXTERN_FUNC_ENTER;
1702
1703         retvm_if(clientp == NULL, 0, "clientp is NULL. FAIL !!!");
1704
1705         curl_session_s *session = (curl_session_s *) clientp;
1706         if (session->msg != NULL) {
1707                 if (session->msg->abort != 0) {
1708                         _EXTERN_FUNC_EXIT;
1709                         return 1;
1710                 }
1711         }
1712
1713         _EXTERN_FUNC_EXIT;
1714         return 0;
1715 }
1716
1717 static int _curl_session_abort(curl_session_s * session)
1718 {
1719         _INNER_FUNC_ENTER;
1720
1721         retvm_if(session == NULL, 0, "session is NULL. FAIL !!!");
1722
1723         if (session->msg != NULL) {
1724                 session->msg->abort = 1;
1725         }
1726
1727         _INNER_FUNC_EXIT;
1728
1729         return 1;
1730 }
1731
1732 static common_header_info_s *__create_header_info(char *key, char *value)
1733 {
1734         _INNER_FUNC_ENTER;
1735
1736         retvm_if(key == NULL, NULL, "key is NULL. FAIL !!!");
1737         retvm_if(value == NULL, NULL, "value is NULL. FAIL !!!");
1738
1739         common_header_info_s *header_info = NULL;
1740         header_info = (common_header_info_s *) calloc(1, sizeof(common_header_info_s));
1741         if (header_info == NULL) {
1742                 return NULL;
1743         }
1744         header_info->key = strdup(key);
1745         header_info->value = strdup(value);
1746
1747         _INNER_FUNC_EXIT;
1748
1749         return header_info;
1750 }
1751
1752 static int _parse_http_header(http_buffer_s * header, GList ** header_list)
1753 {
1754         _INNER_FUNC_ENTER;
1755
1756         retvm_if(header == NULL, 0, "header is NULL. FAIL !!!");
1757
1758         common_header_info_s *header_info = NULL;
1759
1760         int state = 0;
1761         int ret = 1;
1762         char *value = NULL;
1763         char *buff = malloc(header->length + 1);
1764         if (buff == NULL) {
1765                 _DEBUG_ERROR("MALLOC failed !!!");
1766                 return 0;
1767         }
1768         char *tmp = buff;
1769         char ch;
1770
1771         char *key = NULL;
1772         *header_list = NULL;
1773
1774         memcpy(buff, header->buff, header->length);
1775         buff[header->length] = 0;
1776
1777         while (*tmp) {
1778                 ch = *tmp;
1779                 if (ch == '\r' || ch == '\n') {
1780                         *tmp = 0;
1781                         if ((key != NULL) && (state == 100)) {
1782                                 header_info = __create_header_info(key, value ? value : "");
1783                                 *header_list = g_list_append(*header_list, header_info);
1784                         }
1785                         state = 0;
1786                         key = NULL;
1787                         value = NULL;
1788                         tmp++;
1789                         continue;
1790                 }
1791                 switch (state) {
1792                 case 0:
1793                         if (isspace(ch) && (key == NULL)) {
1794                                 *tmp = 0;
1795                         } else {
1796                                 if (key == NULL) {
1797                                         key = tmp;
1798                                 }
1799                                 if (ch == ':') {
1800                                         *tmp = 0;
1801                                         state = 100;
1802                                 }
1803                         }
1804
1805                         break;
1806                 case 100:
1807                         if (isspace(ch) && (value == NULL)) {
1808                                 *tmp = 0;
1809                         } else {
1810                                 if (value == NULL) {
1811                                         value = tmp;
1812                                 }
1813                                 if (ch == ';') {
1814                                         *tmp = 0;
1815                                         if (key != NULL) {
1816                                                 header_info = __create_header_info(key, value);
1817                                                 *header_list = g_list_append(*header_list, header_info);
1818                                                 value = NULL;
1819                                         }
1820                                 }
1821                         }
1822                         break;
1823                 }
1824                 tmp++;
1825         }
1826
1827         free(buff);
1828
1829         _INNER_FUNC_EXIT;
1830
1831         return ret;
1832 }
1833
1834 #ifdef CBA
1835 static void _add_certificate_option(CURL * curl, http_message_s * msg)
1836 {
1837         _INNER_FUNC_ENTER;
1838
1839         retm_if(msg == NULL, "msg is NULL. FAIL !!!");
1840
1841         if (msg->cert_info->accept_all_certs != 1)
1842                 curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, ssl_context_cb);
1843
1844         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
1845         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
1846
1847         curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
1848         curl_easy_setopt(curl, CURLOPT_SSLCERT, msg->cert_info->certificate_path);
1849         curl_easy_setopt(curl, CURLOPT_KEYPASSWD, msg->cert_info->privatekey_password);
1850
1851         curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
1852         curl_easy_setopt(curl, CURLOPT_SSLKEY, msg->cert_info->privatekey);
1853
1854         /* set the file with the certs vaildating the server */
1855         //curl_easy_setopt(session->curl,CURLOPT_CAINFO,pServerCert);
1856         curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, TRUE);
1857
1858         _INNER_FUNC_EXIT;
1859 }
1860
1861 static CURLcode ssl_context_cb(CURL * curl, SSL_CTX * sslctx, void *param)
1862 {
1863         _EXTERN_FUNC_ENTER;
1864
1865         SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_peer_cb);
1866
1867         _EXTERN_FUNC_EXIT;
1868         return CURLE_OK;
1869 }
1870
1871 static int verify_peer_cb(int preverify_ok, X509_STORE_CTX * x509_ctx)
1872 {
1873         _EXTERN_FUNC_ENTER;
1874
1875         int retVal = 1;
1876
1877         _DEBUG_INFO("[na_http_plugIn] Read Peer certificates from SSL context !!");
1878         X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
1879         if (cert == NULL) {
1880                 _DEBUG_ERROR("[na_http_plugIn] No cert info available in the Context !!");
1881                 retVal = 0;
1882                 goto return_part;
1883         }
1884
1885         int err = X509_STORE_CTX_get_error(x509_ctx);
1886 //    char cert_file_path[1024] = {0, };
1887 //    snprintf(cert_file_path, sizeof(cert_file_path), "%s/PeerCertificate_%u", "aaa",(int)g_thread_self());
1888 //    _DEBUG_INFO("[na_http_plugIn] Certificate Path : %s",cert_file_path);
1889 //
1890 //    FILE *fp = fopen(cert_file_path, "a");
1891 //    errno = 0;
1892 //    if (!fp) {
1893 //        _DEBUG_ERROR("[na_http_plugIn] Failed to open file : %s", strerror(errno));
1894 //        retVal = 0;
1895 //        goto return_part;
1896 //    }
1897
1898         if (preverify_ok) {
1899 //        fprintf(fp,"Certificate is OK\n");
1900                 _DEBUG_INFO("[na_http_plugIn] Certificate is OK !!");
1901         } else {
1902 //        fprintf(fp,"Certificate verification failed.Reason::%d\n",err);
1903                 _DEBUG_ERROR("[na_http_plugIn] Certificate verification failed ( err : %d ) !!", err);
1904                 retVal = 0;
1905         }
1906 //    X509_print_fp(fp,cert);
1907 //    fprintf(fp,"===========================================\n");
1908 //    if (fp != NULL) {
1909 //        fclose(fp);
1910 //        fp = NULL;
1911 //    }
1912
1913  return_part:
1914
1915         _EXTERN_FUNC_EXIT;
1916
1917         return retVal;
1918 }
1919 #endif
1920
1921 #endif
1922
1923 EXPORT_API void sync_agent_plugin_register_fw_main_loop_network_access(void *data)
1924 {
1925         _EXTERN_FUNC_ENTER;
1926
1927         _EXTERN_FUNC_EXIT;
1928
1929         return;
1930 }