Remove DRM dependency
[framework/web/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         default:
827                 break;
828         }
829
830         Q_destroy_q_event(&event);
831
832         return ret;
833 }
834
835 da_result_t handle_event_control(stage_info *stage, q_event_t *event)
836 {
837         da_result_t ret = DA_RESULT_OK;
838
839         DA_LOG_FUNC_START(HTTPManager);
840
841         if (event->event_type == Q_EVENT_TYPE_CONTROL) {
842                 switch (event->type.q_event_control.control_type) {
843                 case Q_EVENT_TYPE_CONTROL_CANCEL:
844                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
845                         ret = handle_event_cancel(stage);
846                         break;
847
848                 case Q_EVENT_TYPE_CONTROL_SUSPEND:
849                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
850                         ret = handle_event_suspend(stage);
851                         break;
852
853                 case Q_EVENT_TYPE_CONTROL_RESUME:
854                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
855                         ret = handle_event_resume(stage);
856                         break;
857                 case Q_EVENT_TYPE_CONTROL_ABORT:
858                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
859                         ret = handle_event_abort(stage);
860                         break;
861                         /* Fixme: need to think how we use this type. For now, this type is not used. */
862                 case Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED:
863                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED");
864                         break;
865                 }
866         }
867
868         return ret;
869 }
870
871 da_result_t handle_event_http(stage_info *stage, q_event_t *event)
872 {
873         da_result_t ret = DA_RESULT_OK;
874         q_event_data_http_t *q_event_data_http = DA_NULL;
875
876         //      DA_LOG_FUNC_START(HTTPManager);
877
878         if (event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
879                 q_event_data_http = &(event->type.q_event_data_http);
880                 switch (q_event_data_http->data_type) {
881                 case Q_EVENT_TYPE_DATA_PACKET:
882                         ret = handle_event_http_packet(stage, event);
883
884                         break;
885
886                 case Q_EVENT_TYPE_DATA_FINAL:
887                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL");
888                         ret = handle_event_http_final(stage, event);
889
890                         break;
891
892                 case Q_EVENT_TYPE_DATA_ABORT:
893                         DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT");
894                         ret = handle_event_http_abort(stage, event);
895
896                         break;
897                 }
898         }
899
900         return ret;
901 }
902
903 da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event)
904 {
905         da_result_t ret = DA_RESULT_OK;
906         da_bool_t is_handle_hdr_success = DA_TRUE;
907         q_event_data_http_t *received_data = DA_NULL;
908
909         //      DA_LOG_FUNC_START(HTTPManager);
910
911         received_data = &(event->type.q_event_data_http);
912
913         if (received_data->http_response_msg) {
914                 ret = handle_http_hdr(stage, received_data->http_response_msg,
915                                 received_data->http_response_msg->status_code);
916                 if (DA_RESULT_OK != ret) {
917                         is_handle_hdr_success = DA_FALSE;
918                 }
919
920                 received_data->http_response_msg = NULL;
921         }
922
923         if (received_data->body_len > 0) {
924                 if (is_handle_hdr_success == DA_TRUE) {
925                         ret = handle_http_body(stage, received_data->body_data,
926                                         received_data->body_len);
927                 }
928                 /*For all cases body_data should be deleted*/
929                 free(received_data->body_data);
930                 received_data->body_data = DA_NULL;
931         }
932
933         return ret;
934 }
935
936 da_result_t handle_event_http_final(stage_info *stage, q_event_t *event)
937 {
938         da_result_t ret = DA_RESULT_OK;
939
940         http_state_t http_state = 0;
941         int download_id = DA_INVALID_ID;
942
943         DA_LOG_FUNC_START(HTTPManager);
944
945         download_id = GET_STAGE_DL_ID(stage);
946         _disconnect_transaction(stage);
947
948         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
949         http_state = GET_HTTP_STATE_ON_STAGE(stage);
950         DA_LOG(HTTPManager, "http_state = %d", http_state);
951         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
952
953         switch (http_state) {
954         case HTTP_STATE_REDIRECTED:
955                 CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage);
956                 break;
957
958         case HTTP_STATE_DOWNLOAD_REQUESTED:
959                 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED");
960                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
961                 break;
962
963         case HTTP_STATE_DOWNLOADING:
964                 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOADING");
965                 ret = file_write_complete(stage);
966                 if (ret != DA_RESULT_OK) {
967                         discard_download(stage);
968                         goto ERR;
969                 }
970                 /*                      ret = _check_downloaded_file_size_is_same_with_header_content_size(stage);
971                  if(ret != DA_RESULT_OK)
972                  {
973                  discard_download(stage) ;
974                  goto ERR;
975                  }
976                  */
977                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
978                 send_client_update_downloading_info(
979                                 download_id,
980                                 GET_DL_REQ_ID(download_id),
981                                 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
982                                 DA_NULL);
983                 break;
984
985         case HTTP_STATE_REQUEST_PAUSE:
986                 if (GET_CONTENT_STORE_FILE_HANDLE(GET_STAGE_CONTENT_STORE_INFO(stage))) {
987                         ret = file_write_complete(stage);
988                         send_client_update_downloading_info(
989                                         download_id,
990                                         GET_DL_REQ_ID(download_id),
991                                         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
992                                         GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)));
993
994                         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
995                                         = DA_FALSE;
996                 }
997                 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
998                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
999                 send_client_da_state(download_id, DA_STATE_SUSPENDED,
1000                                 DA_RESULT_OK);
1001                 DA_LOG(HTTPManager, "Server Notification code is set to NULL");
1002                 break;
1003
1004         case HTTP_STATE_ABORTED:
1005         case HTTP_STATE_CANCELED:
1006                 discard_download(stage);
1007                 break;
1008
1009         case HTTP_STATE_REQUEST_CANCEL:
1010                 ret = file_write_complete(stage);
1011                 if (ret != DA_RESULT_OK)
1012                         goto ERR;
1013                 discard_download(stage);
1014                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage);
1015                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1016                 break;
1017
1018         default:
1019                 ret = file_write_complete(stage);
1020                 if (ret != DA_RESULT_OK)
1021                         goto ERR;
1022                 discard_download(stage);
1023                 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1024                 break;
1025         }
1026
1027 ERR:
1028         /* When file complete is failed */
1029         if (DA_RESULT_OK != ret) {
1030                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1031         }
1032         return ret;
1033 }
1034
1035 da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event)
1036 {
1037         da_result_t ret = DA_RESULT_OK;
1038         http_state_t http_state = 0;
1039
1040         DA_LOG_FUNC_START(HTTPManager);
1041
1042         GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))
1043                 = event->type.q_event_data_http.error_type;
1044         DA_LOG_CRITICAL(HTTPManager, "set internal error code : [%d]", GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1045         _disconnect_transaction(stage);
1046
1047         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1048         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1049         DA_LOG(HTTPManager, "http_state = %d", http_state);
1050         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1051
1052         switch (http_state) {
1053         case HTTP_STATE_REQUEST_PAUSE:
1054                 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
1055                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
1056                 send_client_da_state(GET_STAGE_DL_ID(stage),
1057                                 DA_STATE_SUSPENDED, DA_RESULT_OK);
1058                 ret = file_write_complete(stage);
1059                 if (ret != DA_RESULT_OK)
1060                         goto ERR;
1061                 break;
1062
1063         case HTTP_STATE_REQUEST_CANCEL:
1064                 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
1065                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1066                 ret = file_write_complete(stage);
1067                 if (ret != DA_RESULT_OK)
1068                         goto ERR;
1069                 discard_download(stage);
1070                 break;
1071
1072         default:
1073                 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1074                 ret = file_write_complete(stage);
1075                 if (ret != DA_RESULT_OK)
1076                         goto ERR;
1077                 discard_download(stage);
1078                 break;
1079         }
1080 ERR:
1081         return ret;
1082 }
1083
1084 da_result_t handle_http_hdr(stage_info *stage,
1085                 http_msg_response_t *http_msg_response, int http_status)
1086 {
1087         da_result_t ret = DA_RESULT_OK;
1088         int download_id = DA_INVALID_ID;
1089         http_state_t http_state = 0;
1090         char *response_header_data = DA_NULL;
1091
1092         DA_LOG_FUNC_START(HTTPManager);
1093
1094         download_id = GET_STAGE_DL_ID(stage);
1095
1096         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1097         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1098         DA_LOG(HTTPManager, "http_state = %d", http_state);
1099         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1100
1101         switch (http_state) {
1102         case HTTP_STATE_DOWNLOAD_REQUESTED:
1103         case HTTP_STATE_REQUEST_PAUSE:
1104         case HTTP_STATE_REQUEST_RESUME:
1105         case HTTP_STATE_REDIRECTED:
1106                 /* In case of manual download, this is first update.
1107                  * So, the client can know the mime type at second update */
1108                 if (DA_TRUE == is_this_client_manual_download_type() &&
1109                                 http_msg_response) {
1110                         // SHOULD free response_header_data when it is not used any more
1111                         response_header_data = get_http_response_header_raw(http_msg_response);
1112                         send_client_update_dl_info(
1113                                 download_id,
1114                                 GET_DL_REQ_ID(download_id),
1115                                 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1116                                 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1117                                 DA_NULL,
1118                                 response_header_data,
1119                                 DA_NULL);
1120                         if (response_header_data) {
1121                                 free(response_header_data);
1122                                 response_header_data = NULL;
1123                         }
1124                 }
1125                 ret = handle_http_status_code(stage, http_msg_response,
1126                                 http_status);
1127                 if (ret != DA_RESULT_OK)
1128                         goto ERR;
1129                 break;
1130
1131         case HTTP_STATE_REQUEST_CANCEL:
1132                 DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state);
1133                 break;
1134
1135         default:
1136                 DA_LOG_ERR(HTTPManager, "http_state = %d", http_state);
1137                 goto ERR;
1138         }
1139
1140 ERR:
1141         return ret;
1142 }
1143
1144 da_result_t handle_http_status_code(stage_info *stage,
1145                 http_msg_response_t *http_msg_response, int http_status)
1146 {
1147         da_result_t ret = DA_RESULT_OK;
1148
1149         int download_id = DA_INVALID_ID;
1150         req_dl_info *request_info = DA_NULL;
1151         http_state_t http_state = 0;
1152
1153         DA_LOG_FUNC_START(HTTPManager);
1154
1155         download_id = GET_STAGE_DL_ID(stage);
1156         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1157
1158         GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response
1159                         = http_msg_response;
1160
1161         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1162         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1163         DA_LOG(HTTPManager, "http_state = %d", http_state);
1164         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1165
1166         switch (http_status) {
1167         case 200:
1168         case 201:
1169         case 202:
1170         case 203:
1171                 if (http_state == HTTP_STATE_REQUEST_RESUME)
1172                         clean_paused_file(stage);
1173                 ret = set_hdr_fields_on_download_info(stage);
1174                 if (ret != DA_RESULT_OK)
1175                         goto ERR;
1176                 ret = _check_content_type_is_matched(stage);
1177                 if (ret != DA_RESULT_OK)
1178                         goto ERR;
1179                 ret = _check_enough_memory_for_this_download(stage);
1180                 if (ret != DA_RESULT_OK)
1181                         goto ERR;
1182                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
1183                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
1184                 break;
1185
1186         case 206:
1187                 DA_LOG(HTTPManager, "HTTP Status is %d - Partial download for resume!",http_status);
1188                 if (http_state != HTTP_STATE_REQUEST_RESUME) {
1189                         DA_LOG_ERR(HTTPManager, "This download is not resumed, revoke");
1190                         ret = DA_ERR_INVALID_STATE;
1191                         goto ERR;
1192                 }
1193                 ret = _check_this_partial_download_is_available(stage,
1194                                 http_msg_response);
1195                 if (ret != DA_RESULT_OK)
1196                         goto ERR;
1197                 CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage);
1198                 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
1199                 break;
1200
1201         case 300:
1202         case 301:
1203         case 302:
1204         case 303:
1205         case 305:
1206         case 306:
1207         case 307:
1208                 DA_LOG(HTTPManager, "HTTP Status is %d - redirection!",http_status);
1209                 ret = exchange_url_from_header_for_redirection(stage, http_msg_response);
1210                 if (ret != DA_RESULT_OK)
1211                         goto ERR;
1212                 CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage);
1213                 http_msg_response_destroy(&http_msg_response);
1214                 break;
1215
1216         case 100:
1217         case 101:
1218         case 102:
1219         case 204:
1220         case 304:
1221                 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);
1222                 ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT;
1223                 break;
1224
1225         case 416: // Requested range not satisfiable
1226         case 503:
1227         case 504:
1228         default:
1229                 GET_REQUEST_HTTP_RESULT(request_info)
1230                         = DA_ERR_UNREACHABLE_SERVER;
1231                 DA_LOG_CRITICAL(HTTPManager, "set internal error code : DA_ERR_UNREACHABLE_SERVER [%d]", DA_ERR_UNREACHABLE_SERVER);
1232                 break;
1233         }
1234
1235 ERR:
1236         return ret;
1237 }
1238
1239 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
1240                 http_msg_response_t *http_msg_response)
1241 {
1242         da_result_t ret = DA_RESULT_OK;
1243         char *location = DA_NULL;
1244
1245         DA_LOG_FUNC_START(HTTPManager);
1246
1247         if (http_msg_response_get_location(http_msg_response, &location)) {
1248                 DA_LOG(HTTPManager, "location  = %s\n", location);
1249                 GET_REQUEST_HTTP_REQ_LOCATION(GET_STAGE_TRANSACTION_INFO(stage)) = location;
1250         }
1251
1252         return ret;
1253 }
1254
1255 da_result_t handle_http_body(stage_info *stage, char *body, int body_len)
1256 {
1257         da_result_t ret = DA_RESULT_OK;
1258         http_state_t http_state = 0;
1259         int download_id = DA_INVALID_ID;
1260
1261         //      DA_LOG_FUNC_START(HTTPManager);
1262
1263         download_id = GET_STAGE_DL_ID(stage);
1264
1265         if (DA_RESULT_OK
1266                         != GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))) {
1267                 DA_LOG_CRITICAL(HTTPManager, "ignore because internal error code is set with [%d]",
1268                                 GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1269                 return ret;
1270         }
1271
1272         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1273         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1274         //      DA_LOG(HTTPManager, "http_state = %d", http_state);
1275         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1276
1277         if (http_state == HTTP_STATE_DOWNLOAD_STARTED) {
1278                 ret = start_file_writing(stage);
1279                 if (DA_RESULT_OK != ret)
1280                         goto ERR;
1281
1282                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage);
1283                 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
1284                                 DA_RESULT_OK);
1285                 send_client_update_dl_info(
1286                                 download_id,
1287                                 GET_DL_REQ_ID(download_id),
1288                                 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1289                                 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1290                                 GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1291                                 DA_NULL,
1292                                 DA_NULL);
1293         } else if (http_state == HTTP_STATE_RESUMED) {
1294                 ret = start_file_writing_append(stage);
1295                 if (DA_RESULT_OK != ret)
1296                         goto ERR;
1297
1298                 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage);
1299                 send_client_da_state(download_id, DA_STATE_RESUMED,
1300                                 DA_RESULT_OK);
1301                 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
1302                                 DA_RESULT_OK);
1303         }
1304
1305         _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1306         http_state = GET_HTTP_STATE_ON_STAGE(stage);
1307         //      DA_LOG(HTTPManager, "http_state = %d", http_state);
1308         _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1309
1310         switch (http_state) {
1311         case HTTP_STATE_REDIRECTED:
1312                 DA_LOG(HTTPManager, "Just ignore http body, because this body is not for redirection one.");
1313                 break;
1314
1315         case HTTP_STATE_DOWNLOADING:
1316                 /* Should this function before updating download info
1317                  * Because it extract mime type at once only if first download updating at client */
1318                 ret = file_write_ongoing(stage, body, body_len);
1319                 if (ret != DA_RESULT_OK)
1320                         goto ERR;
1321                 if (DA_TRUE == is_this_client_manual_download_type()) {
1322                         send_client_update_dl_info(
1323                                         download_id,
1324                                         GET_DL_REQ_ID(download_id),
1325                                         GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1326                                         body_len,
1327                                         GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1328                                         DA_NULL,
1329                                         body);
1330                 } else if ((DA_TRUE ==
1331                                 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)))) {
1332                         send_client_update_downloading_info(
1333                                         download_id,
1334                                         GET_DL_REQ_ID(download_id),
1335                                         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1336                                         DA_NULL);
1337
1338                         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1339                                         = DA_FALSE;
1340                 }
1341                 break;
1342
1343         case HTTP_STATE_REQUEST_PAUSE:
1344                 if (DA_TRUE == is_this_client_manual_download_type()) {
1345                         send_client_update_dl_info(
1346                                         download_id,
1347                                         GET_DL_REQ_ID(download_id),
1348                                         GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1349                                         GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1350                                         GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1351                                         body,
1352                                         DA_NULL);
1353                 } else {
1354                         ret = file_write_ongoing(stage, body, body_len);
1355                         if (ret != DA_RESULT_OK)
1356                         goto ERR;
1357                 }
1358                 break;
1359
1360         default:
1361                 DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state);
1362
1363                 goto ERR;
1364         }
1365
1366 ERR:
1367         return ret;
1368 }
1369
1370 /* Function should be renamed , as it is actually not setting the header fields in download info */
1371 da_result_t set_hdr_fields_on_download_info(stage_info *stage)
1372 {
1373         da_result_t ret = DA_RESULT_OK;
1374         da_bool_t b_ret = DA_FALSE;
1375
1376         req_dl_info *request_info = DA_NULL;
1377         http_msg_response_t *http_msg_response = NULL;
1378
1379         char *value = NULL;
1380         int int_value = 0;
1381
1382         DA_LOG_FUNC_START(HTTPManager);
1383
1384         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1385
1386         http_msg_response
1387                         = request_info->http_info.http_msg_response;
1388         if (!http_msg_response) {
1389                 DA_LOG_ERR(HTTPManager, "There is no header data!!");
1390                 ret = DA_ERR_INVALID_ARGUMENT;
1391                 goto ERR;
1392         }
1393
1394         b_ret = http_msg_response_get_content_type(http_msg_response, &value);
1395         if (b_ret) {
1396                 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
1397                 value = NULL;
1398                 DA_LOG(HTTPManager, "[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
1399         }
1400
1401         b_ret = http_msg_response_get_content_length(http_msg_response,
1402                         &int_value);
1403         if (b_ret) {
1404                 GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = int_value;
1405                 int_value = 0;
1406                 DA_LOG(HTTPManager, "[Content-Length][%d] - stored", GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
1407         }
1408
1409         b_ret = http_msg_response_get_ETag(http_msg_response, &value);
1410         if (b_ret) {
1411                 GET_REQUEST_HTTP_HDR_ETAG(request_info) = value;
1412                 value = NULL;
1413                 DA_LOG(HTTPManager, "[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info));
1414         }
1415
1416 ERR:
1417         return ret;
1418 }
1419
1420 da_result_t _check_content_type_is_matched(stage_info *stage)
1421 {
1422         da_result_t ret = DA_RESULT_OK;
1423         req_dl_info *request_info = DA_NULL;
1424         source_info_t *source_info = DA_NULL;
1425         char *content_type_from_server = DA_NULL;
1426
1427         DA_LOG_FUNC_START(HTTPManager);
1428
1429         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1430         source_info = GET_STAGE_SOURCE_INFO(stage);
1431
1432         content_type_from_server = GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info);
1433         if (content_type_from_server == DA_NULL) {
1434                 DA_LOG(HTTPManager, "http header has no Content-Type field, no need to compare");
1435                 return DA_RESULT_OK;
1436         }
1437
1438         return ret;
1439 }
1440
1441 da_result_t _check_enough_memory_for_this_download(stage_info *stage)
1442 {
1443         da_result_t ret = DA_RESULT_OK;
1444
1445         req_dl_info *request_info = DA_NULL;
1446
1447         long long cont_len = 0;
1448         da_storage_size_t memory;
1449
1450         DA_LOG_FUNC_START(HTTPManager);
1451
1452         memset(&memory, 0x00, sizeof(da_storage_size_t));
1453         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1454
1455         cont_len = (long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
1456         if (cont_len) {
1457                 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1458                 if (DA_RESULT_OK == ret) {
1459                         DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %lld",memory.b_available,memory.b_size, cont_len);
1460                         if (memory.b_available < ((cont_len
1461                                         + SAVE_FILE_BUFFERING_SIZE_50KB)
1462                                         / memory.b_size)) /* 50KB buffering */
1463                         {
1464                                 ret = DA_ERR_DISK_FULL;
1465                                 goto ERR;
1466                         }
1467                 }
1468         }
1469
1470 ERR:
1471         return ret;
1472 }
1473
1474 da_result_t _check_this_partial_download_is_available(stage_info *stage,
1475                 http_msg_response_t *new_http_msg_response)
1476 {
1477         da_result_t ret = DA_RESULT_OK;
1478         da_bool_t b_ret = DA_FALSE;
1479
1480         char *origin_ETag = NULL;
1481         char *new_ETag = NULL;
1482
1483         int remained_content_len = 0;
1484         da_storage_size_t memory;
1485
1486         char *value = NULL;
1487         int int_value = 0;
1488
1489         DA_LOG_FUNC_START(HTTPManager);
1490
1491         origin_ETag
1492                         = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage));
1493
1494         b_ret = http_msg_response_get_content_length(new_http_msg_response,
1495                         &int_value);
1496         if (b_ret) {
1497                 remained_content_len = int_value;
1498                 int_value = 0;
1499                 DA_LOG(HTTPManager, "[remained_content_len][%d]", remained_content_len);
1500         }
1501
1502         b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
1503         if (b_ret) {
1504                 new_ETag = value;
1505                 value = NULL;
1506                 DA_LOG(HTTPManager, "[new ETag][%s]", new_ETag);
1507         } else {
1508                 goto ERR;
1509         }
1510
1511         if (0 != strcmp(origin_ETag, new_ETag)) {
1512                 DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
1513                 /* FIXME Later : Need to detail error exception handling */
1514                 ret = DA_ERR_NETWORK_FAIL;
1515                 /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
1516                 goto ERR;
1517         }
1518
1519         if (remained_content_len) {
1520                 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1521                 if (DA_RESULT_OK == ret) {
1522                         DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %lld",memory.b_available,memory.b_size, remained_content_len );
1523                         if (memory.b_available < ((remained_content_len
1524                                         + SAVE_FILE_BUFFERING_SIZE_50KB)
1525                                         / memory.b_size)) /* 50KB buffering */
1526                         {
1527                                 ret = DA_ERR_DISK_FULL;
1528                                 goto ERR;
1529                         }
1530                 }
1531         }
1532
1533 ERR:
1534         if (new_ETag) {
1535                 free(new_ETag);
1536                 new_ETag = DA_NULL;
1537         }
1538
1539         return ret;
1540 }
1541
1542 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
1543                 stage_info *stage)
1544 {
1545         da_result_t ret = DA_RESULT_OK;
1546
1547         req_dl_info *request_info = DA_NULL;
1548         file_info *file_info_data = DA_NULL;
1549
1550         char *real_file_path = DA_NULL;
1551         int content_size_from_real_file = DA_INVALID_ID;
1552         unsigned int content_size_from_http_header = DA_INVALID_ID;
1553
1554         DA_LOG_FUNC_START(HTTPManager);
1555
1556         request_info = GET_STAGE_TRANSACTION_INFO(stage);
1557         file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
1558
1559         content_size_from_http_header
1560                         = GET_CONTENT_STORE_FILE_SIZE(file_info_data);
1561
1562         if (content_size_from_http_header > 0) {
1563                 real_file_path
1564                                 = GET_CONTENT_STORE_TMP_FILE_NAME(file_info_data);
1565                 get_file_size(real_file_path,
1566                                 &content_size_from_real_file);
1567
1568                 if ((unsigned int) content_size_from_real_file
1569                                 != content_size_from_http_header) {
1570                         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);
1571                         ret = DA_ERR_MISMATCH_CONTENT_SIZE;
1572                 }
1573         }
1574
1575         return ret;
1576 }
1577
1578 da_result_t _disconnect_transaction(stage_info *stage)
1579 {
1580         da_result_t ret = DA_RESULT_OK;
1581         int transaction_id = DA_INVALID_ID;
1582
1583         DA_LOG_FUNC_START(HTTPManager);
1584
1585         transaction_id
1586                         = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1587
1588         DA_LOG(HTTPManager, "transaction_id = %d download_id = %d", transaction_id, GET_STAGE_DL_ID(stage));
1589
1590         if (transaction_id != DA_INVALID_ID) {
1591                 ret = PI_http_disconnect_transaction(transaction_id);
1592                 GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage))
1593                                 = DA_INVALID_ID;
1594         }
1595
1596         return ret;
1597 }
1598
1599 da_result_t _cancel_transaction(stage_info *stage)
1600 {
1601         da_result_t ret = DA_RESULT_OK;
1602         int transaction_id = DA_INVALID_ID;
1603
1604         DA_LOG_FUNC_START(HTTPManager);
1605
1606         transaction_id
1607                         = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1608
1609         DA_LOG(HTTPManager, "transaction_id = %d", transaction_id);
1610
1611         if (transaction_id != DA_INVALID_ID) {
1612                 http_state_t state = 0;
1613                 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1614                 state = GET_HTTP_STATE_ON_STAGE(stage);
1615                 if (state <= HTTP_STATE_DOWNLOAD_REQUESTED)
1616                         ret = PI_http_cancel_transaction(transaction_id, DA_TRUE);
1617                 else
1618                         ret = PI_http_cancel_transaction(transaction_id, DA_FALSE);
1619                 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1620         }
1621
1622         return ret;
1623 }
1624
1625 void __parsing_user_request_header(char *user_request_header,
1626                 char **out_field, char **out_value)
1627 {
1628         int len = 0;
1629         char *pos = NULL;
1630         char *temp_pos = NULL;
1631         char *field = NULL;
1632         char *value = NULL;
1633
1634         DA_LOG_FUNC_START(HTTPManager);
1635
1636         if (!user_request_header) {
1637                 DA_LOG_ERR(HTTPManager, "user_request_header is NULL");
1638                 goto ERR;
1639         }
1640
1641         pos = strchr(user_request_header, ':');
1642         if (!pos) {
1643                 DA_LOG_ERR(HTTPManager, "Fail to parse");
1644                 goto ERR;
1645         }
1646         temp_pos = (char *)user_request_header;
1647         while (*temp_pos)
1648         {
1649                 if (temp_pos == pos || *temp_pos == ' ') {
1650                         len =  temp_pos - user_request_header;
1651                         break;
1652                 }
1653                 temp_pos++;
1654         }
1655         if (len < 1) {
1656                 DA_LOG_ERR(HTTPManager, "Wrong field name");
1657                 goto ERR;
1658         }
1659         field = (char *)calloc(1, len + 1);
1660         if (!field) {
1661                 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1662                 goto ERR;
1663         }
1664         strncpy(field, user_request_header, len);
1665         pos++;
1666         while (*pos)
1667         {
1668                 if (*pos != ' ')
1669                         break;
1670                 pos++;
1671         }
1672         len = strlen(pos) + 1;
1673         value = (char *)calloc(1, len + 1);
1674         if (!value) {
1675                 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1676                 goto ERR;
1677         }
1678         strncpy(value, pos, len);
1679         *out_field = field;
1680         *out_value = value;
1681         DA_LOG(HTTPManager, "field[%s], value[%s]", field, value);
1682
1683         return;
1684 ERR:
1685         if (field) {
1686                 free(field);
1687                 field = NULL;
1688         }
1689         if (value) {
1690                 free(value);
1691                 value = NULL;
1692         }
1693         return;
1694 }
1695