2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include "download-agent-dl-info.h"
25 #include "download-agent-file.h"
26 #include "download-agent-mime-util.h"
27 #include "download-agent-client-mgr.h"
28 #include "download-agent-http-msg-handler.h"
29 #include "download-agent-plugin-conf.h"
30 #include "download-agent-plugin-drm.h"
31 #include "download-agent-plugin-libcurl.h"
32 #include "download-provider-client-manager.h"
34 void __http_update_cb(http_raw_data_t *data, void *user_param);
35 static proxy_info_t *__get_proxy_info();
37 #define CONVERT_STR(NAME) (#NAME)
39 #define VCONF_KEY_PROXY_EXCEPTION_LIST "db/menu/network/server_network_settings/proxy_exceptional_address"
40 #define PROXY_EXCEPTION_LIST_DELIMITER ";"
41 #define HTTP_PREFIX "http://"
42 #define HTTPS_PREFIX "https://"
44 static const char *__get_state_str(http_state_t state)
48 case HTTP_STATE_READY_TO_DOWNLOAD:
49 str = CONVERT_STR(HTTP_STATE_READY_TO_DOWNLOAD);
51 case HTTP_STATE_REDIRECTED:
52 str = CONVERT_STR(HTTP_STATE_REDIRECTED);
54 case HTTP_STATE_DOWNLOAD_REQUESTED:
55 str = CONVERT_STR(HTTP_STATE_DOWNLOAD_REQUESTED);
57 case HTTP_STATE_DOWNLOAD_STARTED:
58 str = CONVERT_STR(HTTP_STATE_DOWNLOAD_STARTED);
60 case HTTP_STATE_DOWNLOADING:
61 str = CONVERT_STR(HTTP_STATE_DOWNLOADING);
63 case HTTP_STATE_DOWNLOAD_FINISH:
64 str = CONVERT_STR(HTTP_STATE_DOWNLOAD_FINISH);
66 case HTTP_STATE_REQUEST_CANCEL:
67 str = CONVERT_STR(HTTP_STATE_REQUEST_CANCEL);
69 case HTTP_STATE_REQUEST_PAUSE:
70 str = CONVERT_STR(HTTP_STATE_REQUEST_PAUSE);
72 case HTTP_STATE_REQUEST_RESUME:
73 str = CONVERT_STR(HTTP_STATE_REQUEST_RESUME);
75 case HTTP_STATE_CANCELED:
76 str = CONVERT_STR(HTTP_STATE_CANCELED);
78 case HTTP_STATE_FAILED:
79 str = CONVERT_STR(HTTP_STATE_FAILED);
81 case HTTP_STATE_PAUSED:
82 str = CONVERT_STR(HTTP_STATE_PAUSED);
84 case HTTP_STATE_RESUMED:
85 str = CONVERT_STR(HTTP_STATE_RESUMED);
87 case HTTP_STATE_ABORTED:
88 str = CONVERT_STR(HTTP_STATE_ABORTED);
90 case HTTP_STATE_WAIT_FOR_NET_ERR:
91 str = CONVERT_STR(HTTP_STATE_WAIT_FOR_NET_ERR);
94 str = "Unknown State";
100 // 0: not required, 1: required
101 static int __is_proxy_required(char *url)
103 char *parsed_url = NULL;
104 char *exception_list = vconf_get_str(VCONF_KEY_PROXY_EXCEPTION_LIST);
106 char *next_ptr = NULL;
107 char *next_ptr2 = NULL;
112 DA_LOGI("proxy exception list[%s]", exception_list);
114 if (url && strstr(url, HTTP_PREFIX))
115 parsed_url = url + strlen(HTTP_PREFIX);
116 else if (url && strstr(url, HTTPS_PREFIX))
117 parsed_url = url + strlen(HTTPS_PREFIX);
121 DA_LOGI("compared url[%s] parsed url[%s]", url, parsed_url);
123 ptr = strtok_r(exception_list, PROXY_EXCEPTION_LIST_DELIMITER, &next_ptr);
125 // Ignore protocol prefix
126 if (strstr(ptr, HTTP_PREFIX))
127 ptr = ptr + strlen(HTTP_PREFIX);
128 else if (strstr(ptr, HTTPS_PREFIX))
129 ptr = ptr + strlen(HTTPS_PREFIX);
132 if (ptr && strstr(ptr, "/"))
133 ptr = strtok_r(ptr, "/", &next_ptr2);
135 if (ptr && parsed_url && strncmp(parsed_url, ptr, strlen(ptr)) == 0) {
136 DA_LOGI("[%s/%s] is exist in exception list.", url, ptr);
137 free(exception_list);
141 ptr = strtok_r(NULL, PROXY_EXCEPTION_LIST_DELIMITER, &next_ptr);
144 free(exception_list);
146 DA_LOGI("There is no matched address in exception list");
151 void __init_http_info(http_info_t *http_info)
155 http_info->update_cb = __http_update_cb;
156 DA_MUTEX_INIT(&(http_info->mutex_state), DA_NULL);
157 DA_MUTEX_INIT(&(http_info->mutex_http), DA_NULL);
158 DA_COND_INIT(&(http_info->cond_http), DA_NULL);
160 DA_MUTEX_LOCK(&(http_info->mutex_state));
161 http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
162 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
165 void __parsing_user_request_header(char *user_request_header,
166 char **out_field, char **out_value)
170 char *temp_pos = NULL;
176 if (!user_request_header) {
177 DA_LOGE("NULL CHECK!: user_request_header");
181 pos = strchr(user_request_header, ':');
183 DA_LOGE("Fail to parse");
186 temp_pos = (char *)user_request_header;
188 if (temp_pos == pos || *temp_pos == ' ') {
189 len = temp_pos - user_request_header;
195 DA_LOGE("Wrong field name");
198 field = (char *)calloc(1, len + 1);
200 DA_LOGE("Fail to calloc");
203 strncpy(field, user_request_header, len);
212 DA_LOGE("Fail to copy pos");
217 DA_SECURE_LOGD("field[%s], value[%s]", field, value);
229 da_ret_t __set_http_request_hdr(req_info_t *req_info, http_info_t *http_info, file_info_t *file_info)
231 da_ret_t ret = DA_RESULT_OK;
232 http_msg_request_t *http_msg_request = NULL;
233 char *user_agent = NULL;
238 NULL_CHECK_RET(req_info);
239 NULL_CHECK_RET(http_info);
240 NULL_CHECK_RET(file_info);
241 NULL_CHECK_RET_OPT(req_info->url, DA_ERR_INVALID_URL);
242 count = req_info->req_header_count;
244 ret = http_msg_request_create(&http_msg_request);
245 if (ret != DA_RESULT_OK)
248 ret = http_msg_request_set_url(http_msg_request, req_info->url);
249 if (ret != DA_RESULT_OK)
252 ret = get_user_agent_string(&user_agent);
253 if (user_agent && ret == DA_RESULT_OK)
254 http_msg_request_add_field(http_msg_request,
255 HTTP_FIELD_UAGENT, user_agent);
258 http_msg_request_add_field(http_msg_request,
259 HTTP_FIELD_ACCEPT_LANGUAGE, "en");
260 http_msg_request_add_field(http_msg_request,
261 HTTP_FIELD_ACCEPT_CHARSET, "utf-8");
263 if (req_info->req_header && count > 0) {
265 for (i = 0; i < count; i++) {
268 __parsing_user_request_header(req_info->req_header[i],
270 if (field && value) {
271 http_msg_request_add_field(http_msg_request, field, value);
289 DA_LOGE("Fail to parse user request header");
293 if (req_info->etag) {
294 char buff[64] = {0,};
296 http_msg_request_add_field(http_msg_request,
297 HTTP_FIELD_IF_RANGE, req_info->etag);
298 get_file_size(req_info->temp_file_path, &size);
300 file_info->file_size_of_temp_file = size;
302 snprintf(buff, sizeof(buff)-1, "bytes=%llu-", size);
303 http_msg_request_add_field(http_msg_request,
304 HTTP_FIELD_RANGE, buff);
307 http_info->http_msg_request = http_msg_request;
311 if (http_msg_request)
312 http_msg_request_destroy(&http_msg_request);
318 da_ret_t __create_http_resume_hdr(req_info_t *req_info, http_info_t *http_info,
319 file_info_t *file_info)
321 da_ret_t ret = DA_RESULT_OK;
322 da_bool_t b_ret = DA_FALSE;
324 char temp_size_str[32] = { 0, };
325 char *etag_from_response = NULL;
326 char *date_from_response = NULL;
327 http_msg_response_t *first_response = NULL;
328 http_msg_request_t *resume_request = NULL;
329 http_msg_request_t *old_request = NULL;
333 first_response = http_info->http_msg_response;
334 if (first_response) {
335 b_ret = http_msg_response_get_ETag(first_response, &value);
337 etag_from_response = value;
339 DA_SECURE_LOGD("[ETag][%s]", etag_from_response);
341 b_ret = http_msg_response_get_date(first_response, &value);
343 date_from_response = value;
345 DA_LOGV("[Date][%s]", date_from_response);
347 DA_SECURE_LOGD("downloaded_size[%llu]", file_info->bytes_written_to_file);
348 snprintf(temp_size_str, sizeof(temp_size_str), "bytes=%llu-",
349 file_info->bytes_written_to_file);
350 DA_SECURE_LOGD("size str[%s]", temp_size_str);
351 free(first_response);
352 http_info->http_msg_response = DA_NULL;
354 old_request = http_info->http_msg_request;
356 http_info->http_msg_request = DA_NULL;
358 ret = __set_http_request_hdr(req_info, http_info, file_info);
359 if (ret != DA_RESULT_OK)
362 resume_request = http_info->http_msg_request;
363 if (etag_from_response) {
364 http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE,
367 if (date_from_response) {
368 http_msg_request_add_field(resume_request,
369 HTTP_FIELD_IF_RANGE, date_from_response);
373 if (strlen(temp_size_str) > 0)
374 http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE,
378 if (etag_from_response) {
379 free(etag_from_response);
380 etag_from_response = NULL;
382 if (date_from_response) {
383 free(date_from_response);
384 date_from_response = NULL;
390 da_ret_t __start_transaction(da_info_t *da_info)
392 da_ret_t ret = DA_RESULT_OK;
393 http_info_t *http_info;
397 DA_LOGE("NULL CHECK!: da_info");
398 return DA_ERR_INVALID_ARGUMENT;
400 http_info = da_info->http_info;
402 DA_LOGE("NULL CHECK!: http_info");
403 return DA_ERR_INVALID_ARGUMENT;
405 http_info->http_method = HTTP_METHOD_GET;
407 // Check exception list for proxy
408 if (__is_proxy_required(da_info->req_info->url))
409 http_info->proxy_info = __get_proxy_info();
411 http_info->proxy_info = NULL;
413 ret = PI_http_start(da_info);
418 da_ret_t __start_resume_transaction(da_info_t *da_info)
420 da_ret_t ret = DA_RESULT_OK;
421 http_info_t *http_info = DA_NULL;
422 file_info_t *file_info = DA_NULL;
423 req_info_t *req_info = DA_NULL;
425 NULL_CHECK_RET(da_info);
426 http_info = da_info->http_info;
427 NULL_CHECK_RET(http_info);
428 file_info = da_info->file_info;
429 NULL_CHECK_RET(file_info);
430 req_info = da_info->req_info;
431 NULL_CHECK_RET(req_info);
433 ret = __create_http_resume_hdr(req_info, http_info,
435 if (ret != DA_RESULT_OK)
438 reset_http_info_for_resume(http_info);
439 if (file_info->file_path) {
440 req_info->temp_file_path = strdup(file_info->file_path);
442 DA_LOGE("file_path cannot be NULL in resume case");
443 return DA_ERR_INVALID_ARGUMENT;
445 ret = __start_transaction(da_info);
450 da_ret_t __start_new_transaction(da_info_t *da_info)
452 da_ret_t ret = DA_RESULT_OK;
455 DA_LOGE("NULL CHECK!: da_info");
456 return DA_ERR_INVALID_ARGUMENT;
459 ret = __set_http_request_hdr(da_info->req_info, da_info->http_info, da_info->file_info);
460 if (ret != DA_RESULT_OK)
463 ret = __start_transaction(da_info);
467 int __check_wait_for_auto_retry(http_info_t *http_info)
469 da_ret_t ret = DA_RESULT_OK;
472 NULL_CHECK_RET_OPT(http_info, 0);
473 gettimeofday(&tp, NULL);
474 ts.tv_sec = tp.tv_sec + DA_MAX_TIME_OUT;
475 ts.tv_nsec = tp.tv_usec * 1000;
476 DA_LOGI("Network Fail case, wait for a while");
478 DA_MUTEX_LOCK(&(http_info->mutex_state));
479 http_info->state = HTTP_STATE_WAIT_FOR_NET_ERR;
480 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
481 DA_MUTEX_LOCK(&(http_info->mutex_http));
482 ret = pthread_cond_timedwait(&(http_info->cond_http),
483 &(http_info->mutex_http), &ts);
484 DA_MUTEX_UNLOCK(&(http_info->mutex_http));
485 if (ret == ETIMEDOUT) {
486 DA_LOGI("Waiting is done by timeout");
487 } else if (ret != 0) {
488 DA_LOGE("fail to pthread_cond_waittime[%d]", ret);
490 DA_LOGI("Waiting is done by control");
491 DA_MUTEX_LOCK(&(http_info->mutex_state));
492 DA_LOGI("http_state[%s]", __get_state_str(http_info->state));
493 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
500 // In download thread
501 da_ret_t request_http_download(da_info_t *da_info)
503 da_ret_t ret = DA_RESULT_OK;
504 req_info_t *req_info = DA_NULL;
505 http_info_t *http_info = DA_NULL;
506 http_state_t http_state = HTTP_STATE_READY_TO_DOWNLOAD;
507 da_bool_t need_wait = DA_TRUE;
511 NULL_CHECK_RET(da_info);
512 req_info = da_info->req_info;
513 NULL_CHECK_RET(req_info);
514 http_info = da_info->http_info;
515 NULL_CHECK_RET(http_info);
516 __init_http_info(http_info);
519 DA_MUTEX_LOCK(&(http_info->mutex_state));
520 http_state = http_info->state;
521 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
522 DA_LOGD("http_state[%s][%d]", __get_state_str(http_info->state), da_info->da_id);
523 switch (http_state) {
524 case HTTP_STATE_READY_TO_DOWNLOAD:
525 DA_MUTEX_LOCK(&(http_info->mutex_state));
526 http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED;
527 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
528 ret = __start_new_transaction(da_info);
529 DA_MUTEX_LOCK(&(http_info->mutex_state));
530 http_state = http_info->state;
531 DA_LOGD("http_state[%s][%d]", __get_state_str(http_info->state), da_info->da_id);
532 http_info->error_code = ret;
533 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
534 if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) {
535 DA_LOGE("Network failed");
536 if (__check_wait_for_auto_retry(http_info) == 1)
539 need_wait = DA_FALSE;
542 case HTTP_STATE_REDIRECTED:
543 case HTTP_STATE_DOWNLOAD_REQUESTED:
544 case HTTP_STATE_DOWNLOAD_STARTED:
545 case HTTP_STATE_DOWNLOADING:
546 case HTTP_STATE_REQUEST_PAUSE:
547 DA_LOGE("Cannot enter here:[%s][%d]",
548 __get_state_str(http_info->state), da_info->da_id);
550 case HTTP_STATE_REQUEST_CANCEL:
552 case HTTP_STATE_REQUEST_RESUME:
553 DA_MUTEX_LOCK(&(http_info->mutex_state));
554 http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
555 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
558 case HTTP_STATE_CANCELED:
559 need_wait = DA_FALSE;
560 ret = DA_RESULT_USER_CANCELED;
562 case HTTP_STATE_PAUSED:
563 DA_LOGD("error_code[%d]", http_info->error_code);
564 send_client_paused_info(da_info);
565 DA_LOGD("Waiting thread for paused state");
566 DA_MUTEX_LOCK(&(http_info->mutex_http));
567 pthread_cond_wait(&(http_info->cond_http), &(http_info->mutex_http));
568 DA_MUTEX_UNLOCK(&(http_info->mutex_http));
569 DA_LOGD("Wake up thread due to resume");
571 case HTTP_STATE_RESUMED:
572 DA_MUTEX_LOCK(&(http_info->mutex_state));
573 http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED;
574 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
575 ret = __start_resume_transaction(da_info);
576 DA_MUTEX_LOCK(&(http_info->mutex_state));
577 http_state = http_info->state;
578 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
579 if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) {
580 DA_LOGE("Network failed");
581 if (__check_wait_for_auto_retry(http_info) == 1)
584 need_wait = DA_FALSE;
587 case HTTP_STATE_DOWNLOAD_FINISH:
588 need_wait = DA_FALSE;
589 if (ret == DA_RESULT_OK)
590 ret = check_drm_convert(da_info->file_info);
592 case HTTP_STATE_FAILED:
593 if (ret == DA_ERR_NETWORK_FAIL) {
594 if (__check_wait_for_auto_retry(http_info) == 1)
597 need_wait = DA_FALSE;
599 need_wait = DA_FALSE;
602 case HTTP_STATE_ABORTED:
603 need_wait = DA_FALSE;
608 } while (need_wait == DA_TRUE);
609 DA_LOGD("Final http_state[%s][%d] err[%d]", __get_state_str(http_info->state), da_info->da_id, ret);
610 if (http_info->state != HTTP_STATE_PAUSED)
611 send_client_finished_info(da_info, ret);
612 DA_LOGI("=== Exiting http_download ret[%d] ===", ret);
616 da_ret_t __disconnect_transaction(http_info_t *http_info)
618 da_ret_t ret = DA_RESULT_OK;
620 ret = PI_http_disconnect(http_info);
624 da_ret_t __handle_event_abort(http_info_t *http_info)
626 da_ret_t ret = DA_RESULT_OK;
627 http_state_t state = 0;
631 DA_MUTEX_LOCK(&(http_info->mutex_state));
632 state = http_info->state;
633 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
634 DA_LOGV("http_state[%s]", __get_state_str(state));
637 case HTTP_STATE_READY_TO_DOWNLOAD:
638 case HTTP_STATE_REDIRECTED:
639 case HTTP_STATE_DOWNLOAD_REQUESTED:
640 case HTTP_STATE_DOWNLOAD_STARTED:
641 case HTTP_STATE_DOWNLOADING:
642 case HTTP_STATE_REQUEST_CANCEL:
643 case HTTP_STATE_REQUEST_PAUSE:
644 case HTTP_STATE_REQUEST_RESUME:
645 case HTTP_STATE_CANCELED:
646 case HTTP_STATE_PAUSED:
647 case HTTP_STATE_RESUMED:
648 case HTTP_STATE_ABORTED:
649 case HTTP_STATE_WAIT_FOR_NET_ERR:
650 /* IF the network session is terminated due to some error,
651 * the state can be aborted.(data aborted case) */
652 DA_MUTEX_LOCK(&(http_info->mutex_state));
653 http_info->state = HTTP_STATE_ABORTED;
654 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
655 __disconnect_transaction(http_info);
657 case HTTP_STATE_DOWNLOAD_FINISH:
660 DA_LOGE("Cannot enter here");
666 da_ret_t __check_enough_memory(http_info_t *http_info, req_info_t *req_info)
668 da_ret_t ret = DA_RESULT_OK;
669 da_size_t cont_len = 0;
670 dp_client_slots_fmt *slot = DA_NULL;
671 const char *dir_path = DA_NULL;
672 const char *user_install_path = DA_NULL;
675 NULL_CHECK_RET(http_info);
676 cont_len = http_info->content_len_from_header;
677 NULL_CHECK_RET(req_info);
678 user_install_path = (const char*)req_info->install_path;
679 slot = req_info->user_client_data;
680 NULL_CHECK_RET(slot);
682 if (user_install_path) {
683 dir_path = user_install_path;
685 tzplatform_set_user(slot->credential.uid);
686 dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE;
687 tzplatform_reset_user();
689 ret = get_available_memory(dir_path, cont_len);
694 da_ret_t request_to_abort_http_download(da_info_t *da_info)
696 da_ret_t ret = DA_RESULT_OK;
697 ret = __handle_event_abort(da_info->http_info);
701 da_ret_t request_to_cancel_http_download(da_info_t *da_info)
703 da_ret_t ret = DA_RESULT_OK;
704 http_info_t *http_info = DA_NULL;
705 http_state_t http_state = 0;
710 NULL_CHECK_RET(da_info);
711 http_info = da_info->http_info;
712 NULL_CHECK_RET(http_info);
714 DA_MUTEX_LOCK(&(http_info->mutex_state));
715 http_state = http_info->state;
716 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
717 DA_LOGD("http_state[%s]", __get_state_str(http_state));
718 switch (http_state) {
719 case HTTP_STATE_READY_TO_DOWNLOAD:
720 ret = PI_http_cancel(http_info);
721 DA_MUTEX_LOCK(&(http_info->mutex_state));
722 http_info->state = HTTP_STATE_CANCELED;
723 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
725 case HTTP_STATE_WAIT_FOR_NET_ERR:
726 DA_MUTEX_LOCK(&(http_info->mutex_state));
727 http_info->state = HTTP_STATE_CANCELED;
728 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
729 DA_MUTEX_LOCK(&(http_info->mutex_http));
730 DA_COND_SIGNAL(&(http_info->cond_http));
731 DA_MUTEX_UNLOCK(&(http_info->mutex_http));
733 case HTTP_STATE_PAUSED:
734 DA_MUTEX_LOCK(&(http_info->mutex_state));
735 http_info->state = HTTP_STATE_CANCELED;
736 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
738 case HTTP_STATE_DOWNLOAD_REQUESTED:
739 case HTTP_STATE_DOWNLOAD_STARTED:
740 case HTTP_STATE_DOWNLOADING:
741 case HTTP_STATE_REQUEST_RESUME:
742 case HTTP_STATE_RESUMED:
743 DA_LOGI("Change http_info->state to HTTP_STATE_REQUEST_CANCEL");
744 mutex_ret = pthread_mutex_lock(&(http_info->mutex_state));
745 if (mutex_ret == 0) {
746 http_info->state = HTTP_STATE_REQUEST_CANCEL;
747 mutex_ret = pthread_mutex_unlock(&(http_info->mutex_state));
749 DA_LOGE("pthread_mutex_unlock FAIL with [%d]", mutex_ret);
751 DA_LOGE("pthread_mutex_lock FAIL with [%d]", mutex_ret);
753 ret = PI_http_cancel(http_info);
755 case HTTP_STATE_DOWNLOAD_FINISH:
756 ret = DA_ERR_INVALID_STATE;
758 case HTTP_STATE_REQUEST_CANCEL:
759 DA_LOGV("cancel is already in progress... ");
760 ret = DA_ERR_INVALID_STATE;
763 ret = DA_ERR_INVALID_STATE;
764 DA_LOGE("Cannot enter here");
770 da_ret_t request_to_suspend_http_download(da_info_t *da_info)
773 da_ret_t ret = DA_RESULT_OK;
774 http_info_t *http_info = DA_NULL;
775 http_state_t http_state = 0;
779 NULL_CHECK_RET(da_info);
780 http_info = da_info->http_info;
781 NULL_CHECK_RET(http_info);
783 DA_MUTEX_LOCK(&(http_info->mutex_state));
784 http_state = http_info->state;
785 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
786 DA_LOGD("http_state[%s]", __get_state_str(http_state));
788 switch (http_state) {
789 case HTTP_STATE_PAUSED:
790 case HTTP_STATE_REQUEST_PAUSE:
791 DA_LOGI("Already paused. http_state[%s]", __get_state_str(http_state));
792 ret = DA_ERR_ALREADY_SUSPENDED;
794 case HTTP_STATE_READY_TO_DOWNLOAD:
795 DA_LOGE("Download has not been started yet");
796 ret = DA_ERR_INVALID_STATE;
798 case HTTP_STATE_WAIT_FOR_NET_ERR:
799 DA_LOGD("error_code[%d]", http_info->error_code);
800 DA_MUTEX_LOCK(&(http_info->mutex_state));
801 http_info->state = HTTP_STATE_PAUSED;
802 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
803 DA_MUTEX_LOCK(&(http_info->mutex_http));
804 DA_COND_SIGNAL(&(http_info->cond_http));
805 DA_MUTEX_UNLOCK(&(http_info->mutex_http));
808 DA_MUTEX_LOCK(&(http_info->mutex_state));
809 http_info->state = HTTP_STATE_REQUEST_PAUSE;
810 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
811 DA_LOGD("error_code[%d]", http_info->error_code);
812 if (http_info->error_code != DA_ERR_NETWORK_FAIL)
813 ret = PI_http_pause(http_info);
814 DA_MUTEX_LOCK(&(http_info->mutex_state));
815 http_info->state = HTTP_STATE_PAUSED;
816 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
823 da_ret_t request_to_resume_http_download(da_info_t *da_info)
825 da_ret_t ret = DA_RESULT_OK;
826 http_info_t *http_info = DA_NULL;
827 http_state_t http_state = 0;
832 NULL_CHECK_RET(da_info);
833 http_info = da_info->http_info;
834 NULL_CHECK_RET(http_info);
836 DA_MUTEX_LOCK(&(http_info->mutex_state));
837 http_state = http_info->state;
838 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
839 DA_LOGD("http_state[%s]", __get_state_str(http_state));
841 switch (http_state) {
842 case HTTP_STATE_PAUSED:
843 DA_MUTEX_LOCK(&(http_info->mutex_state));
844 http_info->state = HTTP_STATE_RESUMED;
845 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
846 DA_LOGD("Wake up thread for paused state");
847 DA_MUTEX_LOCK(&(http_info->mutex_http));
848 DA_COND_SIGNAL(&(http_info->cond_http));
849 DA_MUTEX_UNLOCK(&(http_info->mutex_http));
850 DA_LOGD("error_code[%d]", http_info->error_code);
851 if (http_info->error_code != DA_ERR_NETWORK_FAIL) {
852 ret = PI_http_unpause(http_info);
853 if (ret != DA_RESULT_OK)
854 PI_http_cancel(http_info);
855 DA_LOGD("Change state to HTTP_STATE_DOWNLOADING");
856 DA_MUTEX_LOCK(&(http_info->mutex_state));
857 http_info->state = HTTP_STATE_DOWNLOADING;
858 DA_LOGD("Changed state[%s]", __get_state_str(http_info->state));
859 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
860 DA_LOGD("Complete to change state");
862 DA_LOGD("Can't resume[%d]", http_info->error_code);
865 case HTTP_STATE_REQUEST_PAUSE:
866 DA_LOGD("Waiting to handle pause request");
868 DA_MUTEX_LOCK(&(http_info->mutex_state));
869 http_state = http_info->state;
870 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
871 if (http_state == HTTP_STATE_PAUSED) {
872 DA_LOGD("Change to paused state");
873 ret = PI_http_unpause(http_info);
877 } while (retry_count < 10000);
878 if (ret != DA_RESULT_OK || retry_count >= 10000)
879 PI_http_cancel(http_info);
881 case HTTP_STATE_RESUMED:
882 ret = DA_ERR_ALREADY_RESUMED;
885 DA_LOGE("Fail to resume. Invalid state check. http_state[%s]",
886 __get_state_str(http_state));
887 ret = DA_ERR_INVALID_STATE;
888 // If resume is failed due to invalid state, the previous pause should be canceled.
889 PI_http_cancel(http_info);
895 da_ret_t __check_resume_download_is_available(
896 req_info_t *req_info, http_info_t *http_info, file_info_t *file_info)
898 da_ret_t ret = DA_RESULT_OK;
899 da_bool_t b_ret = DA_FALSE;
900 char *origin_ETag = NULL;
901 char *new_ETag = NULL;
902 da_size_t remained_content_len = 0;
905 char *temp_file_path = DA_NULL;
906 const char *dir_path = DA_NULL;
907 dp_client_slots_fmt *slot = DA_NULL;
910 NULL_CHECK_RET(req_info);
911 slot = req_info->user_client_data;
912 NULL_CHECK_RET(slot);
914 origin_ETag = req_info->etag;
916 b_ret = http_msg_response_get_content_length(http_info->http_msg_response,
919 remained_content_len = size;
921 DA_SECURE_LOGD("remained_content_len[%llu]", remained_content_len);
924 b_ret = http_msg_response_get_ETag(http_info->http_msg_response, &value);
928 DA_SECURE_LOGD("new ETag[%s]", new_ETag);
933 if (origin_ETag && new_ETag && strcmp(origin_ETag, new_ETag)) {
934 DA_LOGE("ETag is not identical! revoke!");
935 /* FIXME Later : Need to detail error exception handling */
936 ret = DA_ERR_NETWORK_FAIL;
937 /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
941 if (remained_content_len > 0) {
942 if (req_info->install_path)
943 dir_path = (const char *)req_info->install_path;
945 tzplatform_set_user(slot->credential.uid);
946 dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE;
947 tzplatform_reset_user();
949 ret = get_available_memory(dir_path, remained_content_len);
950 if (ret != DA_RESULT_OK)
954 if (!http_info->content_type_from_header) {
955 b_ret = http_msg_response_get_content_type(http_info->http_msg_response,
958 http_info->content_type_from_header = value;
960 DA_SECURE_LOGD("Content-Type[%s]",
961 http_info->content_type_from_header);
964 temp_file_path = req_info->temp_file_path;
965 if (!temp_file_path) {
966 DA_LOGE("Temporary file path cannot be NULL");
967 ret = DA_ERR_INVALID_ARGUMENT;
970 get_file_size(temp_file_path, &size);
971 http_info->content_len_from_header = remained_content_len + size;
972 DA_SECURE_LOGD("Content-Length[%llu]", http_info->content_len_from_header);
982 da_ret_t __check_content_type_is_matched(http_info_t *http_info)
984 da_ret_t ret = DA_RESULT_OK;
985 char *content_type_from_server = DA_NULL;
989 content_type_from_server = http_info->content_type_from_header;
990 if (content_type_from_server == DA_NULL) {
991 DA_LOGV("http header has no Content-Type field, no need to compare");
997 da_ret_t __handle_http_status_code(http_info_t *http_info,
998 file_info_t *file_info, req_info_t *req_info)
1000 da_ret_t ret = DA_RESULT_OK;
1001 http_state_t http_state = 0;
1002 http_msg_response_t *http_msg_response = DA_NULL;
1003 char *location = DA_NULL;
1004 char *if_range_str = DA_NULL;
1005 char *range_str = DA_NULL;
1006 int http_status = 0;
1008 NULL_CHECK_RET(http_info);
1009 NULL_CHECK_RET(file_info);
1010 NULL_CHECK_RET(req_info);
1011 DA_MUTEX_LOCK(&(http_info->mutex_state));
1012 http_state = http_info->state;
1013 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1014 DA_LOGD("http_state[%s]", __get_state_str(http_state));
1015 http_msg_response = http_info->http_msg_response;
1016 NULL_CHECK_RET(http_msg_response);
1017 http_status = http_msg_response->status_code;
1018 switch (http_status) {
1023 // Although expecting 206, 200 response is received. Remove temporary file and reset file info
1024 if (http_info->http_msg_request &&
1025 http_msg_request_get_if_range(http_info->http_msg_request, &if_range_str) == DA_TRUE &&
1026 http_msg_request_get_range(http_info->http_msg_request, &range_str) == DA_TRUE) {
1027 DA_LOGI("Server do not support if-range option");
1028 clean_paused_file(file_info);
1032 if (http_state == HTTP_STATE_REQUEST_RESUME)
1033 clean_paused_file(file_info);
1034 ret = __check_content_type_is_matched(http_info);
1035 if (ret != DA_RESULT_OK)
1037 ret = __check_enough_memory(http_info, req_info);
1038 if (ret != DA_RESULT_OK)
1040 DA_MUTEX_LOCK(&(http_info->mutex_state));
1041 http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
1042 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1046 DA_LOGV("HTTP Status is %d - Partial download for resume!", http_status);
1047 /* The resume can be started with start API.
1048 * So the state should be not HTTP_STATE_RESUME_REQUESTED but HTTP_STATE_DOWNLOAD_REQUESTED*/
1049 if (http_state == HTTP_STATE_DOWNLOAD_REQUESTED) {
1050 ret = __check_resume_download_is_available(req_info, http_info, file_info);
1051 if (ret != DA_RESULT_OK)
1053 DA_MUTEX_LOCK(&(http_info->mutex_state));
1054 http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
1055 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1057 } else if (http_state == HTTP_STATE_REQUEST_RESUME) {
1058 ///FIXME later : how get previous response header
1059 ///ret = __check_this_partial_download_is_available(http_info,
1060 /// previous_ http_msg_response);
1061 //if (ret != DA_RESULT_OK)
1063 DA_MUTEX_LOCK(&(http_info->mutex_state));
1064 http_info->state = HTTP_STATE_RESUMED;
1065 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1067 DA_LOGE("This download is not resumed, revoke");
1068 ret = DA_ERR_INVALID_STATE;
1080 DA_LOGV("HTTP Status is %d - redirection!", http_status);
1081 if (http_msg_response_get_location(http_msg_response, &location)) {
1082 DA_SECURE_LOGD("location = %s\n", location);
1083 http_info->location_url = location;
1084 DA_LOGI("[TEST] location_url[%p]", http_info->location_url);
1086 DA_MUTEX_LOCK(&(http_info->mutex_state));
1087 http_info->state = HTTP_STATE_REDIRECTED;
1088 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1089 http_msg_response_destroy(&http_msg_response);
1090 http_info->http_msg_response = DA_NULL;
1098 DA_LOGV("HTTP Status is %d - 204 server got the request, \
1099 but no content to reply back, \
1100 304 means not modified!", http_status);
1101 if (!req_info->cache)
1102 ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT;
1105 case 416: // Requested range not satisfiable
1109 ret = DA_ERR_UNREACHABLE_SERVER;
1110 DA_LOGI("set internal error code : DA_ERR_UNREACHABLE_SERVER");
1118 da_ret_t __check_before_downloading(da_info_t *da_info, http_state_t state)
1120 da_ret_t ret = DA_RESULT_OK;
1121 http_info_t *http_info = DA_NULL;
1122 req_info_t *req_info = DA_NULL;
1123 file_info_t *file_info = DA_NULL;
1124 NULL_CHECK_RET(da_info);
1125 http_info = da_info->http_info;
1126 NULL_CHECK_RET(http_info);
1127 req_info = da_info->req_info;
1128 NULL_CHECK_RET(req_info);
1129 file_info = da_info->file_info;
1130 NULL_CHECK_RET(file_info);
1131 DA_LOGD("state:%s", __get_state_str(state));
1133 if (req_info->temp_file_path && file_info->bytes_written_to_file > 0) {
1134 ret = start_file_append(file_info);
1135 } else if (state == HTTP_STATE_DOWNLOAD_STARTED) {
1136 ret = start_file_writing(da_info);
1138 DA_LOGE("Cannot enter here!");
1139 ret = DA_ERR_INVALID_ARGUMENT;
1142 if (DA_RESULT_OK != ret)
1145 DA_MUTEX_LOCK(&(http_info->mutex_state));
1146 http_info->state = HTTP_STATE_DOWNLOADING;
1147 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1149 ret = send_client_update_dl_info(da_info);
1154 static void __handle_empty_file(da_info_t *da_info)
1156 char *transfer_encoding = DA_NULL;
1157 http_msg_response_t *http_msg_response = DA_NULL;
1159 NULL_CHECK(da_info);
1160 NULL_CHECK(da_info->http_info);
1162 http_msg_response = da_info->http_info->http_msg_response;
1163 NULL_CHECK(http_msg_response);
1165 if (http_msg_response->status_code == 200
1166 && http_msg_response_get_transfer_encoding(http_msg_response,
1167 &transfer_encoding) == DA_FALSE) {
1168 start_file_writing(da_info);
1169 DA_LOGD("Empty file");
1172 if (transfer_encoding)
1173 free(transfer_encoding);
1176 static proxy_info_t *__get_proxy_info()
1178 proxy_info_t *proxy_info = DA_NULL;
1179 char scheme[DA_MAX_SCHEME_LEN] = {0, };
1180 char user_name[DA_MAX_USER_NAME_LEN] = {0, };
1181 char password[DA_MAX_PASSWORD_LEN] = {0, };
1182 char host[DA_MAX_PROXY_ADDR_LEN] = {0, }; // ip:port
1183 char *proxy_uri = get_proxy_address(); // scheme://userinfo@ip:port
1186 if (proxy_uri && !strstr(proxy_uri, "0.0.0.0")) {
1187 proxy_info = (proxy_info_t *)calloc(1, sizeof(proxy_info_t));
1189 DA_LOGE("Failed to calloc");
1194 char *found = strrchr(proxy_uri, '@');
1196 size_t userinfo_len = strlen(proxy_uri) - strlen(found);
1197 char *userinfo = strndup(proxy_uri, userinfo_len);
1199 DA_LOGE("Failed to copy proxy_uri to userinfo");
1205 if (strstr(userinfo, SCHEME_DELIMETER))
1206 sscanf(userinfo, "%7[^:/]://%255[^:]:%255s", scheme, user_name, password);
1208 sscanf(userinfo, "%255[^:]:%255s", user_name, password);
1212 sscanf(found + 1, "%63s", host);
1213 if (strlen(host) == 0) {
1214 DA_LOGE("Invalid proxy address");
1220 if (strlen(scheme) == 0)
1221 strncpy(scheme, DEFAULT_SCHEME, DA_MAX_SCHEME_LEN - 1);
1223 ret = asprintf(&proxy_info->addr, "%s://%s", scheme, host);
1224 if (ret == -1 || proxy_info->addr == NULL) {
1225 DA_LOGE("Failed to set proxy_info->addr");
1231 proxy_info->addr = strdup(proxy_uri);
1232 DA_LOGI("proxy_info->addr[%s] will be used.", proxy_info->addr);
1234 proxy_info->user_name = strlen(user_name) > 0 ? strdup(user_name) : DA_NULL;
1235 proxy_info->password = strlen(password) > 0 ? strdup(password) : DA_NULL;
1241 DA_LOGI("host[%s] user_name[%s] password[***]", host, user_name);
1246 da_ret_t __handle_event_http_header(http_raw_data_t *raw_data, da_info_t *da_info)
1248 da_ret_t ret = DA_RESULT_OK;
1249 http_state_t http_state = 0;
1250 http_info_t *http_info = DA_NULL;
1251 file_info_t *file_info = DA_NULL;
1252 req_info_t *req_info = DA_NULL;
1253 http_msg_response_t *http_msg_response = DA_NULL;
1254 http_msg_t *http_msg = DA_NULL;
1256 char *mime_type = DA_NULL;
1257 char *etag = DA_NULL;
1258 char *cache_control = DA_NULL;
1259 char *last_modified = DA_NULL;
1260 char *file_name = DA_NULL;
1262 NULL_CHECK_RET(da_info);
1263 http_info = da_info->http_info;
1264 NULL_CHECK_RET(http_info);
1265 file_info = da_info->file_info;
1266 NULL_CHECK_RET(file_info);
1267 req_info = da_info->req_info;
1268 NULL_CHECK_RET(req_info);
1269 NULL_CHECK_RET(raw_data);
1271 http_msg = http_info->http_msg;
1272 NULL_CHECK_RET(http_msg);
1274 DA_MUTEX_LOCK(&(http_info->mutex_state));
1275 http_state = http_info->state;
1276 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1277 DA_LOGD("http_state[%s]", __get_state_str(http_state));
1278 http_msg_response = http_info->http_msg_response;
1279 switch (http_state) {
1280 case HTTP_STATE_DOWNLOAD_REQUESTED:
1281 case HTTP_STATE_REQUEST_PAUSE:
1282 case HTTP_STATE_REQUEST_RESUME:
1283 case HTTP_STATE_REDIRECTED:
1284 http_msg_response_get_content_length(http_msg_response, &size);
1286 __handle_empty_file(da_info);
1287 http_info->content_len_from_header = size;
1288 http_msg_response_get_content_type(http_msg_response, &mime_type);
1289 http_info->content_type_from_header = mime_type;
1291 file_info->mime_type = strdup(mime_type);
1292 http_msg_response_get_ETag(http_msg_response, &etag);
1293 http_info->etag_from_header = etag;
1295 http_msg_response_get_cache_control(http_msg_response, &cache_control);
1296 http_info->cache_control_from_header = cache_control;
1297 http_msg_response_get_last_modified(http_msg_response, &last_modified);
1298 http_info->last_modified_from_header = last_modified;
1300 http_msg_response_get_content_disposition(
1301 http_msg_response, http_msg, DA_NULL, &file_name);
1302 http_info->file_name_from_header = file_name;
1303 ret = __handle_http_status_code(http_info, file_info, req_info);
1304 if (ret != DA_RESULT_OK) {
1305 DA_LOGE("Fail to handle http status code");
1310 http_msg_response_get_RAF_mode(http_msg_response, &val);
1312 DA_LOGE("Fail to raf mode value from response header");
1314 DA_LOGI("[RAF] val[%s:%s]", HTTP_FIELD_RAF_MODE, val);
1315 if (strcmp(val, "yes") == 0) {
1316 DA_MUTEX_LOCK(&(http_info->mutex_state));
1317 http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
1318 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1319 ret = __check_before_downloading(da_info, http_info->state);
1320 if (ret != DA_RESULT_OK) {
1324 http_info->is_raf_mode_confirmed = DA_TRUE;
1325 ret = PI_http_set_file_name_to_curl(http_info->http_msg, file_info->file_path);
1326 if (ret != DA_RESULT_OK) {
1327 DA_LOGE("Fail to set file name to curl");
1336 case HTTP_STATE_REQUEST_CANCEL:
1337 DA_LOGV("Cancel is in progress.. http_state[%s]",
1338 __get_state_str(http_state));
1342 DA_LOGE("http_state[%s]", __get_state_str(http_state));
1347 if (ret != DA_RESULT_OK) {
1348 DA_LOGE("Request to cancel due to error[%d]", ret);
1349 PI_http_cancel(http_info);
1350 http_info->error_code = ret;
1351 discard_download(file_info);
1352 DA_MUTEX_LOCK(&(http_info->mutex_state));
1353 http_info->state = HTTP_STATE_FAILED;
1354 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1360 da_ret_t __handle_event_http_packet(http_raw_data_t *raw_data, da_info_t *da_info)
1362 da_ret_t ret = DA_RESULT_OK;
1363 http_state_t http_state = 0;
1364 http_info_t *http_info = DA_NULL;
1365 file_info_t *file_info = DA_NULL;
1370 NULL_CHECK_RET(da_info);
1371 http_info = da_info->http_info;
1372 NULL_CHECK_RET(http_info);
1373 file_info = da_info->file_info;
1374 NULL_CHECK_RET(file_info);
1375 NULL_CHECK_RET(raw_data);
1377 DA_MUTEX_LOCK(&(http_info->mutex_state));
1378 http_state = http_info->state;
1379 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1381 switch (http_state) {
1382 case HTTP_STATE_DOWNLOAD_STARTED:
1384 if (http_info->is_raf_mode_confirmed == DA_FALSE) {
1386 ret = __check_before_downloading(da_info, http_state);
1387 if (ret != DA_RESULT_OK)
1389 ret = file_write_ongoing(file_info,
1390 raw_data->body, raw_data->body_len);
1391 if (ret != DA_RESULT_OK)
1395 file_info->bytes_written_to_file =
1396 raw_data->received_len + file_info->file_size_of_temp_file;
1397 file_info->is_updated = DA_TRUE;
1400 ret = send_client_update_progress_info(da_info);
1401 DA_MUTEX_LOCK(&(http_info->mutex_state));
1402 http_state = HTTP_STATE_DOWNLOADING;
1403 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1405 case HTTP_STATE_RESUMED:
1406 DA_LOGD("http_state[%s]", __get_state_str(http_state));
1408 if (http_info->is_raf_mode_confirmed == DA_FALSE) {
1410 if (__check_before_downloading(da_info, http_state) == DA_RESULT_OK) {
1411 ret = file_write_ongoing(file_info,
1412 raw_data->body, raw_data->body_len);
1413 if (ret != DA_RESULT_OK)
1417 file_info->bytes_written_to_file =
1418 raw_data->received_len + file_info->file_size_of_temp_file;
1419 file_info->is_updated = DA_TRUE;
1422 ret = send_client_update_progress_info(da_info);
1424 DA_LOGD("Do nothing! Wait for changing state properly");
1427 case HTTP_STATE_REDIRECTED:
1428 DA_LOGV("http_state[%s]", __get_state_str(http_state));
1430 case HTTP_STATE_DOWNLOADING:
1432 if (http_info->is_raf_mode_confirmed == DA_FALSE) {
1434 /* Should this function before updating download info
1435 * Because it extract mime type at once only if first download updating at client */
1436 ret = file_write_ongoing(file_info,
1437 raw_data->body, raw_data->body_len);
1438 if (ret != DA_RESULT_OK)
1442 file_info->bytes_written_to_file =
1443 raw_data->received_len + file_info->file_size_of_temp_file;
1444 file_info->is_updated = DA_TRUE;
1447 // send event every 1 second.
1448 if ((t = time(DA_NULL)) > 0) {
1449 if ((localtime_r(&t, &lc_time)) != DA_NULL) {
1450 if (da_info->update_time != lc_time.tm_sec) {
1451 da_info->update_time = lc_time.tm_sec;
1452 ret = send_client_update_progress_info(da_info);
1455 DA_LOGE("Fail to call localtime");
1456 ret = send_client_update_progress_info(da_info);
1459 DA_LOGE("Fail to call time");
1460 ret = send_client_update_progress_info(da_info);
1463 case HTTP_STATE_REQUEST_PAUSE:
1465 if (http_info->is_raf_mode_confirmed == DA_FALSE) {
1467 DA_LOGV("http_state[%s]", __get_state_str(http_state));
1468 ret = file_write_ongoing(file_info,
1469 raw_data->body, raw_data->body_len);
1470 if (ret != DA_RESULT_OK)
1474 file_info->bytes_written_to_file =
1475 raw_data->received_len + file_info->file_size_of_temp_file;
1476 file_info->is_updated = DA_TRUE;
1482 DA_LOGE("Do nothing! http_state is in case[%s]",
1483 __get_state_str(http_state));
1487 if (ret != DA_RESULT_OK) {
1488 DA_LOGE("Request to cancel due to error[%d]", ret);
1489 PI_http_cancel(http_info);
1490 http_info->error_code = ret;
1491 discard_download(da_info->file_info);
1492 DA_MUTEX_LOCK(&(http_info->mutex_state));
1493 http_info->state = HTTP_STATE_FAILED;
1494 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1497 free(raw_data->body);
1502 da_ret_t __check_file_size_with_header_content_size(file_info_t *file_info)
1504 da_ret_t ret = DA_RESULT_OK;
1505 unsigned long long tmp_file_size = 0;
1509 if (file_info->file_size > 0) {
1511 #ifdef _ENABLE_OMA_DRM
1512 if (is_content_drm_dm(file_info->mime_type)) {
1513 /* FIXME Later : How can get the file size of DRM file. */
1518 get_file_size(file_info->file_path, &tmp_file_size);
1520 if (tmp_file_size != file_info->file_size) {
1521 DA_SECURE_LOGE("Real file size[%llu], MISMATCH CONTENT SIZE",
1523 ret = DA_ERR_MISMATCH_CONTENT_SIZE;
1529 da_ret_t __handle_event_http_final(http_raw_data_t *raw_data, da_info_t *da_info)
1531 da_ret_t ret = DA_RESULT_OK;
1532 http_state_t http_state = 0;
1533 http_info_t *http_info = DA_NULL;
1534 file_info_t *file_info = DA_NULL;
1538 NULL_CHECK_RET(da_info);
1539 http_info = da_info->http_info;
1540 NULL_CHECK_RET(http_info);
1541 file_info = da_info->file_info;
1542 NULL_CHECK_RET(file_info);
1543 NULL_CHECK_RET(raw_data);
1545 DA_MUTEX_LOCK(&(http_info->mutex_state));
1546 http_state = http_info->state;
1547 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1548 DA_LOGD("http_state[%s]", __get_state_str(http_state));
1550 switch (http_state) {
1551 case HTTP_STATE_REDIRECTED:
1552 DA_MUTEX_LOCK(&(http_info->mutex_state));
1553 http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
1554 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1556 case HTTP_STATE_DOWNLOAD_REQUESTED:
1557 DA_LOGV("case HTTP_STATE_DOWNLOAD_REQUESTED");
1558 DA_MUTEX_LOCK(&(http_info->mutex_state));
1559 http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
1560 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1562 case HTTP_STATE_DOWNLOAD_STARTED:
1563 case HTTP_STATE_DOWNLOADING:
1564 DA_LOGD("case HTTP_STATE_DOWNLOAD_STARTED or HTTP_STATE_DOWNLOADING");
1566 if (http_info->is_raf_mode_confirmed == DA_TRUE)
1567 ret = file_write_complete_for_raf(file_info);
1569 ret = file_write_complete(file_info);
1571 ret = file_write_complete(file_info);
1573 if (ret != DA_RESULT_OK) {
1574 discard_download(file_info);
1577 ret = __check_file_size_with_header_content_size(file_info);
1578 if (ret != DA_RESULT_OK) {
1579 discard_download(file_info) ;
1582 DA_MUTEX_LOCK(&(http_info->mutex_state));
1583 http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
1584 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1585 ret = send_client_update_progress_info(da_info);
1587 case HTTP_STATE_REQUEST_PAUSE:
1589 if (http_info->is_raf_mode_confirmed == DA_TRUE) {
1590 if (file_info->file_handle)
1591 ret = file_write_complete_for_raf(file_info);
1593 ret = file_write_complete(file_info);
1596 if (file_info->file_handle) {
1597 ret = file_write_complete(file_info);
1598 // send_client_update_progress_info(da_info);
1601 DA_MUTEX_LOCK(&(http_info->mutex_state));
1602 http_info->state = HTTP_STATE_PAUSED;
1603 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1605 case HTTP_STATE_ABORTED:
1606 case HTTP_STATE_CANCELED:
1607 discard_download(file_info);
1609 case HTTP_STATE_REQUEST_CANCEL:
1611 if (http_info->is_raf_mode_confirmed == DA_TRUE)
1612 ret = file_write_complete_for_raf(file_info);
1614 ret = file_write_complete(file_info);
1616 ret = file_write_complete(file_info);
1618 if (ret != DA_RESULT_OK)
1620 discard_download(file_info);
1621 DA_MUTEX_LOCK(&(http_info->mutex_state));
1622 http_info->state = HTTP_STATE_CANCELED;
1623 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1625 case HTTP_STATE_PAUSED:
1626 DA_LOGD("Remain paused stated");
1630 if (http_info->is_raf_mode_confirmed == DA_TRUE)
1631 ret = file_write_complete_for_raf(file_info);
1633 ret = file_write_complete(file_info);
1635 ret = file_write_complete(file_info);
1637 if (ret != DA_RESULT_OK)
1639 discard_download(file_info);
1640 DA_MUTEX_LOCK(&(http_info->mutex_state));
1641 http_info->state = HTTP_STATE_FAILED;
1642 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1647 /* When file complete is failed */
1648 if (DA_RESULT_OK != ret) {
1649 DA_MUTEX_LOCK(&(http_info->mutex_state));
1650 http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
1651 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1654 free(raw_data->body);
1659 void __http_update_cb(http_raw_data_t *data, void *user_param)
1661 http_raw_data_t *raw_data = DA_NULL;
1662 da_info_t *da_info = DA_NULL;
1663 if (!data || !user_param) {
1664 DA_LOGE("NULL CHECK!: data, user_param");
1669 da_info = (da_info_t *)user_param;
1671 switch (data->type) {
1672 case HTTP_EVENT_GOT_HEADER:
1673 __handle_event_http_header(raw_data, da_info);
1675 case HTTP_EVENT_GOT_PACKET:
1676 __handle_event_http_packet(raw_data, da_info);
1678 case HTTP_EVENT_FINAL:
1679 __handle_event_http_final(raw_data, da_info);
1682 case HTTP_EVENT_ABORT:
1683 ret = __handle_event_http_abort(raw_data, da_info);
1689 da_bool_t is_stopped_state(da_info_t *da_info)
1691 http_info_t *http_info = DA_NULL;
1692 http_state_t http_state;
1693 NULL_CHECK_RET_OPT(da_info, DA_FALSE);
1694 http_info = da_info->http_info;
1695 NULL_CHECK_RET_OPT(http_info, DA_FALSE);
1696 DA_MUTEX_LOCK(&(http_info->mutex_state));
1697 http_state = http_info->state;
1698 DA_MUTEX_UNLOCK(&(http_info->mutex_state));
1699 switch (http_state) {
1700 case HTTP_STATE_REQUEST_CANCEL:
1701 case HTTP_STATE_CANCELED:
1702 case HTTP_STATE_FAILED:
1703 case HTTP_STATE_ABORTED:
1704 //case HTTP_STATE_REQUEST_PAUSE:
1705 //case HTTP_STATE_REQUEST_RESUME:
1706 //case HTTP_STATE_WAIT_FOR_NET_ERR: