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