4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
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)
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"
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);
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);
48 da_result_t pause_for_flow_control(stage_info *stage);
49 da_result_t unpause_for_flow_control(stage_info *stage);
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);
58 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
59 http_msg_response_t *http_msg_response);
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);
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);
72 da_result_t set_hdr_fields_on_download_info(stage_info *stage);
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(
79 da_result_t _check_this_partial_download_is_available(stage_info *stage,
80 http_msg_response_t *new_http_msg_response);
82 da_result_t _cancel_transaction(stage_info *stage);
83 da_result_t _disconnect_transaction(stage_info *stage);
85 void __parsing_user_request_header(char *user_request_header,
86 char **out_field, char **out_value);
90 da_result_t init_http_mgr(void)
92 da_result_t ret = DA_RESULT_OK;
94 DA_LOG_FUNC_START(HTTPManager);
96 if (http_mgr.is_http_init == DA_FALSE) {
97 http_mgr.is_http_init = DA_TRUE;
105 da_result_t request_to_abort_http_download(stage_info *stage)
107 da_result_t ret = DA_RESULT_OK;
108 q_event_t *q_event = DA_NULL;
110 DA_LOG_FUNC_START(HTTPManager);
112 DA_LOG_ERR(HTTPManager, "Stage is NULL. download info is already destroyed");
113 return DA_ERR_INVALID_ARGUMENT;
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");
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);
130 void deinit_http_mgr(void)
132 DA_LOG_FUNC_START(HTTPManager);
134 if (http_mgr.is_http_init == DA_TRUE) {
135 http_mgr.is_http_init = DA_FALSE;
142 da_result_t request_http_download(stage_info *stage)
144 da_result_t ret = DA_RESULT_OK;
146 int download_id = DA_INVALID_ID;
147 http_state_t http_state = 0;
148 da_bool_t need_wait = DA_TRUE;
150 queue_t *queue = DA_NULL;
151 req_dl_info *req_info = DA_NULL;
153 DA_LOG_FUNC_START(HTTPManager);
155 download_id = GET_STAGE_DL_ID(stage);
156 queue = GET_DL_QUEUE(download_id);
157 req_info = GET_STAGE_TRANSACTION_INFO(stage);
159 DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(download_id));
161 CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD, stage);
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);
170 _cancel_transaction(stage);
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)));
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);
186 DA_LOG(HTTPManager, "exiting with error...");
187 need_wait = DA_FALSE;
191 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_REQUESTED, stage);
193 send_client_da_state(download_id,
194 DA_STATE_DOWNLOAD_STARTED,
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;
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);
214 // DA_LOG(HTTPManager, "Waiting for input");
216 // DA_LOG(HTTPManager, "Woke up to receive new packet or control event");
218 _da_thread_mutex_unlock (&(queue->mutex_queue));
222 } while (need_wait == DA_TRUE);
224 ret = GET_REQUEST_HTTP_RESULT(req_info);
225 DA_LOG(HTTPManager, "--------------Exiting request_http_download! ret = %d", ret);
229 da_result_t request_to_cancel_http_download(stage_info *stage)
231 da_result_t ret = DA_RESULT_OK;
232 q_event_t *q_event = DA_NULL;
234 DA_LOG_FUNC_START(HTTPManager);
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");
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);
250 da_result_t request_to_suspend_http_download(stage_info *stage)
252 da_result_t ret = DA_RESULT_OK;
253 http_state_t http_state = 0;
254 q_event_t *q_event = DA_NULL;
256 DA_LOG_FUNC_START(HTTPManager);
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)));
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;
271 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
272 ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_SUSPEND,
274 if (ret != DA_RESULT_OK) {
275 DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
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)),
290 da_result_t request_to_resume_http_download(stage_info *stage)
292 da_result_t ret = DA_RESULT_OK;
293 http_state_t http_state = 0;
294 q_event_t *q_event = DA_NULL;
296 DA_LOG_FUNC_START(HTTPManager);
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)));
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,
308 if (ret != DA_RESULT_OK) {
309 DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
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)),
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;
325 case HTTP_STATE_RESUMED:
326 ret = DA_ERR_ALREADY_RESUMED;
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;
341 da_result_t start_new_transaction(stage_info *stage)
343 da_result_t ret = DA_RESULT_OK;
345 ret = set_http_request_hdr(stage);
346 if (ret != DA_RESULT_OK)
349 ret = make_transaction_info_and_start_transaction(stage);
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)
358 da_result_t ret = DA_RESULT_OK;
360 http_msg_request_t *http_msg_request = NULL;
361 char *user_agent = NULL;
363 DA_LOG_FUNC_START(HTTPManager);
366 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
367 ret = DA_ERR_INVALID_URL;
371 ret = http_msg_request_create(&http_msg_request);
372 if (ret != DA_RESULT_OK)
375 ret = http_msg_request_set_url(http_msg_request, url);
376 if (ret != DA_RESULT_OK)
379 user_agent = get_user_agent();
381 http_msg_request_add_field(http_msg_request, HTTP_FIELD_UAGENT,
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");
387 if (user_request_header && user_request_header_count > 0) {
389 for (i = 0; i < user_request_header_count; i++)
393 __parsing_user_request_header(user_request_header[i],
395 if (field && value) {
396 http_msg_request_add_field(http_msg_request, field, value);
406 DA_LOG_ERR(HTTPManager, "Fail to parse user request header");
410 DA_LOG(HTTPManager, "no user reqeust header inserted");
412 *out_http_msg_request = http_msg_request;
415 if (ret != DA_RESULT_OK)
416 http_msg_request_destroy(&http_msg_request);
421 da_result_t set_http_request_hdr(stage_info *stage)
423 da_result_t ret = DA_RESULT_OK;
424 req_dl_info *request_info = 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;
431 DA_LOG_FUNC_START(HTTPManager);
433 request_info = GET_STAGE_TRANSACTION_INFO(stage);
436 (url = GET_REQUEST_HTTP_REQ_URL(request_info))) {
437 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
438 ret = DA_ERR_INVALID_URL;
442 user_request_header = GET_REQUEST_HTTP_USER_REQUEST_HEADER(
444 user_request_header_count = GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(
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;
457 da_result_t make_transaction_info_and_start_transaction(stage_info *stage)
459 da_result_t ret = DA_RESULT_OK;
461 int download_id = DA_INVALID_ID;
462 req_dl_info *request_info = DA_NULL;
464 input_for_tranx_t *input_for_tranx = DA_NULL;
466 DA_LOG_FUNC_START(HTTPManager);
468 download_id = GET_STAGE_DL_ID(stage);
470 request_info = GET_STAGE_TRANSACTION_INFO(stage);
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;
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;
484 input_for_tranx->proxy_addr = get_proxy_address();
485 input_for_tranx->queue = GET_DL_QUEUE(download_id);
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;
492 ret = PI_http_start_transaction(input_for_tranx,
493 &(GET_REQUEST_HTTP_TRANS_ID(request_info)));
494 if (ret != DA_RESULT_OK)
498 if (input_for_tranx) {
499 free(input_for_tranx);
500 input_for_tranx = DA_NULL;
506 da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info)
509 char **user_request_header = DA_NULL;
510 int user_request_header_count = 0;
511 source_info_t *source_info = DA_NULL;
513 DA_LOG_FUNC_START(HTTPManager);
516 DA_LOG_ERR(HTTPManager, "stage is NULL");
517 return DA_ERR_INVALID_ARGUMENT;
520 source_info = GET_STAGE_SOURCE_INFO(stage);
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);
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;
535 DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
536 return DA_ERR_INVALID_URL;
539 _da_thread_mutex_init(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)), NULL);
544 da_result_t pause_for_flow_control(stage_info *stage)
549 da_result_t unpause_for_flow_control(stage_info *stage)
551 da_result_t ret = DA_RESULT_OK;
553 // DA_LOG_FUNC_START(HTTPManager);
555 PI_http_unpause_transaction(
556 GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)));
559 da_result_t handle_event_abort(stage_info *stage)
561 da_result_t ret = DA_RESULT_OK;
562 http_state_t state = 0;
564 DA_LOG_FUNC_START(HTTPManager);
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)));
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);
584 case HTTP_STATE_DOWNLOAD_FINISH:
587 DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
592 da_result_t handle_event_cancel(stage_info *stage)
594 da_result_t ret = DA_RESULT_OK;
595 http_state_t state = 0;
597 DA_LOG_FUNC_START(HTTPManager);
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)));
604 case HTTP_STATE_READY_TO_DOWNLOAD:
605 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
606 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
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);
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);
624 case HTTP_STATE_DOWNLOAD_FINISH:
627 case HTTP_STATE_REQUEST_CANCEL:
628 DA_LOG(HTTPManager, "HTTP_STATE_REQUEST_CANCEL : cancel is already in progress... ");
632 DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
639 da_result_t handle_event_suspend(stage_info *stage)
641 da_result_t ret = DA_RESULT_OK;
642 http_state_t http_state = 0;
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)));
648 switch (http_state) {
649 case HTTP_STATE_REQUEST_PAUSE:
650 DA_LOG(HTTPManager, "already requested to pause! do nothing");
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);
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);
671 da_result_t handle_event_resume(stage_info *stage)
673 da_result_t ret = DA_RESULT_OK;
674 http_msg_request_t *resume_request = NULL;
676 http_state_t http_state = 0;
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)));
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;
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));
691 CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_RESUME,stage);
692 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
694 ret = create_resume_http_request_hdr(stage, &resume_request);
695 if (ret != DA_RESULT_OK)
698 if (GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request)
699 free(GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request);
701 GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request
704 make_transaction_info_and_start_transaction(stage);
711 da_result_t create_resume_http_request_hdr(stage_info *stage,
712 http_msg_request_t **out_resume_request)
714 da_result_t ret = DA_RESULT_OK;
715 da_bool_t b_ret = DA_FALSE;
717 req_dl_info *request_info = NULL;
719 http_msg_response_t *first_response = NULL;
720 http_msg_request_t *resume_request = NULL;
724 unsigned int downloaded_data_size = 0;
725 char downloaded_data_size_to_str[32] = { 0, };
727 char *etag_from_response = NULL;
728 char *date_from_response = NULL;
730 DA_LOG_FUNC_START(HTTPManager);
732 request_info = GET_STAGE_TRANSACTION_INFO(stage);
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;
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);
744 etag_from_response = value;
746 DA_LOG(HTTPManager, "[ETag][%s]", etag_from_response);
749 b_ret = http_msg_response_get_date(first_response, &value);
751 date_from_response = value;
753 DA_LOG(HTTPManager, "[Date][%s]", date_from_response);
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);
764 ret = make_default_http_request_hdr(url, NULL, 0, &resume_request);
765 if (ret != DA_RESULT_OK)
768 if (etag_from_response) {
769 http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE,
772 if (date_from_response) {
773 http_msg_request_add_field(resume_request,
774 HTTP_FIELD_IF_RANGE, date_from_response);
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);
782 *out_resume_request = resume_request;
785 if (etag_from_response) {
786 free(etag_from_response);
787 etag_from_response = NULL;
790 if (date_from_response) {
791 free(date_from_response);
792 date_from_response = NULL;
798 da_result_t handle_any_input(stage_info *stage)
800 da_result_t ret = DA_RESULT_OK;
802 int download_id = GET_STAGE_DL_ID(stage);
804 queue_t *queue = DA_NULL;
805 q_event_t *event = DA_NULL;
807 // DA_LOG_FUNC_START(HTTPManager);
809 queue = GET_DL_QUEUE(download_id);
811 Q_pop_event(queue, &event);
812 if (event == DA_NULL) {
813 DA_LOG(HTTPManager, "There is no data on the queue!");
817 switch (event->event_type) {
818 case Q_EVENT_TYPE_CONTROL:
819 ret = handle_event_control(stage, event);
822 case Q_EVENT_TYPE_DATA_HTTP:
823 ret = handle_event_http(stage, event);
826 case Q_EVENT_TYPE_DATA_DRM:
833 Q_destroy_q_event(&event);
838 da_result_t handle_event_control(stage_info *stage, q_event_t *event)
840 da_result_t ret = DA_RESULT_OK;
842 DA_LOG_FUNC_START(HTTPManager);
844 if (event->event_type == Q_EVENT_TYPE_CONTROL) {
845 switch (event->type.q_event_control.control_type) {
846 case Q_EVENT_TYPE_CONTROL_CANCEL:
847 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
848 ret = handle_event_cancel(stage);
851 case Q_EVENT_TYPE_CONTROL_SUSPEND:
852 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
853 ret = handle_event_suspend(stage);
856 case Q_EVENT_TYPE_CONTROL_RESUME:
857 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
858 ret = handle_event_resume(stage);
860 case Q_EVENT_TYPE_CONTROL_ABORT:
861 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
862 ret = handle_event_abort(stage);
864 /* Fixme: need to think how we use this type. For now, this type is not used. */
865 case Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED:
866 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED");
874 da_result_t handle_event_http(stage_info *stage, q_event_t *event)
876 da_result_t ret = DA_RESULT_OK;
877 q_event_data_http_t *q_event_data_http = DA_NULL;
879 // DA_LOG_FUNC_START(HTTPManager);
881 if (event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
882 q_event_data_http = &(event->type.q_event_data_http);
883 switch (q_event_data_http->data_type) {
884 case Q_EVENT_TYPE_DATA_PACKET:
885 ret = handle_event_http_packet(stage, event);
889 case Q_EVENT_TYPE_DATA_FINAL:
890 DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL");
891 ret = handle_event_http_final(stage, event);
895 case Q_EVENT_TYPE_DATA_ABORT:
896 DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT");
897 ret = handle_event_http_abort(stage, event);
906 da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event)
908 da_result_t ret = DA_RESULT_OK;
909 da_bool_t is_handle_hdr_success = DA_TRUE;
910 q_event_data_http_t *received_data = DA_NULL;
912 // DA_LOG_FUNC_START(HTTPManager);
914 received_data = &(event->type.q_event_data_http);
916 if (received_data->http_response_msg) {
917 ret = handle_http_hdr(stage, received_data->http_response_msg,
918 received_data->http_response_msg->status_code);
919 if (DA_RESULT_OK != ret) {
920 is_handle_hdr_success = DA_FALSE;
923 received_data->http_response_msg = NULL;
926 if (received_data->body_len > 0) {
927 if (is_handle_hdr_success == DA_TRUE) {
928 ret = handle_http_body(stage, received_data->body_data,
929 received_data->body_len);
931 /*For all cases body_data should be deleted*/
932 free(received_data->body_data);
933 received_data->body_data = DA_NULL;
939 da_result_t handle_event_http_final(stage_info *stage, q_event_t *event)
941 da_result_t ret = DA_RESULT_OK;
943 http_state_t http_state = 0;
944 int download_id = DA_INVALID_ID;
946 DA_LOG_FUNC_START(HTTPManager);
948 download_id = GET_STAGE_DL_ID(stage);
949 _disconnect_transaction(stage);
951 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
952 http_state = GET_HTTP_STATE_ON_STAGE(stage);
953 DA_LOG(HTTPManager, "http_state = %d", http_state);
954 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
956 switch (http_state) {
957 case HTTP_STATE_REDIRECTED:
958 CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage);
961 case HTTP_STATE_DOWNLOAD_REQUESTED:
962 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED");
963 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
966 case HTTP_STATE_DOWNLOADING:
967 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOADING");
968 ret = file_write_complete(stage);
969 if (ret != DA_RESULT_OK) {
970 discard_download(stage);
973 /* ret = _check_downloaded_file_size_is_same_with_header_content_size(stage);
974 if(ret != DA_RESULT_OK)
976 discard_download(stage) ;
980 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
981 send_client_update_downloading_info(
983 GET_DL_REQ_ID(download_id),
984 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
988 case HTTP_STATE_REQUEST_PAUSE:
989 if (GET_CONTENT_STORE_FILE_HANDLE(GET_STAGE_CONTENT_STORE_INFO(stage))) {
990 ret = file_write_complete(stage);
991 send_client_update_downloading_info(
993 GET_DL_REQ_ID(download_id),
994 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
995 GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)));
997 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1000 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
1001 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
1002 send_client_da_state(download_id, DA_STATE_SUSPENDED,
1004 DA_LOG(HTTPManager, "Server Notification code is set to NULL");
1007 case HTTP_STATE_ABORTED:
1008 case HTTP_STATE_CANCELED:
1009 discard_download(stage);
1012 case HTTP_STATE_REQUEST_CANCEL:
1013 ret = file_write_complete(stage);
1014 if (ret != DA_RESULT_OK)
1016 discard_download(stage);
1017 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage);
1018 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1022 ret = file_write_complete(stage);
1023 if (ret != DA_RESULT_OK)
1025 discard_download(stage);
1026 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1031 /* When file complete is failed */
1032 if (DA_RESULT_OK != ret) {
1033 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1038 da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event)
1040 da_result_t ret = DA_RESULT_OK;
1041 http_state_t http_state = 0;
1043 DA_LOG_FUNC_START(HTTPManager);
1045 GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))
1046 = event->type.q_event_data_http.error_type;
1047 DA_LOG_CRITICAL(HTTPManager, "set internal error code : [%d]", GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1048 _disconnect_transaction(stage);
1050 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1051 http_state = GET_HTTP_STATE_ON_STAGE(stage);
1052 DA_LOG(HTTPManager, "http_state = %d", http_state);
1053 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1055 switch (http_state) {
1056 case HTTP_STATE_REQUEST_PAUSE:
1057 CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
1058 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
1059 send_client_da_state(GET_STAGE_DL_ID(stage),
1060 DA_STATE_SUSPENDED, DA_RESULT_OK);
1061 ret = file_write_complete(stage);
1062 if (ret != DA_RESULT_OK)
1066 case HTTP_STATE_REQUEST_CANCEL:
1067 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
1068 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1069 ret = file_write_complete(stage);
1070 if (ret != DA_RESULT_OK)
1072 discard_download(stage);
1076 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1077 ret = file_write_complete(stage);
1078 if (ret != DA_RESULT_OK)
1080 discard_download(stage);
1087 da_result_t handle_http_hdr(stage_info *stage,
1088 http_msg_response_t *http_msg_response, int http_status)
1090 da_result_t ret = DA_RESULT_OK;
1091 int download_id = DA_INVALID_ID;
1092 http_state_t http_state = 0;
1093 char *response_header_data = DA_NULL;
1095 DA_LOG_FUNC_START(HTTPManager);
1097 download_id = GET_STAGE_DL_ID(stage);
1099 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1100 http_state = GET_HTTP_STATE_ON_STAGE(stage);
1101 DA_LOG(HTTPManager, "http_state = %d", http_state);
1102 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1104 switch (http_state) {
1105 case HTTP_STATE_DOWNLOAD_REQUESTED:
1106 case HTTP_STATE_REQUEST_PAUSE:
1107 case HTTP_STATE_REQUEST_RESUME:
1108 case HTTP_STATE_REDIRECTED:
1109 /* In case of manual download, this is first update.
1110 * So, the client can know the mime type at second update */
1111 if (DA_TRUE == is_this_client_manual_download_type() &&
1112 http_msg_response) {
1113 // SHOULD free response_header_data when it is not used any more
1114 response_header_data = get_http_response_header_raw(http_msg_response);
1115 send_client_update_dl_info(
1117 GET_DL_REQ_ID(download_id),
1118 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1119 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1121 response_header_data,
1123 if (response_header_data) {
1124 free(response_header_data);
1125 response_header_data = NULL;
1128 ret = handle_http_status_code(stage, http_msg_response,
1130 if (ret != DA_RESULT_OK)
1134 case HTTP_STATE_REQUEST_CANCEL:
1135 DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state);
1139 DA_LOG_ERR(HTTPManager, "http_state = %d", http_state);
1147 da_result_t handle_http_status_code(stage_info *stage,
1148 http_msg_response_t *http_msg_response, int http_status)
1150 da_result_t ret = DA_RESULT_OK;
1152 int download_id = DA_INVALID_ID;
1153 req_dl_info *request_info = DA_NULL;
1154 http_state_t http_state = 0;
1156 DA_LOG_FUNC_START(HTTPManager);
1158 download_id = GET_STAGE_DL_ID(stage);
1159 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1161 GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response
1162 = http_msg_response;
1164 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1165 http_state = GET_HTTP_STATE_ON_STAGE(stage);
1166 DA_LOG(HTTPManager, "http_state = %d", http_state);
1167 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1169 switch (http_status) {
1174 if (http_state == HTTP_STATE_REQUEST_RESUME)
1175 clean_paused_file(stage);
1176 ret = set_hdr_fields_on_download_info(stage);
1177 if (ret != DA_RESULT_OK)
1179 ret = _check_content_type_is_matched(stage);
1180 if (ret != DA_RESULT_OK)
1182 ret = _check_enough_memory_for_this_download(stage);
1183 if (ret != DA_RESULT_OK)
1185 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
1186 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
1190 DA_LOG(HTTPManager, "HTTP Status is %d - Partial download for resume!",http_status);
1191 if (http_state != HTTP_STATE_REQUEST_RESUME) {
1192 DA_LOG_ERR(HTTPManager, "This download is not resumed, revoke");
1193 ret = DA_ERR_INVALID_STATE;
1196 ret = _check_this_partial_download_is_available(stage,
1198 if (ret != DA_RESULT_OK)
1200 CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage);
1201 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
1211 DA_LOG(HTTPManager, "HTTP Status is %d - redirection!",http_status);
1212 ret = exchange_url_from_header_for_redirection(stage, http_msg_response);
1213 if (ret != DA_RESULT_OK)
1215 CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage);
1216 http_msg_response_destroy(&http_msg_response);
1224 DA_LOG(HTTPManager, "HTTP Status is %d - 204 means server got the request, but no content to reply back, 304 means not modified!",http_status);
1225 ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT;
1228 case 416: // Requested range not satisfiable
1232 GET_REQUEST_HTTP_RESULT(request_info)
1233 = DA_ERR_UNREACHABLE_SERVER;
1234 DA_LOG_CRITICAL(HTTPManager, "set internal error code : DA_ERR_UNREACHABLE_SERVER [%d]", DA_ERR_UNREACHABLE_SERVER);
1242 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
1243 http_msg_response_t *http_msg_response)
1245 da_result_t ret = DA_RESULT_OK;
1246 char *location = DA_NULL;
1248 DA_LOG_FUNC_START(HTTPManager);
1250 if (http_msg_response_get_location(http_msg_response, &location)) {
1251 DA_LOG(HTTPManager, "location = %s\n", location);
1252 GET_REQUEST_HTTP_REQ_LOCATION(GET_STAGE_TRANSACTION_INFO(stage)) = location;
1258 da_result_t handle_http_body(stage_info *stage, char *body, int body_len)
1260 da_result_t ret = DA_RESULT_OK;
1261 http_state_t http_state = 0;
1262 int download_id = DA_INVALID_ID;
1264 // DA_LOG_FUNC_START(HTTPManager);
1266 download_id = GET_STAGE_DL_ID(stage);
1269 != GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))) {
1270 DA_LOG_CRITICAL(HTTPManager, "ignore because internal error code is set with [%d]",
1271 GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
1275 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1276 http_state = GET_HTTP_STATE_ON_STAGE(stage);
1277 // DA_LOG(HTTPManager, "http_state = %d", http_state);
1278 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1280 if (http_state == HTTP_STATE_DOWNLOAD_STARTED) {
1281 ret = start_file_writing(stage);
1282 if (DA_RESULT_OK != ret)
1285 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage);
1286 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
1288 send_client_update_dl_info(
1290 GET_DL_REQ_ID(download_id),
1291 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1292 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1293 GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1296 } else if (http_state == HTTP_STATE_RESUMED) {
1297 ret = start_file_writing_append(stage);
1298 if (DA_RESULT_OK != ret)
1301 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage);
1302 send_client_da_state(download_id, DA_STATE_RESUMED,
1304 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
1308 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1309 http_state = GET_HTTP_STATE_ON_STAGE(stage);
1310 // DA_LOG(HTTPManager, "http_state = %d", http_state);
1311 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1313 switch (http_state) {
1314 case HTTP_STATE_REDIRECTED:
1315 DA_LOG(HTTPManager, "Just ignore http body, because this body is not for redirection one.");
1318 case HTTP_STATE_DOWNLOADING:
1319 /* Should this function before updating download info
1320 * Because it extract mime type at once only if first download updating at client */
1321 ret = file_write_ongoing(stage, body, body_len);
1322 if (ret != DA_RESULT_OK)
1324 if (DA_TRUE == is_this_client_manual_download_type()) {
1325 send_client_update_dl_info(
1327 GET_DL_REQ_ID(download_id),
1328 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1330 GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1333 } else if ((DA_TRUE ==
1334 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)))) {
1335 send_client_update_downloading_info(
1337 GET_DL_REQ_ID(download_id),
1338 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1341 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1346 case HTTP_STATE_REQUEST_PAUSE:
1347 if (DA_TRUE == is_this_client_manual_download_type()) {
1348 send_client_update_dl_info(
1350 GET_DL_REQ_ID(download_id),
1351 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1352 GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1353 GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
1357 ret = file_write_ongoing(stage, body, body_len);
1358 if (ret != DA_RESULT_OK)
1364 DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state);
1373 /* Function should be renamed , as it is actually not setting the header fields in download info */
1374 da_result_t set_hdr_fields_on_download_info(stage_info *stage)
1376 da_result_t ret = DA_RESULT_OK;
1377 da_bool_t b_ret = DA_FALSE;
1379 req_dl_info *request_info = DA_NULL;
1380 http_msg_response_t *http_msg_response = NULL;
1385 DA_LOG_FUNC_START(HTTPManager);
1387 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1390 = request_info->http_info.http_msg_response;
1391 if (!http_msg_response) {
1392 DA_LOG_ERR(HTTPManager, "There is no header data!!");
1393 ret = DA_ERR_INVALID_ARGUMENT;
1397 b_ret = http_msg_response_get_content_type(http_msg_response, &value);
1399 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
1401 DA_LOG(HTTPManager, "[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
1404 b_ret = http_msg_response_get_content_length(http_msg_response,
1407 GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = int_value;
1409 DA_LOG(HTTPManager, "[Content-Length][%d] - stored", GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
1412 b_ret = http_msg_response_get_ETag(http_msg_response, &value);
1414 GET_REQUEST_HTTP_HDR_ETAG(request_info) = value;
1416 DA_LOG(HTTPManager, "[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info));
1423 da_result_t _check_content_type_is_matched(stage_info *stage)
1425 da_result_t ret = DA_RESULT_OK;
1426 req_dl_info *request_info = DA_NULL;
1427 source_info_t *source_info = DA_NULL;
1428 char *content_type_from_server = DA_NULL;
1430 DA_LOG_FUNC_START(HTTPManager);
1432 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1433 source_info = GET_STAGE_SOURCE_INFO(stage);
1435 content_type_from_server = GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info);
1436 if (content_type_from_server == DA_NULL) {
1437 DA_LOG(HTTPManager, "http header has no Content-Type field, no need to compare");
1438 return DA_RESULT_OK;
1444 da_result_t _check_enough_memory_for_this_download(stage_info *stage)
1446 da_result_t ret = DA_RESULT_OK;
1448 req_dl_info *request_info = DA_NULL;
1450 long long cont_len = 0;
1451 da_storage_size_t memory;
1453 DA_LOG_FUNC_START(HTTPManager);
1455 memset(&memory, 0x00, sizeof(da_storage_size_t));
1456 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1458 cont_len = (long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
1460 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1461 if (DA_RESULT_OK == ret) {
1462 DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %lld",memory.b_available,memory.b_size, cont_len);
1463 if (memory.b_available < ((cont_len
1464 + SAVE_FILE_BUFFERING_SIZE_50KB)
1465 / memory.b_size)) /* 50KB buffering */
1467 ret = DA_ERR_DISK_FULL;
1477 da_result_t _check_this_partial_download_is_available(stage_info *stage,
1478 http_msg_response_t *new_http_msg_response)
1480 da_result_t ret = DA_RESULT_OK;
1481 da_bool_t b_ret = DA_FALSE;
1483 char *origin_ETag = NULL;
1484 char *new_ETag = NULL;
1486 int remained_content_len = 0;
1487 da_storage_size_t memory;
1492 DA_LOG_FUNC_START(HTTPManager);
1495 = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage));
1497 b_ret = http_msg_response_get_content_length(new_http_msg_response,
1500 remained_content_len = int_value;
1502 DA_LOG(HTTPManager, "[remained_content_len][%d]", remained_content_len);
1505 b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
1509 DA_LOG(HTTPManager, "[new ETag][%s]", new_ETag);
1514 if (0 != strcmp(origin_ETag, new_ETag)) {
1515 DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
1516 /* FIXME Later : Need to detail error exception handling */
1517 ret = DA_ERR_NETWORK_FAIL;
1518 /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
1522 if (remained_content_len) {
1523 ret = get_available_memory(DA_STORAGE_PHONE, &memory);
1524 if (DA_RESULT_OK == ret) {
1525 DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %lld",memory.b_available,memory.b_size, remained_content_len );
1526 if (memory.b_available < ((remained_content_len
1527 + SAVE_FILE_BUFFERING_SIZE_50KB)
1528 / memory.b_size)) /* 50KB buffering */
1530 ret = DA_ERR_DISK_FULL;
1545 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
1548 da_result_t ret = DA_RESULT_OK;
1550 req_dl_info *request_info = DA_NULL;
1551 file_info *file_info_data = DA_NULL;
1553 char *real_file_path = DA_NULL;
1554 int content_size_from_real_file = DA_INVALID_ID;
1555 unsigned int content_size_from_http_header = DA_INVALID_ID;
1557 DA_LOG_FUNC_START(HTTPManager);
1559 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1560 file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
1562 content_size_from_http_header
1563 = GET_CONTENT_STORE_FILE_SIZE(file_info_data);
1565 if (content_size_from_http_header > 0) {
1567 = GET_CONTENT_STORE_TMP_FILE_NAME(file_info_data);
1568 if (is_content_drm_dm(
1569 GET_CONTENT_STORE_CONTENT_TYPE(file_info_data))) {
1570 /* FIXME Later : How can get the file size of DRM file. */
1571 content_size_from_real_file
1572 = content_size_from_http_header;
1574 get_file_size(real_file_path,
1575 &content_size_from_real_file);
1578 if ((unsigned int) content_size_from_real_file
1579 != content_size_from_http_header) {
1580 DA_LOG_ERR(HTTPManager, "size from header = %d, real size = %d, DA_ERR_MISMATCH_CONTENT_SIZE", content_size_from_http_header, content_size_from_real_file);
1581 ret = DA_ERR_MISMATCH_CONTENT_SIZE;
1588 da_result_t _disconnect_transaction(stage_info *stage)
1590 da_result_t ret = DA_RESULT_OK;
1591 int transaction_id = DA_INVALID_ID;
1593 DA_LOG_FUNC_START(HTTPManager);
1596 = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1598 DA_LOG(HTTPManager, "transaction_id = %d download_id = %d", transaction_id, GET_STAGE_DL_ID(stage));
1600 if (transaction_id != DA_INVALID_ID) {
1601 ret = PI_http_disconnect_transaction(transaction_id);
1602 GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage))
1609 da_result_t _cancel_transaction(stage_info *stage)
1611 da_result_t ret = DA_RESULT_OK;
1612 int transaction_id = DA_INVALID_ID;
1614 DA_LOG_FUNC_START(HTTPManager);
1617 = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1619 DA_LOG(HTTPManager, "transaction_id = %d", transaction_id);
1621 if (transaction_id != DA_INVALID_ID) {
1622 http_state_t state = 0;
1623 _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1624 state = GET_HTTP_STATE_ON_STAGE(stage);
1625 if (state <= HTTP_STATE_DOWNLOAD_REQUESTED)
1626 ret = PI_http_cancel_transaction(transaction_id, DA_TRUE);
1628 ret = PI_http_cancel_transaction(transaction_id, DA_FALSE);
1629 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1635 void __parsing_user_request_header(char *user_request_header,
1636 char **out_field, char **out_value)
1640 char *temp_pos = NULL;
1644 DA_LOG_FUNC_START(HTTPManager);
1646 if (!user_request_header) {
1647 DA_LOG_ERR(HTTPManager, "user_request_header is NULL");
1651 pos = strchr(user_request_header, ':');
1653 DA_LOG_ERR(HTTPManager, "Fail to parse");
1656 temp_pos = (char *)user_request_header;
1659 if (temp_pos == pos || *temp_pos == ' ') {
1660 len = temp_pos - user_request_header;
1666 DA_LOG_ERR(HTTPManager, "Wrong field name");
1669 field = (char *)calloc(1, len + 1);
1671 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1674 strncpy(field, user_request_header, len);
1682 len = strlen(pos) + 1;
1683 value = (char *)calloc(1, len + 1);
1685 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1688 strncpy(value, pos, len);
1691 DA_LOG(HTTPManager, "field[%s], value[%s]", field, value);