52d72c9bcabc94244edb6fa52214c9f1e73c4c85
[platform/framework/web/download-provider.git] / src / agent / download-agent-http-mgr.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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 "download-agent-utils.h"
18 #include "download-agent-debug.h"
19 #include "download-agent-client-mgr.h"
20 #include "download-agent-http-mgr.h"
21 #include "download-agent-http-misc.h"
22 #include "download-agent-http-msg-handler.h"
23 #include "download-agent-file.h"
24 #include "download-agent-plugin-conf.h"
25 #include "download-agent-plugin-http-interface.h"
26
27 da_result_t make_default_http_request_hdr(const char *url,
28                 char **user_request_header,
29                 int user_request_heaer_count,
30                 http_msg_request_t **out_http_msg_request,
31                 char *user_request_etag,
32                 char *user_request_temp_file_path);
33 da_result_t create_resume_http_request_hdr(stage_info *stage,
34                 http_msg_request_t **out_resume_request);
35
36 da_result_t start_new_transaction(stage_info *stage);
37 da_result_t set_http_request_hdr(stage_info *stage);
38 da_result_t make_transaction_info_and_start_transaction(stage_info *stage);
39
40 da_result_t pause_for_flow_control(stage_info *stage);
41 da_result_t unpause_for_flow_control(stage_info *stage);
42
43 da_result_t handle_any_input(stage_info *stage);
44 da_result_t handle_event_control(stage_info *stage, q_event_t *event);
45 da_result_t handle_event_http(stage_info *stage, q_event_t *event);
46 da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event);
47 da_result_t handle_event_http_final(stage_info *stage, q_event_t *event);
48 da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event);
49
50 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
51                 http_msg_response_t *http_msg_response);
52
53 da_result_t handle_event_abort(stage_info *stage);
54 da_result_t handle_event_cancel(stage_info *stage);
55 da_result_t handle_event_suspend(stage_info *stage);
56 da_result_t handle_event_resume(stage_info *stage);
57 da_result_t handle_http_hdr(stage_info *stage,
58                 http_msg_response_t *http_msg_response, int http_status);
59 da_result_t handle_http_status_code(stage_info *stage,
60                 http_msg_response_t *http_msg_response, int http_status);
61 da_result_t handle_http_body(stage_info *stage, char *body, int body_len);
62
63 da_result_t set_hdr_fields_on_download_info(stage_info *stage);
64
65 da_result_t _check_content_type_is_matched(stage_info *stage);
66 da_result_t _check_enough_memory_for_this_download(stage_info *stage);
67 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
68                 stage_info *stage);
69
70 da_result_t _check_resume_download_is_available(stage_info *stage,
71                 http_msg_response_t *new_http_msg_response);
72 da_result_t _check_this_partial_download_is_available(stage_info *stage,
73                 http_msg_response_t *new_http_msg_response);
74
75 da_result_t _cancel_transaction(stage_info *stage);
76 da_result_t _disconnect_transaction(stage_info *stage);
77
78 void __parsing_user_request_header(char *user_request_header,
79                 char **out_field, char **out_value);
80
81 http_mgr_t http_mgr;
82
83 da_result_t init_http_mgr(void)
84 {
85         da_result_t ret = DA_RESULT_OK;
86
87         DA_LOG_FUNC_START(HTTPManager);
88
89         if (http_mgr.is_http_init == DA_FALSE) {
90                 http_mgr.is_http_init = DA_TRUE;
91                 ret = PI_http_init();
92         }
93
94         return ret;
95 }
96
97
98 da_result_t request_to_abort_http_download(stage_info *stage)
99 {
100         da_result_t ret = DA_RESULT_OK;
101         q_event_t *q_event = DA_NULL;
102
103         DA_LOG_FUNC_START(HTTPManager);
104         if (!stage) {
105                 DA_LOG_ERR(HTTPManager, "Stage is NULL. download info is already destroyed");
106                 return DA_ERR_INVALID_ARGUMENT;
107         }
108
109         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
110         ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_ABORT, &q_event);
111         if (ret != DA_RESULT_OK) {
112                 DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
113                 goto ERR;
114         } else {
115                 DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
116                 Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event);
117         }
118
119 ERR:
120         return ret;
121 }
122
123 void deinit_http_mgr(void)
124 {
125         DA_LOG_FUNC_START(HTTPManager);
126
127         if (http_mgr.is_http_init == DA_TRUE) {
128                 http_mgr.is_http_init = DA_FALSE;
129                 PI_http_deinit();
130         }
131
132         return;
133 }
134
135 da_result_t request_http_download(stage_info *stage)
136 {
137         da_result_t ret = DA_RESULT_OK;
138
139         int slot_id = DA_INVALID_ID;
140         http_state_t http_state = 0;
141         da_bool_t need_wait = DA_TRUE;
142
143         queue_t *queue = DA_NULL;
144         req_dl_info *req_info = DA_NULL;
145
146         DA_LOG_FUNC_START(HTTPManager);
147
148         slot_id = GET_STAGE_DL_ID(stage);
149         queue = GET_DL_QUEUE(slot_id);
150         req_info = GET_STAGE_TRANSACTION_INFO(stage);
151
152         DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(slot_id));
153
154         CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD, stage);
155
156         do {
157                 ret = handle_any_input(stage);
158                 if (ret != DA_RESULT_OK) {
159                         if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) {
160                                 GET_REQUEST_HTTP_RESULT(req_info) = ret;
161                                 DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret);
162                         }
163                         _cancel_transaction(stage);
164                 }
165                 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
166                 http_state = GET_HTTP_STATE_ON_STAGE(stage);
167                 DA_LOG_VERBOSE(HTTPManager, "http_state = %d", http_state);
168                 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
169
170                 switch (http_state) {
171                 case HTTP_STATE_READY_TO_DOWNLOAD:
172                         ret = start_new_transaction(stage);
173                         if (ret != DA_RESULT_OK) {
174                                 if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) {
175                                         GET_REQUEST_HTTP_RESULT(req_info) = ret;
176                                         DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret);
177                                 }
178                                 DA_LOG(HTTPManager, "exiting with error...");
179                                 need_wait = DA_FALSE;
180                                 break;
181                         }
182
183                         CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_REQUESTED, stage);
184                         break;
185
186                 case HTTP_STATE_CANCELED:
187                 case HTTP_STATE_DOWNLOAD_FINISH:
188                 case HTTP_STATE_ABORTED:
189 #ifdef PAUSE_EXIT
190                 case HTTP_STATE_PAUSED:
191 #endif
192                         DA_LOG(HTTPManager, "exiting...");
193                         need_wait = DA_FALSE;
194                         break;
195
196                 default:
197                         break;
198                 }
199
200                 if (need_wait == DA_TRUE) {
201                         _da_thread_mutex_lock(&(queue->mutex_queue));
202                         if (DA_FALSE == GET_IS_Q_HAVING_DATA(queue)) {
203                                 unpause_for_flow_control(stage);
204
205 //                              DA_LOG(HTTPManager, "Waiting for input");
206                                 Q_goto_sleep(queue);
207 //                              DA_LOG(HTTPManager, "Woke up to receive new packet or control event");
208                         }
209                         _da_thread_mutex_unlock (&(queue->mutex_queue));
210
211                 }
212
213         } while (need_wait == DA_TRUE);
214
215         ret = GET_REQUEST_HTTP_RESULT(req_info);
216         DA_LOG(HTTPManager, "--------------Exiting request_http_download! ret = %d", ret);
217         return ret;
218 }
219
220 da_result_t request_to_cancel_http_download(stage_info *stage)
221 {
222         da_result_t ret = DA_RESULT_OK;
223         q_event_t *q_event = DA_NULL;
224
225         DA_LOG_FUNC_START(HTTPManager);
226
227         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
228         ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_CANCEL, &q_event);
229         if (ret != DA_RESULT_OK) {
230                 DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
231                 goto ERR;
232         } else {
233                 DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
234                 Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event);
235         }
236
237 ERR:
238         return ret;
239 }
240
241 da_result_t request_to_suspend_http_download(stage_info *stage)
242 {
243         da_result_t ret = DA_RESULT_OK;
244         http_state_t http_state = 0;
245         q_event_t *q_event = DA_NULL;
246
247         DA_LOG_FUNC_START(HTTPManager);
248
249         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
250         http_state = GET_HTTP_STATE_ON_STAGE(stage);
251         DA_LOG(HTTPManager, "http_state = %d", http_state);
252         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
253
254         switch (http_state) {
255         case HTTP_STATE_PAUSED:
256         case HTTP_STATE_REQUEST_PAUSE:
257                 DA_LOG_CRITICAL(HTTPManager, "Already paused. http_state = %d", http_state);
258                 ret = DA_ERR_ALREADY_SUSPENDED;
259                 break;
260
261         default:
262                 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
263                 ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_SUSPEND,
264                                 &q_event);
265                 if (ret != DA_RESULT_OK) {
266                         DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
267                         goto ERR;
268                 } else {
269                         DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
270                         Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)),
271                                         q_event);
272                 }
273
274                 break;
275         }
276
277 ERR:
278         return ret;
279 }
280
281 da_result_t request_to_resume_http_download(stage_info *stage)
282 {
283         da_result_t ret = DA_RESULT_OK;
284         http_state_t http_state = 0;
285         q_event_t *q_event = DA_NULL;
286
287         DA_LOG_FUNC_START(HTTPManager);
288
289         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
290         http_state = GET_HTTP_STATE_ON_STAGE(stage);
291         DA_LOG(HTTPManager, "[%d] http_state = %d", GET_STAGE_DL_ID(stage), http_state);
292         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
293
294         switch (http_state) {
295         case HTTP_STATE_PAUSED:
296                 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
297                 ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_RESUME,
298                                 &q_event);
299                 if (ret != DA_RESULT_OK) {
300                         DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
301                         goto ERR;
302                 } else {
303                         DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
304                         Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)),
305                                         q_event);
306                 }
307
308                 break;
309
310         case HTTP_STATE_REQUEST_PAUSE:
311                 DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. Previous pause is not finished. http_state = %d", GET_STAGE_DL_ID(stage), http_state);
312                 ret = DA_ERR_INVALID_STATE;
313
314                 break;
315
316         case HTTP_STATE_RESUMED:
317                 ret = DA_ERR_ALREADY_RESUMED;
318
319                 break;
320
321         default:
322                 DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. This is not a paused ID. http_state = %d", GET_STAGE_DL_ID(stage), http_state);
323                 ret = DA_ERR_INVALID_STATE;
324
325                 break;
326         }
327
328 ERR:
329         return ret;
330 }
331
332 da_result_t start_new_transaction(stage_info *stage)
333 {
334         da_result_t ret = DA_RESULT_OK;
335
336         ret = set_http_request_hdr(stage);
337         if (ret != DA_RESULT_OK)
338                 return ret;
339
340         ret = make_transaction_info_and_start_transaction(stage);
341         return ret;
342 }
343
344 da_result_t make_default_http_request_hdr(const char *url,
345                 char **user_request_header,
346                 int user_request_header_count,
347                 http_msg_request_t **out_http_msg_request,
348                 char *user_request_etag,
349                 char *user_request_temp_file_path)
350 {
351         da_result_t ret = DA_RESULT_OK;
352
353         http_msg_request_t *http_msg_request = NULL;
354         char *user_agent = NULL;
355
356         DA_LOG_FUNC_START(HTTPManager);
357
358         if (!url) {
359                 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
360                 ret = DA_ERR_INVALID_URL;
361                 goto ERR;
362         }
363
364         ret = http_msg_request_create(&http_msg_request);
365         if (ret != DA_RESULT_OK)
366                 goto ERR;
367
368         ret = http_msg_request_set_url(http_msg_request, url);
369         if (ret != DA_RESULT_OK)
370                 goto ERR;
371
372         user_agent = get_user_agent();
373         if (user_agent)
374                 http_msg_request_add_field(http_msg_request, HTTP_FIELD_UAGENT,
375                                 user_agent);
376
377         http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
378         http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_CHARSET, "utf-8");
379
380         if (user_request_header && user_request_header_count > 0) {
381                 int i = 0;
382                 for (i = 0; i < user_request_header_count; i++)
383                 {
384                         char *field = NULL;
385                         char *value = NULL;
386                         __parsing_user_request_header(user_request_header[i],
387                                 &field, &value);
388                         if (field && value) {
389                                 http_msg_request_add_field(http_msg_request, field, value);
390                                 if (field) {
391                                         free(field);
392                                         field = NULL;
393                                 }
394                                 if (value) {
395                                         free(value);
396                                         value= NULL;
397                                 }
398                         } else {
399                                 if (field) {
400                                         free(field);
401                                         field = NULL;
402                                 }
403                                 if (value) {
404                                         free(value);
405                                         value= NULL;
406                                 }
407                                 DA_LOG_ERR(HTTPManager, "Fail to parse user request header");
408                         }
409                 }
410         } else
411                 DA_LOG(HTTPManager, "no user reqeust header inserted");
412
413         if (user_request_etag) {
414                 char buff[64] = {0,};
415                 unsigned long long size = 0;
416                 http_msg_request_add_field(http_msg_request,
417                                 HTTP_FIELD_IF_RANGE, user_request_etag);
418                 get_file_size(user_request_temp_file_path, &size);
419                 snprintf(buff, sizeof(buff)-1, "bytes=%llu-", size);
420                 http_msg_request_add_field(http_msg_request,
421                                                 HTTP_FIELD_RANGE, buff);
422         }
423
424         *out_http_msg_request = http_msg_request;
425
426 ERR:
427         if (ret != DA_RESULT_OK)
428                 http_msg_request_destroy(&http_msg_request);
429         if (user_agent)
430                 free(user_agent);
431         return ret;
432 }
433
434 da_result_t set_http_request_hdr(stage_info *stage)
435 {
436         da_result_t ret = DA_RESULT_OK;
437         req_dl_info *request_info = DA_NULL;
438
439         char *url = DA_NULL;
440         char **user_request_header = DA_NULL;
441         int user_request_header_count = 0;
442         char *user_request_etag = DA_NULL;
443         char *user_request_temp_file_path = DA_NULL;
444         http_msg_request_t* http_msg_request = NULL;
445
446         DA_LOG_FUNC_START(HTTPManager);
447
448         request_info = GET_STAGE_TRANSACTION_INFO(stage);
449
450         if (DA_NULL ==
451                         (url = GET_REQUEST_HTTP_REQ_URL(request_info))) {
452                 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
453                 ret = DA_ERR_INVALID_URL;
454                 goto ERR;
455         }
456
457         user_request_header = GET_REQUEST_HTTP_USER_REQUEST_HEADER(
458                         request_info);
459         user_request_header_count = GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(
460                         request_info);
461         user_request_etag = GET_REQUEST_HTTP_USER_REQUEST_ETAG(
462                         request_info);
463         user_request_temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(
464                                 request_info);
465         if (user_request_etag) {
466                 DA_LOG(HTTPManager, "user_request_etag[%s]",user_request_etag);
467         } else {
468                 DA_LOG_ERR(HTTPManager, "user_request_etag is NULL");
469         }
470         ret = make_default_http_request_hdr(url, user_request_header,
471                 user_request_header_count, &http_msg_request,
472                 user_request_etag, user_request_temp_file_path);
473         if (ret == DA_RESULT_OK)
474                 request_info->http_info.http_msg_request = http_msg_request;
475
476 ERR:
477         return ret;
478
479 }
480
481 da_result_t make_transaction_info_and_start_transaction(stage_info *stage)
482 {
483         da_result_t ret = DA_RESULT_OK;
484
485         int slot_id = DA_INVALID_ID;
486         req_dl_info *request_info = DA_NULL;
487
488         input_for_tranx_t *input_for_tranx = DA_NULL;
489
490         DA_LOG_FUNC_START(HTTPManager);
491
492         slot_id = GET_STAGE_DL_ID(stage);
493
494         request_info = GET_STAGE_TRANSACTION_INFO(stage);
495
496         if (GET_REQUEST_HTTP_REQ_URL(request_info) == DA_NULL) {
497                 DA_LOG_ERR(HTTPManager, "url is NULL");
498                 ret = DA_ERR_INVALID_URL;
499                 goto ERR;
500         }
501
502         input_for_tranx = (input_for_tranx_t*) calloc(1,
503                         sizeof(input_for_tranx_t));
504         if (input_for_tranx == DA_NULL) {
505                 ret = DA_ERR_FAIL_TO_MEMALLOC;
506                 goto ERR;
507         } else {
508                 input_for_tranx->proxy_addr = get_proxy_address();
509                 input_for_tranx->queue = GET_DL_QUEUE(slot_id);
510
511                 input_for_tranx->http_method = PI_HTTP_METHOD_GET;
512                 input_for_tranx->http_msg_request
513                                 = request_info->http_info.http_msg_request;
514         }
515
516         ret = PI_http_start_transaction(input_for_tranx,
517                         &(GET_REQUEST_HTTP_TRANS_ID(request_info)));
518         if (ret != DA_RESULT_OK)
519                 goto ERR;
520
521 ERR:
522         if (input_for_tranx) {
523                 free(input_for_tranx);
524                 input_for_tranx = DA_NULL;
525         }
526
527         return ret;
528 }
529
530 da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info)
531 {
532         char *url = DA_NULL;
533         char **user_request_header = DA_NULL;
534         int user_request_header_count = 0;
535         char *user_request_etag = DA_NULL;
536         char *user_request_temp_file_path = DA_NULL;
537         int dl_id = -1;
538         source_info_t *source_info = DA_NULL;
539
540         DA_LOG_FUNC_START(HTTPManager);
541
542         if (!stage) {
543                 DA_LOG_ERR(HTTPManager, "stage is NULL");
544                 return DA_ERR_INVALID_ARGUMENT;
545         }
546
547         source_info = GET_STAGE_SOURCE_INFO(stage);
548
549         url = source_info->source_info_type.source_info_basic->url;
550         user_request_header =
551                 source_info->source_info_type.source_info_basic->user_request_header;
552         user_request_header_count =
553                 source_info->source_info_type.source_info_basic->user_request_header_count;
554         dl_id = source_info->source_info_type.source_info_basic->dl_id;
555         user_request_etag = GET_DL_USER_ETAG(GET_STAGE_DL_ID(stage));
556         user_request_temp_file_path = GET_DL_USER_TEMP_FILE_PATH(GET_STAGE_DL_ID(stage));
557
558         DA_LOG(HTTPManager, "url [%s]", url);
559
560         if (url) {
561                 GET_REQUEST_HTTP_REQ_URL(out_info) = url;
562                 GET_REQUEST_HTTP_USER_REQUEST_HEADER(out_info) = user_request_header;
563                 GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(out_info) =
564                         user_request_header_count;
565                 GET_REQUEST_HTTP_USER_REQUEST_ETAG(out_info) =
566                                         user_request_etag;
567                 GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(out_info) =
568                                         user_request_temp_file_path;
569         } else {
570                 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
571                 return DA_ERR_INVALID_URL;
572         }
573
574         _da_thread_mutex_init(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)), NULL);
575
576         return DA_RESULT_OK;
577 }
578
579 da_result_t pause_for_flow_control(stage_info *stage)
580 {
581         return DA_RESULT_OK;
582 }
583
584 da_result_t unpause_for_flow_control(stage_info *stage)
585 {
586         da_result_t ret = DA_RESULT_OK;
587
588         //      DA_LOG_FUNC_START(HTTPManager);
589
590         PI_http_unpause_transaction(
591                         GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)));
592         return ret;
593 }
594 da_result_t handle_event_abort(stage_info *stage)
595 {
596         da_result_t ret = DA_RESULT_OK;
597         http_state_t state = 0;
598
599         DA_LOG_FUNC_START(HTTPManager);
600
601         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
602         state = GET_HTTP_STATE_ON_STAGE(stage);
603         DA_LOG(HTTPManager, "http_state = %d", state);
604         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
605         switch (state) {
606         case HTTP_STATE_READY_TO_DOWNLOAD:
607         case HTTP_STATE_REDIRECTED:
608         case HTTP_STATE_DOWNLOAD_REQUESTED:
609         case HTTP_STATE_DOWNLOAD_STARTED:
610         case HTTP_STATE_DOWNLOADING:
611         case HTTP_STATE_REQUEST_CANCEL:
612         case HTTP_STATE_REQUEST_PAUSE:
613         case HTTP_STATE_REQUEST_RESUME:
614         case HTTP_STATE_CANCELED:
615         case HTTP_STATE_PAUSED:
616         case HTTP_STATE_RESUMED:
617         case HTTP_STATE_ABORTED:
618                 /* IF the network session is terminated due to some error,
619                  * the state can be aborted.(data aborted case) */
620                 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
621                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_ABORTED, stage);
622                 _disconnect_transaction(stage);
623                 break;
624         case HTTP_STATE_DOWNLOAD_FINISH:
625                 break;
626         default:
627                 DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
628                 break;
629         }
630         return ret;
631 }
632
633 da_result_t handle_event_cancel(stage_info *stage)
634 {
635         da_result_t ret = DA_RESULT_OK;
636         http_state_t state = 0;
637
638         DA_LOG_FUNC_START(HTTPManager);
639
640         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
641         state = GET_HTTP_STATE_ON_STAGE(stage);
642         DA_LOG(HTTPManager, "http_state = %d", state);
643         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
644         switch (state) {
645         case HTTP_STATE_READY_TO_DOWNLOAD:
646                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
647                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
648                 break;
649
650         case HTTP_STATE_PAUSED:
651                 discard_download(stage);
652                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
653                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
654                 break;
655
656         case HTTP_STATE_DOWNLOAD_REQUESTED:
657         case HTTP_STATE_DOWNLOAD_STARTED:
658         case HTTP_STATE_DOWNLOADING:
659         case HTTP_STATE_REQUEST_RESUME:
660         case HTTP_STATE_RESUMED:
661                 _cancel_transaction(stage);
662                 CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_CANCEL, stage);
663                 break;
664
665         case HTTP_STATE_DOWNLOAD_FINISH:
666                 break;
667
668         case HTTP_STATE_REQUEST_CANCEL:
669                 DA_LOG(HTTPManager, "HTTP_STATE_REQUEST_CANCEL : cancel is already in progress... ");
670                 break;
671
672         default:
673                 DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
674                 break;
675         }
676
677         return ret;
678 }
679
680 da_result_t handle_event_suspend(stage_info *stage)
681 {
682         da_result_t ret = DA_RESULT_OK;
683         http_state_t http_state = 0;
684
685         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
686         http_state = GET_HTTP_STATE_ON_STAGE(stage);
687         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
688
689         switch (http_state) {
690         case HTTP_STATE_REQUEST_PAUSE:
691                 DA_LOG(HTTPManager, "already requested to pause! do nothing");
692                 break;
693
694         case HTTP_STATE_READY_TO_DOWNLOAD:
695                 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
696                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
697                 send_client_paused_info(GET_STAGE_DL_ID(stage));
698                 break;
699
700         default:
701                 //send_client_paused_info(GET_STAGE_DL_ID(stage));
702                 _cancel_transaction(stage);
703                 GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK;
704                 DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage));
705                 CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_PAUSE,stage);
706                 break;
707         }
708
709         return ret;
710 }
711
712 da_result_t handle_event_resume(stage_info *stage)
713 {
714         da_result_t ret = DA_RESULT_OK;
715         http_msg_request_t *resume_request = NULL;
716
717         http_state_t http_state = 0;
718
719         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
720         http_state = GET_HTTP_STATE_ON_STAGE(stage);
721         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
722
723         if (http_state != HTTP_STATE_PAUSED) {
724                 DA_LOG_ERR(HTTPManager, "Not HTTP_STATE_PAUSED! http_state = %d", http_state);
725                 ret = DA_ERR_INVALID_STATE;
726                 goto ERR;
727         }
728
729         GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK;
730         DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage));
731
732         CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_RESUME,stage);
733         CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
734
735         ret = create_resume_http_request_hdr(stage, &resume_request);
736         if (ret != DA_RESULT_OK)
737                 goto ERR;
738
739         if (GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request)
740                 free(GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request);
741
742         GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request
743                         = resume_request;
744
745         make_transaction_info_and_start_transaction(stage);
746
747 ERR:
748         return ret;
749
750 }
751
752 da_result_t create_resume_http_request_hdr(stage_info *stage,
753                 http_msg_request_t **out_resume_request)
754 {
755         da_result_t ret = DA_RESULT_OK;
756         da_bool_t b_ret = DA_FALSE;
757
758         req_dl_info *request_info = NULL;
759
760         http_msg_response_t *first_response = NULL;
761         http_msg_request_t *resume_request = NULL;
762
763         char *value = NULL;
764         char *url = NULL;
765         unsigned int downloaded_data_size = 0;
766         char downloaded_data_size_to_str[32] = { 0, };
767
768         char *etag_from_response = NULL;
769         char *date_from_response = NULL;
770
771         DA_LOG_FUNC_START(HTTPManager);
772
773         request_info = GET_STAGE_TRANSACTION_INFO(stage);
774
775         if (!(url = GET_REQUEST_HTTP_REQ_URL(GET_STAGE_TRANSACTION_INFO(stage)))) {
776                 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
777                 ret = DA_ERR_INVALID_URL;
778                 goto ERR;
779         }
780
781         first_response = request_info->http_info.http_msg_response;
782         if (first_response) {
783                 b_ret = http_msg_response_get_ETag(first_response, &value);
784                 if (b_ret) {
785                         etag_from_response = value;
786                         value = NULL;
787                         DA_LOG(HTTPManager, "[ETag][%s]", etag_from_response);
788                 }
789
790                 b_ret = http_msg_response_get_date(first_response, &value);
791                 if (b_ret) {
792                         date_from_response = value;
793                         value = NULL;
794                         DA_LOG(HTTPManager, "[Date][%s]", date_from_response);
795                 }
796
797                 downloaded_data_size
798                                 = GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage));
799                 DA_LOG(HTTPManager, "downloaded_data_size = %u", downloaded_data_size);
800                 snprintf(downloaded_data_size_to_str, sizeof(downloaded_data_size_to_str), "bytes=%u-",
801                                 downloaded_data_size);
802                 DA_LOG(HTTPManager, "downloaded_data_size_to_str = %s", downloaded_data_size_to_str);
803         }
804
805         ret = make_default_http_request_hdr(url, NULL, 0, &resume_request, NULL, NULL);
806         if (ret != DA_RESULT_OK)
807                 goto ERR;
808
809         if (etag_from_response) {
810                 http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE,
811                                 etag_from_response);
812         } else {
813                 if (date_from_response) {
814                         http_msg_request_add_field(resume_request,
815                                         HTTP_FIELD_IF_RANGE, date_from_response);
816                 }
817         }
818
819         if (strlen(downloaded_data_size_to_str) > 0)
820                 http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE,
821                                 downloaded_data_size_to_str);
822
823         *out_resume_request = resume_request;
824
825 ERR:
826         if (etag_from_response) {
827                 free(etag_from_response);
828                 etag_from_response = NULL;
829         }
830
831         if (date_from_response) {
832                 free(date_from_response);
833                 date_from_response = NULL;
834         }
835
836         return ret;
837 }
838
839 da_result_t handle_any_input(stage_info *stage)
840 {
841         da_result_t ret = DA_RESULT_OK;
842
843         int slot_id = GET_STAGE_DL_ID(stage);
844
845         queue_t *queue = DA_NULL;
846         q_event_t *event = DA_NULL;
847
848         //      DA_LOG_FUNC_START(HTTPManager);
849
850         queue = GET_DL_QUEUE(slot_id);
851
852         Q_pop_event(queue, &event);
853         if (event == DA_NULL) {
854                 DA_LOG(HTTPManager, "There is no data on the queue!");
855                 return DA_RESULT_OK;
856         }
857
858         switch (event->event_type) {
859         case Q_EVENT_TYPE_CONTROL:
860                 ret = handle_event_control(stage, event);
861                 break;
862
863         case Q_EVENT_TYPE_DATA_HTTP:
864                 ret = handle_event_http(stage, event);
865                 break;
866
867         case Q_EVENT_TYPE_DATA_DRM:
868                 break;
869
870         default:
871                 break;
872         }
873         Q_destroy_q_event(&event);
874
875         return ret;
876 }
877
878 da_result_t handle_event_control(stage_info *stage, q_event_t *event)
879 {
880         da_result_t ret = DA_RESULT_OK;
881
882         DA_LOG_FUNC_START(HTTPManager);
883
884         if (event->event_type == Q_EVENT_TYPE_CONTROL) {
885                 switch (event->type.q_event_control.control_type) {
886                 case Q_EVENT_TYPE_CONTROL_CANCEL:
887                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
888                         ret = handle_event_cancel(stage);
889                         break;
890
891                 case Q_EVENT_TYPE_CONTROL_SUSPEND:
892                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
893                         ret = handle_event_suspend(stage);
894                         break;
895
896                 case Q_EVENT_TYPE_CONTROL_RESUME:
897                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
898                         ret = handle_event_resume(stage);
899                         break;
900                 case Q_EVENT_TYPE_CONTROL_ABORT:
901                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
902                         ret = handle_event_abort(stage);
903                         break;
904                         /* Fixme: need to think how we use this type. For now, this type is not used. */
905                 case Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED:
906                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED");
907                         break;
908                 }
909         }
910
911         return ret;
912 }
913
914 da_result_t handle_event_http(stage_info *stage, q_event_t *event)
915 {
916         da_result_t ret = DA_RESULT_OK;
917         q_event_data_http_t *q_event_data_http = DA_NULL;
918
919         //      DA_LOG_FUNC_START(HTTPManager);
920
921         if (event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
922                 q_event_data_http = &(event->type.q_event_data_http);
923                 switch (q_event_data_http->data_type) {
924                 case Q_EVENT_TYPE_DATA_PACKET:
925                         ret = handle_event_http_packet(stage, event);
926
927                         break;
928
929                 case Q_EVENT_TYPE_DATA_FINAL:
930                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL");
931                         ret = handle_event_http_final(stage, event);
932
933                         break;
934
935                 case Q_EVENT_TYPE_DATA_ABORT:
936                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT");
937                         ret = handle_event_http_abort(stage, event);
938
939                         break;
940                 }
941         }
942         return ret;
943 }
944
945 da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event)
946 {
947         da_result_t ret = DA_RESULT_OK;
948         da_bool_t is_handle_hdr_success = DA_TRUE;
949         q_event_data_http_t *received_data = DA_NULL;
950
951         //      DA_LOG_FUNC_START(HTTPManager);
952
953         received_data = &(event->type.q_event_data_http);
954
955         if (received_data->http_response_msg) {
956                 ret = handle_http_hdr(stage, received_data->http_response_msg,
957                                 received_data->http_response_msg->status_code);
958                 if (DA_RESULT_OK != ret) {
959                         is_handle_hdr_success = DA_FALSE;
960                 }
961
962                 received_data->http_response_msg = NULL;
963         }
964
965         if (received_data->body_len > 0) {
966                 if (is_handle_hdr_success == DA_TRUE) {
967                         ret = handle_http_body(stage, received_data->body_data,
968                                         received_data->body_len);
969                 }
970                 /*For all cases body_data should be deleted*/
971                 free(received_data->body_data);
972                 received_data->body_data = DA_NULL;
973         }
974         return ret;
975 }
976
977 da_result_t handle_event_http_final(stage_info *stage, q_event_t *event)
978 {
979         da_result_t ret = DA_RESULT_OK;
980
981         http_state_t http_state = 0;
982         int slot_id = DA_INVALID_ID;
983
984         DA_LOG_FUNC_START(HTTPManager);
985
986         slot_id = GET_STAGE_DL_ID(stage);
987         _disconnect_transaction(stage);
988
989         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
990         http_state = GET_HTTP_STATE_ON_STAGE(stage);
991         DA_LOG(HTTPManager, "http_state = %d", http_state);
992         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
993
994         switch (http_state) {
995         case HTTP_STATE_REDIRECTED:
996                 CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage);
997                 break;
998
999         case HTTP_STATE_DOWNLOAD_REQUESTED:
1000                 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED");
1001                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1002                 break;
1003
1004         case HTTP_STATE_DOWNLOADING:
1005                 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOADING");
1006                 ret = file_write_complete(stage);
1007                 if (ret != DA_RESULT_OK) {
1008                         discard_download(stage);
1009                         goto ERR;
1010                 }
1011                 /*                      ret = _check_downloaded_file_size_is_same_with_header_content_size(stage);
1012                  if(ret != DA_RESULT_OK)
1013                  {
1014                  discard_download(stage) ;
1015                  goto ERR;
1016                  }
1017                  */
1018                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1019                 send_client_update_progress_info(
1020                                 slot_id,
1021                                 GET_DL_ID(slot_id),
1022                                 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
1023                                 );
1024                 break;
1025
1026         case HTTP_STATE_REQUEST_PAUSE:
1027                 if (GET_CONTENT_STORE_FILE_HANDLE(GET_STAGE_CONTENT_STORE_INFO(stage))) {
1028                         ret = file_write_complete(stage);
1029                         send_client_update_progress_info(
1030                                         slot_id,
1031                                         GET_DL_ID(slot_id),
1032                                         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
1033                                         );
1034
1035                         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1036                                         = DA_FALSE;
1037                 }
1038                 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
1039                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
1040                 send_client_paused_info(GET_STAGE_DL_ID(stage));
1041                 DA_LOG(HTTPManager, "Server Notification code is set to NULL");
1042                 break;
1043
1044         case HTTP_STATE_ABORTED:
1045         case HTTP_STATE_CANCELED:
1046                 discard_download(stage);
1047                 break;
1048
1049         case HTTP_STATE_REQUEST_CANCEL:
1050                 ret = file_write_complete(stage);
1051                 if (ret != DA_RESULT_OK)
1052                         goto ERR;
1053                 discard_download(stage);
1054                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage);
1055                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1056                 break;
1057
1058         default:
1059                 ret = file_write_complete(stage);
1060                 if (ret != DA_RESULT_OK)
1061                         goto ERR;
1062                 discard_download(stage);
1063                 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1064                 break;
1065         }
1066
1067 ERR:
1068         /* When file complete is failed */
1069         if (DA_RESULT_OK != ret) {
1070                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1071         }
1072         return ret;
1073 }
1074
1075 da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event)
1076 {
1077         da_result_t ret = DA_RESULT_OK;
1078         http_state_t http_state = 0;
1079         DA_LOG_FUNC_START(HTTPManager);
1080
1081         GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))
1082                 = event->type.q_event_data_http.error_type;
1083         DA_LOG_CRITICAL(HTTPManager, "set internal error code : [%d]", GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1084         _disconnect_transaction(stage);
1085
1086         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1087         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1088         DA_LOG(HTTPManager, "http_state = %d", http_state);
1089         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1090
1091         switch (http_state) {
1092         case HTTP_STATE_REQUEST_PAUSE:
1093                 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
1094                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
1095                 send_client_paused_info(GET_STAGE_DL_ID(stage));
1096                 ret = file_write_complete(stage);
1097                 if (ret != DA_RESULT_OK)
1098                         goto ERR;
1099                 break;
1100
1101         case HTTP_STATE_REQUEST_CANCEL:
1102                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
1103                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1104                 ret = file_write_complete(stage);
1105                 if (ret != DA_RESULT_OK)
1106                         goto ERR;
1107                 discard_download(stage);
1108                 break;
1109
1110         default:
1111                 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1112                 ret = file_write_complete(stage);
1113                 if (ret != DA_RESULT_OK)
1114                         goto ERR;
1115                 discard_download(stage);
1116                 break;
1117         }
1118 ERR:
1119         return ret;
1120 }
1121
1122 da_result_t handle_http_hdr(stage_info *stage,
1123                 http_msg_response_t *http_msg_response, int http_status)
1124 {
1125         da_result_t ret = DA_RESULT_OK;
1126         int slot_id = DA_INVALID_ID;
1127         http_state_t http_state = 0;
1128
1129         DA_LOG_FUNC_START(HTTPManager);
1130
1131         slot_id = GET_STAGE_DL_ID(stage);
1132
1133         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1134         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1135         DA_LOG(HTTPManager, "http_state = %d", http_state);
1136         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1137
1138         switch (http_state) {
1139         case HTTP_STATE_DOWNLOAD_REQUESTED:
1140         case HTTP_STATE_REQUEST_PAUSE:
1141         case HTTP_STATE_REQUEST_RESUME:
1142         case HTTP_STATE_REDIRECTED:
1143                 ret = handle_http_status_code(stage, http_msg_response,
1144                                 http_status);
1145                 if (ret != DA_RESULT_OK)
1146                         goto ERR;
1147                 break;
1148
1149         case HTTP_STATE_REQUEST_CANCEL:
1150                 DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state);
1151                 break;
1152
1153         default:
1154                 DA_LOG_ERR(HTTPManager, "http_state = %d", http_state);
1155                 goto ERR;
1156         }
1157
1158 ERR:
1159         return ret;
1160 }
1161
1162 da_result_t handle_http_status_code(stage_info *stage,
1163                 http_msg_response_t *http_msg_response, int http_status)
1164 {
1165         da_result_t ret = DA_RESULT_OK;
1166
1167         int slot_id = DA_INVALID_ID;
1168         req_dl_info *request_info = DA_NULL;
1169         http_state_t http_state = 0;
1170
1171         DA_LOG_FUNC_START(HTTPManager);
1172
1173         slot_id = GET_STAGE_DL_ID(stage);
1174         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1175
1176         GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response
1177                         = http_msg_response;
1178
1179         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1180         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1181         DA_LOG(HTTPManager, "http_state = %d", http_state);
1182         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1183
1184         store_http_status(slot_id, http_status);
1185
1186         switch (http_status) {
1187         case 200:
1188         case 201:
1189         case 202:
1190         case 203:
1191                 if (http_state == HTTP_STATE_REQUEST_RESUME)
1192                         clean_paused_file(stage);
1193                 ret = set_hdr_fields_on_download_info(stage);
1194                 if (ret != DA_RESULT_OK)
1195                         goto ERR;
1196                 ret = _check_content_type_is_matched(stage);
1197                 if (ret != DA_RESULT_OK)
1198                         goto ERR;
1199                 ret = _check_enough_memory_for_this_download(stage);
1200                 if (ret != DA_RESULT_OK)
1201                         goto ERR;
1202                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
1203                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
1204                 break;
1205
1206         case 206:
1207                 DA_LOG(HTTPManager, "HTTP Status is %d - Partial download for resume!",http_status);
1208                 /* The resume can be started with start API.
1209                  * So the state should be not HTTP_STATE_RESUME_REQUESTED but HTTP_STATE_DOWNLOAD_REQUESTED*/
1210                 if (http_state == HTTP_STATE_DOWNLOAD_REQUESTED) {
1211                         ret = _check_resume_download_is_available(stage,
1212                                         http_msg_response);
1213                         if (ret != DA_RESULT_OK)
1214                                 goto ERR;
1215                         CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
1216
1217                 } else if (http_state == HTTP_STATE_REQUEST_RESUME) {
1218                         ret = _check_this_partial_download_is_available(stage,
1219                                         http_msg_response);
1220                         if (ret != DA_RESULT_OK)
1221                                 goto ERR;
1222                         CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage);
1223                 } else {
1224                         DA_LOG_ERR(HTTPManager, "This download is not resumed, revoke");
1225                         ret = DA_ERR_INVALID_STATE;
1226                         goto ERR;
1227                 }
1228                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
1229                 break;
1230
1231         case 300:
1232         case 301:
1233         case 302:
1234         case 303:
1235         case 305:
1236         case 306:
1237         case 307:
1238                 DA_LOG(HTTPManager, "HTTP Status is %d - redirection!",http_status);
1239                 ret = exchange_url_from_header_for_redirection(stage, http_msg_response);
1240                 if (ret != DA_RESULT_OK)
1241                         goto ERR;
1242                 CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage);
1243                 http_msg_response_destroy(&http_msg_response);
1244                 break;
1245
1246         case 100:
1247         case 101:
1248         case 102:
1249         case 204:
1250         case 304:
1251                 DA_LOG(HTTPManager, "HTTP Status is %d - 204 means server got the request, but no content to reply back, 304 means not modified!",http_status);
1252                 ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT;
1253                 break;
1254
1255         case 416: // Requested range not satisfiable
1256         case 503:
1257         case 504:
1258         default:
1259                 GET_REQUEST_HTTP_RESULT(request_info)
1260                         = DA_ERR_UNREACHABLE_SERVER;
1261                 DA_LOG_CRITICAL(HTTPManager, "set internal error code : DA_ERR_UNREACHABLE_SERVER [%d]", DA_ERR_UNREACHABLE_SERVER);
1262                 break;
1263         }
1264
1265 ERR:
1266         return ret;
1267 }
1268
1269 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
1270                 http_msg_response_t *http_msg_response)
1271 {
1272         da_result_t ret = DA_RESULT_OK;
1273         char *location = DA_NULL;
1274
1275         DA_LOG_FUNC_START(HTTPManager);
1276
1277         if (http_msg_response_get_location(http_msg_response, &location)) {
1278                 DA_LOG(HTTPManager, "location  = %s\n", location);
1279                 GET_REQUEST_HTTP_REQ_LOCATION(GET_STAGE_TRANSACTION_INFO(stage)) = location;
1280         }
1281
1282         return ret;
1283 }
1284
1285 da_result_t handle_http_body(stage_info *stage, char *body, int body_len)
1286 {
1287         da_result_t ret = DA_RESULT_OK;
1288         http_state_t http_state = 0;
1289         int slot_id = DA_INVALID_ID;
1290
1291         //      DA_LOG_FUNC_START(HTTPManager);
1292
1293         slot_id = GET_STAGE_DL_ID(stage);
1294
1295         if (DA_RESULT_OK
1296                         != GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))) {
1297                 DA_LOG_CRITICAL(HTTPManager, "ignore because internal error code is set with [%d]",
1298                                 GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1299                 return ret;
1300         }
1301
1302         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1303         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1304         //      DA_LOG(HTTPManager, "http_state = %d", http_state);
1305         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1306
1307         if (http_state == HTTP_STATE_DOWNLOAD_STARTED) {
1308                 // resume case
1309                 if (GET_REQUEST_HTTP_USER_REQUEST_ETAG(GET_STAGE_TRANSACTION_INFO(stage)))
1310                         ret = start_file_writing_append_with_new_download(stage);
1311                 else
1312                         ret = start_file_writing(stage);
1313                 if (DA_RESULT_OK != ret)
1314                         goto ERR;
1315
1316                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage);
1317                 send_client_update_dl_info(
1318                                 slot_id,
1319                                 GET_DL_ID(slot_id),
1320                                 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1321                                 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1322                                 GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1323                                 GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1324                                 GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)),
1325                                 GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage))
1326                                 );
1327         } else if (http_state == HTTP_STATE_RESUMED) {
1328                 ret = start_file_writing_append(stage);
1329                 if (DA_RESULT_OK != ret)
1330                         goto ERR;
1331
1332                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage);
1333                 send_client_update_dl_info(
1334                                 slot_id,
1335                                 GET_DL_ID(slot_id),
1336                                 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1337                                 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1338                                 GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1339                                 GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1340                                 GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)),
1341                                 GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage))
1342                                 );
1343         }
1344
1345         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1346         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1347         //      DA_LOG(HTTPManager, "http_state = %d", http_state);
1348         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1349
1350         switch (http_state) {
1351         case HTTP_STATE_REDIRECTED:
1352                 DA_LOG(HTTPManager, "Just ignore http body, because this body is not for redirection one.");
1353                 break;
1354
1355         case HTTP_STATE_DOWNLOADING:
1356                 /* Should this function before updating download info
1357                  * Because it extract mime type at once only if first download updating at client */
1358                 ret = file_write_ongoing(stage, body, body_len);
1359                 if (ret != DA_RESULT_OK)
1360                         goto ERR;
1361                 if ((DA_TRUE ==
1362                                 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)))) {
1363                         send_client_update_progress_info(
1364                                         slot_id,
1365                                         GET_DL_ID(slot_id),
1366                                         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
1367                                         );
1368
1369                         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1370                                         = DA_FALSE;
1371                 }
1372                 break;
1373
1374         case HTTP_STATE_REQUEST_PAUSE:
1375                 ret = file_write_ongoing(stage, body, body_len);
1376                 if (ret != DA_RESULT_OK)
1377                         goto ERR;
1378                 break;
1379
1380         default:
1381                 DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state);
1382
1383                 goto ERR;
1384         }
1385
1386 ERR:
1387         return ret;
1388 }
1389
1390 /* Function should be renamed , as it is actually not setting the header fields in download info */
1391 da_result_t set_hdr_fields_on_download_info(stage_info *stage)
1392 {
1393         da_result_t ret = DA_RESULT_OK;
1394         da_bool_t b_ret = DA_FALSE;
1395
1396         req_dl_info *request_info = DA_NULL;
1397         http_msg_response_t *http_msg_response = NULL;
1398
1399         char *value = NULL;
1400         unsigned long long size = 0;
1401
1402         DA_LOG_FUNC_START(HTTPManager);
1403
1404         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1405
1406         http_msg_response
1407                         = request_info->http_info.http_msg_response;
1408         if (!http_msg_response) {
1409                 DA_LOG_ERR(HTTPManager, "There is no header data!!");
1410                 ret = DA_ERR_INVALID_ARGUMENT;
1411                 goto ERR;
1412         }
1413
1414         b_ret = http_msg_response_get_content_type(http_msg_response, &value);
1415         if (b_ret) {
1416                 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
1417                 value = NULL;
1418                 DA_LOG_VERBOSE(HTTPManager, "[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
1419         }
1420
1421         b_ret = http_msg_response_get_content_length(http_msg_response,
1422                         &size);
1423         if (b_ret) {
1424                 GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = size;
1425                 size = 0;
1426                 DA_LOG_VERBOSE(HTTPManager, "[Content-Length][%d] - stored", GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
1427         }
1428
1429         b_ret = http_msg_response_get_ETag(http_msg_response, &value);
1430         if (b_ret) {
1431                 GET_REQUEST_HTTP_HDR_ETAG(request_info) = value;
1432                 value = NULL;
1433                 DA_LOG_VERBOSE(HTTPManager, "[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info));
1434         }
1435
1436 ERR:
1437         return ret;
1438 }
1439
1440 da_result_t _check_content_type_is_matched(stage_info *stage)
1441 {
1442         da_result_t ret = DA_RESULT_OK;
1443         req_dl_info *request_info = DA_NULL;
1444         source_info_t *source_info = DA_NULL;
1445         char *content_type_from_server = DA_NULL;
1446
1447         DA_LOG_FUNC_START(HTTPManager);
1448
1449         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1450         source_info = GET_STAGE_SOURCE_INFO(stage);
1451
1452         content_type_from_server = GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info);
1453         if (content_type_from_server == DA_NULL) {
1454                 DA_LOG(HTTPManager, "http header has no Content-Type field, no need to compare");
1455                 return DA_RESULT_OK;
1456         }
1457
1458         return ret;
1459 }
1460
1461 da_result_t _check_enough_memory_for_this_download(stage_info *stage)
1462 {
1463         da_result_t ret = DA_RESULT_OK;
1464
1465         req_dl_info *request_info = DA_NULL;
1466
1467         long long cont_len = 0;
1468         da_storage_size_t memory;
1469
1470         DA_LOG_FUNC_START(HTTPManager);
1471
1472         memset(&memory, 0x00, sizeof(da_storage_size_t));
1473         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1474
1475         cont_len = (long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
1476         if (cont_len) {
1477                 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1478                 if (DA_RESULT_OK == ret) {
1479                         DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",memory.b_available,memory.b_size, cont_len);
1480                         if (memory.b_available < ((cont_len
1481                                         + SAVE_FILE_BUFFERING_SIZE_50KB)
1482                                         / memory.b_size)) /* 50KB buffering */
1483                         {
1484                                 ret = DA_ERR_DISK_FULL;
1485                                 goto ERR;
1486                         }
1487                 }
1488         }
1489
1490 ERR:
1491         return ret;
1492 }
1493
1494 da_result_t _check_this_partial_download_is_available(stage_info *stage,
1495                 http_msg_response_t *new_http_msg_response)
1496 {
1497         da_result_t ret = DA_RESULT_OK;
1498         da_bool_t b_ret = DA_FALSE;
1499         char *origin_ETag = NULL;
1500         char *new_ETag = NULL;
1501         unsigned long long remained_content_len = 0;
1502         da_storage_size_t memory;
1503         char *value = NULL;
1504         unsigned long long size = 0;
1505
1506         DA_LOG_FUNC_START(HTTPManager);
1507
1508         origin_ETag
1509                         = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage));
1510
1511         b_ret = http_msg_response_get_content_length(new_http_msg_response,
1512                         &size);
1513         if (b_ret) {
1514                 remained_content_len = size;
1515                 size = 0;
1516                 DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len);
1517         }
1518
1519         b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
1520         if (b_ret) {
1521                 new_ETag = value;
1522                 value = NULL;
1523                 DA_LOG(HTTPManager, "[new ETag][%s]", new_ETag);
1524         } else {
1525                 goto ERR;
1526         }
1527
1528         if (origin_ETag && new_ETag &&
1529                         0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) {
1530                 DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
1531                 /* FIXME Later : Need to detail error exception handling */
1532                 ret = DA_ERR_NETWORK_FAIL;
1533                 /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
1534                 goto ERR;
1535         }
1536
1537         if (remained_content_len) {
1538                 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1539                 if (DA_RESULT_OK == ret) {
1540                         DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
1541                                         memory.b_available,memory.b_size, remained_content_len);
1542                         if (memory.b_available < ((remained_content_len
1543                                         + SAVE_FILE_BUFFERING_SIZE_50KB)
1544                                         / memory.b_size)) /* 50KB buffering */
1545                         {
1546                                 ret = DA_ERR_DISK_FULL;
1547                                 goto ERR;
1548                         }
1549                 }
1550         }
1551
1552 ERR:
1553         if (new_ETag) {
1554                 free(new_ETag);
1555                 new_ETag = DA_NULL;
1556         }
1557
1558         return ret;
1559 }
1560
1561 da_result_t _check_resume_download_is_available(stage_info *stage,
1562                 http_msg_response_t *new_http_msg_response)
1563 {
1564         da_result_t ret = DA_RESULT_OK;
1565         da_bool_t b_ret = DA_FALSE;
1566         char *origin_ETag = NULL;
1567         char *new_ETag = NULL;
1568         unsigned long long remained_content_len = 0;
1569         da_storage_size_t memory;
1570         char *value = NULL;
1571         unsigned long long size = 0;
1572         char *temp_file_path = DA_NULL;
1573         req_dl_info *request_info = DA_NULL;
1574
1575         DA_LOG_FUNC_START(HTTPManager);
1576
1577         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1578         origin_ETag
1579                         = GET_REQUEST_HTTP_USER_REQUEST_ETAG(request_info);
1580
1581         b_ret = http_msg_response_get_content_length(new_http_msg_response,
1582                         &size);
1583         if (b_ret) {
1584                 remained_content_len = size;
1585                 size = 0;
1586                 DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len);
1587         }
1588
1589         b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
1590         if (b_ret) {
1591                 new_ETag = value;
1592                 value = NULL;
1593                 DA_LOG(HTTPManager, "[new ETag][%s]", new_ETag);
1594         } else {
1595                 goto ERR;
1596         }
1597
1598         if (origin_ETag && new_ETag &&
1599                         0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) {
1600                 DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
1601                 /* FIXME Later : Need to detail error exception handling */
1602                 ret = DA_ERR_NETWORK_FAIL;
1603                 /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
1604                 goto ERR;
1605         }
1606
1607         if (remained_content_len) {
1608                 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1609                 if (DA_RESULT_OK == ret) {
1610                         DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
1611                                         memory.b_available,memory.b_size, remained_content_len);
1612                         if (memory.b_available < ((remained_content_len
1613                                         + SAVE_FILE_BUFFERING_SIZE_50KB)
1614                                         / memory.b_size)) /* 50KB buffering */
1615                         {
1616                                 ret = DA_ERR_DISK_FULL;
1617                                 goto ERR;
1618                         }
1619                 }
1620         }
1621         b_ret = http_msg_response_get_content_type(new_http_msg_response, &value);
1622         if (b_ret) {
1623                 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
1624                 value = NULL;
1625                 DA_LOG(HTTPManager, "[Content-Type][%s]",
1626                                 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
1627         }
1628         temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info);
1629         get_file_size(temp_file_path, &size);
1630         GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) =   remained_content_len + size;
1631         DA_LOG(HTTPManager, "[Content-Length][%d]",
1632                         GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
1633
1634
1635 ERR:
1636         if (new_ETag) {
1637                 free(new_ETag);
1638                 new_ETag = DA_NULL;
1639         }
1640
1641         return ret;
1642 }
1643
1644
1645 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
1646                 stage_info *stage)
1647 {
1648         da_result_t ret = DA_RESULT_OK;
1649
1650         req_dl_info *request_info = DA_NULL;
1651         file_info *file_info_data = DA_NULL;
1652
1653         char *real_file_path = DA_NULL;
1654         unsigned long long content_size_from_real_file = 0;
1655         unsigned long long content_size_from_http_header = 0;
1656
1657         DA_LOG_FUNC_START(HTTPManager);
1658
1659         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1660         file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
1661
1662         content_size_from_http_header
1663                         = GET_CONTENT_STORE_FILE_SIZE(file_info_data);
1664
1665         if (content_size_from_http_header > 0) {
1666                 real_file_path
1667                                 = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data);
1668
1669                 get_file_size(real_file_path,
1670                                 &content_size_from_real_file);
1671
1672                 if (content_size_from_real_file
1673                                 != content_size_from_http_header) {
1674                         DA_LOG_ERR(HTTPManager, "size from header = %llu, real size = %llu, DA_ERR_MISMATCH_CONTENT_SIZE",
1675                                         content_size_from_http_header, content_size_from_real_file);
1676                         ret = DA_ERR_MISMATCH_CONTENT_SIZE;
1677                 }
1678         }
1679
1680         return ret;
1681 }
1682
1683 da_result_t _disconnect_transaction(stage_info *stage)
1684 {
1685         da_result_t ret = DA_RESULT_OK;
1686         int transaction_id = DA_INVALID_ID;
1687
1688         DA_LOG_FUNC_START(HTTPManager);
1689
1690         transaction_id
1691                         = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1692
1693         DA_LOG(HTTPManager, "transaction_id = %d slot_id = %d", transaction_id, GET_STAGE_DL_ID(stage));
1694
1695         if (transaction_id != DA_INVALID_ID) {
1696                 ret = PI_http_disconnect_transaction(transaction_id);
1697                 GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage))
1698                                 = DA_INVALID_ID;
1699         }
1700
1701         return ret;
1702 }
1703
1704 da_result_t _cancel_transaction(stage_info *stage)
1705 {
1706         da_result_t ret = DA_RESULT_OK;
1707         int transaction_id = DA_INVALID_ID;
1708
1709         DA_LOG_FUNC_START(HTTPManager);
1710
1711         transaction_id
1712                         = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1713
1714         DA_LOG(HTTPManager, "transaction_id = %d", transaction_id);
1715
1716         if (transaction_id != DA_INVALID_ID) {
1717                 http_state_t state = 0;
1718                 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1719                 state = GET_HTTP_STATE_ON_STAGE(stage);
1720                 if (state <= HTTP_STATE_DOWNLOAD_REQUESTED)
1721                         ret = PI_http_cancel_transaction(transaction_id, DA_TRUE);
1722                 else
1723                         ret = PI_http_cancel_transaction(transaction_id, DA_FALSE);
1724                 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1725         }
1726
1727         return ret;
1728 }
1729
1730 void __parsing_user_request_header(char *user_request_header,
1731                 char **out_field, char **out_value)
1732 {
1733         int len = 0;
1734         char *pos = NULL;
1735         char *temp_pos = NULL;
1736         char *field = NULL;
1737         char *value = NULL;
1738
1739         DA_LOG_FUNC_START(HTTPManager);
1740
1741         if (!user_request_header) {
1742                 DA_LOG_ERR(HTTPManager, "user_request_header is NULL");
1743                 goto ERR;
1744         }
1745
1746         pos = strchr(user_request_header, ':');
1747         if (!pos) {
1748                 DA_LOG_ERR(HTTPManager, "Fail to parse");
1749                 goto ERR;
1750         }
1751         temp_pos = (char *)user_request_header;
1752         while (*temp_pos)
1753         {
1754                 if (temp_pos == pos || *temp_pos == ' ') {
1755                         len =  temp_pos - user_request_header;
1756                         break;
1757                 }
1758                 temp_pos++;
1759         }
1760         if (len < 1) {
1761                 DA_LOG_ERR(HTTPManager, "Wrong field name");
1762                 goto ERR;
1763         }
1764         field = (char *)calloc(1, len + 1);
1765         if (!field) {
1766                 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1767                 goto ERR;
1768         }
1769         strncpy(field, user_request_header, len);
1770         pos++;
1771         while (*pos)
1772         {
1773                 if (*pos != ' ')
1774                         break;
1775                 pos++;
1776         }
1777         len = strlen(pos) + 1;
1778         value = (char *)calloc(1, len + 1);
1779         if (!value) {
1780                 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1781                 goto ERR;
1782         }
1783         strncpy(value, pos, len);
1784         *out_field = field;
1785         *out_value = value;
1786         DA_LOG(HTTPManager, "field[%s], value[%s]", field, value);
1787
1788         return;
1789 ERR:
1790         if (field) {
1791                 free(field);
1792                 field = NULL;
1793         }
1794         return;
1795 }
1796