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);
830 Q_destroy_q_event(&event);
835 da_result_t handle_event_control(stage_info *stage, q_event_t *event)
837 da_result_t ret = DA_RESULT_OK;
839 DA_LOG_FUNC_START(HTTPManager);
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);
848 case Q_EVENT_TYPE_CONTROL_SUSPEND:
849 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
850 ret = handle_event_suspend(stage);
853 case Q_EVENT_TYPE_CONTROL_RESUME:
854 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
855 ret = handle_event_resume(stage);
857 case Q_EVENT_TYPE_CONTROL_ABORT:
858 DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
859 ret = handle_event_abort(stage);
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");
871 da_result_t handle_event_http(stage_info *stage, q_event_t *event)
873 da_result_t ret = DA_RESULT_OK;
874 q_event_data_http_t *q_event_data_http = DA_NULL;
876 // DA_LOG_FUNC_START(HTTPManager);
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);
886 case Q_EVENT_TYPE_DATA_FINAL:
887 DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL");
888 ret = handle_event_http_final(stage, event);
892 case Q_EVENT_TYPE_DATA_ABORT:
893 DA_LOG(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT");
894 ret = handle_event_http_abort(stage, event);
903 da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event)
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;
909 // DA_LOG_FUNC_START(HTTPManager);
911 received_data = &(event->type.q_event_data_http);
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;
920 received_data->http_response_msg = NULL;
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);
928 /*For all cases body_data should be deleted*/
929 free(received_data->body_data);
930 received_data->body_data = DA_NULL;
936 da_result_t handle_event_http_final(stage_info *stage, q_event_t *event)
938 da_result_t ret = DA_RESULT_OK;
940 http_state_t http_state = 0;
941 int download_id = DA_INVALID_ID;
943 DA_LOG_FUNC_START(HTTPManager);
945 download_id = GET_STAGE_DL_ID(stage);
946 _disconnect_transaction(stage);
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)));
953 switch (http_state) {
954 case HTTP_STATE_REDIRECTED:
955 CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage);
958 case HTTP_STATE_DOWNLOAD_REQUESTED:
959 DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED");
960 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
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);
970 /* ret = _check_downloaded_file_size_is_same_with_header_content_size(stage);
971 if(ret != DA_RESULT_OK)
973 discard_download(stage) ;
977 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
978 send_client_update_downloading_info(
980 GET_DL_REQ_ID(download_id),
981 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
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(
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)));
994 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
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,
1001 DA_LOG(HTTPManager, "Server Notification code is set to NULL");
1004 case HTTP_STATE_ABORTED:
1005 case HTTP_STATE_CANCELED:
1006 discard_download(stage);
1009 case HTTP_STATE_REQUEST_CANCEL:
1010 ret = file_write_complete(stage);
1011 if (ret != DA_RESULT_OK)
1013 discard_download(stage);
1014 CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage);
1015 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
1019 ret = file_write_complete(stage);
1020 if (ret != DA_RESULT_OK)
1022 discard_download(stage);
1023 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1028 /* When file complete is failed */
1029 if (DA_RESULT_OK != ret) {
1030 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
1035 da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event)
1037 da_result_t ret = DA_RESULT_OK;
1038 http_state_t http_state = 0;
1040 DA_LOG_FUNC_START(HTTPManager);
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);
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)));
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)
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)
1069 discard_download(stage);
1073 CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
1074 ret = file_write_complete(stage);
1075 if (ret != DA_RESULT_OK)
1077 discard_download(stage);
1084 da_result_t handle_http_hdr(stage_info *stage,
1085 http_msg_response_t *http_msg_response, int http_status)
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;
1092 DA_LOG_FUNC_START(HTTPManager);
1094 download_id = GET_STAGE_DL_ID(stage);
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)));
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(
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)),
1118 response_header_data,
1120 if (response_header_data) {
1121 free(response_header_data);
1122 response_header_data = NULL;
1125 ret = handle_http_status_code(stage, http_msg_response,
1127 if (ret != DA_RESULT_OK)
1131 case HTTP_STATE_REQUEST_CANCEL:
1132 DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state);
1136 DA_LOG_ERR(HTTPManager, "http_state = %d", http_state);
1144 da_result_t handle_http_status_code(stage_info *stage,
1145 http_msg_response_t *http_msg_response, int http_status)
1147 da_result_t ret = DA_RESULT_OK;
1149 int download_id = DA_INVALID_ID;
1150 req_dl_info *request_info = DA_NULL;
1151 http_state_t http_state = 0;
1153 DA_LOG_FUNC_START(HTTPManager);
1155 download_id = GET_STAGE_DL_ID(stage);
1156 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1158 GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response
1159 = http_msg_response;
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)));
1166 switch (http_status) {
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)
1176 ret = _check_content_type_is_matched(stage);
1177 if (ret != DA_RESULT_OK)
1179 ret = _check_enough_memory_for_this_download(stage);
1180 if (ret != DA_RESULT_OK)
1182 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
1183 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
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;
1193 ret = _check_this_partial_download_is_available(stage,
1195 if (ret != DA_RESULT_OK)
1197 CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage);
1198 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
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)
1212 CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage);
1213 http_msg_response_destroy(&http_msg_response);
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;
1225 case 416: // Requested range not satisfiable
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);
1239 da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
1240 http_msg_response_t *http_msg_response)
1242 da_result_t ret = DA_RESULT_OK;
1243 char *location = DA_NULL;
1245 DA_LOG_FUNC_START(HTTPManager);
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;
1255 da_result_t handle_http_body(stage_info *stage, char *body, int body_len)
1257 da_result_t ret = DA_RESULT_OK;
1258 http_state_t http_state = 0;
1259 int download_id = DA_INVALID_ID;
1261 // DA_LOG_FUNC_START(HTTPManager);
1263 download_id = GET_STAGE_DL_ID(stage);
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)));
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)));
1277 if (http_state == HTTP_STATE_DOWNLOAD_STARTED) {
1278 ret = start_file_writing(stage);
1279 if (DA_RESULT_OK != ret)
1282 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage);
1283 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
1285 send_client_update_dl_info(
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)),
1293 } else if (http_state == HTTP_STATE_RESUMED) {
1294 ret = start_file_writing_append(stage);
1295 if (DA_RESULT_OK != ret)
1298 CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage);
1299 send_client_da_state(download_id, DA_STATE_RESUMED,
1301 send_client_da_state(download_id, DA_STATE_DOWNLOADING,
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)));
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.");
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)
1321 if (DA_TRUE == is_this_client_manual_download_type()) {
1322 send_client_update_dl_info(
1324 GET_DL_REQ_ID(download_id),
1325 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1327 GET_CONTENT_STORE_TMP_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
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(
1334 GET_DL_REQ_ID(download_id),
1335 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
1338 IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
1343 case HTTP_STATE_REQUEST_PAUSE:
1344 if (DA_TRUE == is_this_client_manual_download_type()) {
1345 send_client_update_dl_info(
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)),
1354 ret = file_write_ongoing(stage, body, body_len);
1355 if (ret != DA_RESULT_OK)
1361 DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state);
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)
1373 da_result_t ret = DA_RESULT_OK;
1374 da_bool_t b_ret = DA_FALSE;
1376 req_dl_info *request_info = DA_NULL;
1377 http_msg_response_t *http_msg_response = NULL;
1382 DA_LOG_FUNC_START(HTTPManager);
1384 request_info = GET_STAGE_TRANSACTION_INFO(stage);
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;
1394 b_ret = http_msg_response_get_content_type(http_msg_response, &value);
1396 GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
1398 DA_LOG(HTTPManager, "[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
1401 b_ret = http_msg_response_get_content_length(http_msg_response,
1404 GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = int_value;
1406 DA_LOG(HTTPManager, "[Content-Length][%d] - stored", GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
1409 b_ret = http_msg_response_get_ETag(http_msg_response, &value);
1411 GET_REQUEST_HTTP_HDR_ETAG(request_info) = value;
1413 DA_LOG(HTTPManager, "[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info));
1420 da_result_t _check_content_type_is_matched(stage_info *stage)
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;
1427 DA_LOG_FUNC_START(HTTPManager);
1429 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1430 source_info = GET_STAGE_SOURCE_INFO(stage);
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;
1441 da_result_t _check_enough_memory_for_this_download(stage_info *stage)
1443 da_result_t ret = DA_RESULT_OK;
1445 req_dl_info *request_info = DA_NULL;
1447 long long cont_len = 0;
1448 da_storage_size_t memory;
1450 DA_LOG_FUNC_START(HTTPManager);
1452 memset(&memory, 0x00, sizeof(da_storage_size_t));
1453 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1455 cont_len = (long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
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 */
1464 ret = DA_ERR_DISK_FULL;
1474 da_result_t _check_this_partial_download_is_available(stage_info *stage,
1475 http_msg_response_t *new_http_msg_response)
1477 da_result_t ret = DA_RESULT_OK;
1478 da_bool_t b_ret = DA_FALSE;
1480 char *origin_ETag = NULL;
1481 char *new_ETag = NULL;
1483 int remained_content_len = 0;
1484 da_storage_size_t memory;
1489 DA_LOG_FUNC_START(HTTPManager);
1492 = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage));
1494 b_ret = http_msg_response_get_content_length(new_http_msg_response,
1497 remained_content_len = int_value;
1499 DA_LOG(HTTPManager, "[remained_content_len][%d]", remained_content_len);
1502 b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
1506 DA_LOG(HTTPManager, "[new ETag][%s]", new_ETag);
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; */
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 */
1527 ret = DA_ERR_DISK_FULL;
1542 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
1545 da_result_t ret = DA_RESULT_OK;
1547 req_dl_info *request_info = DA_NULL;
1548 file_info *file_info_data = DA_NULL;
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;
1554 DA_LOG_FUNC_START(HTTPManager);
1556 request_info = GET_STAGE_TRANSACTION_INFO(stage);
1557 file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
1559 content_size_from_http_header
1560 = GET_CONTENT_STORE_FILE_SIZE(file_info_data);
1562 if (content_size_from_http_header > 0) {
1564 = GET_CONTENT_STORE_TMP_FILE_NAME(file_info_data);
1565 get_file_size(real_file_path,
1566 &content_size_from_real_file);
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;
1578 da_result_t _disconnect_transaction(stage_info *stage)
1580 da_result_t ret = DA_RESULT_OK;
1581 int transaction_id = DA_INVALID_ID;
1583 DA_LOG_FUNC_START(HTTPManager);
1586 = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1588 DA_LOG(HTTPManager, "transaction_id = %d download_id = %d", transaction_id, GET_STAGE_DL_ID(stage));
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))
1599 da_result_t _cancel_transaction(stage_info *stage)
1601 da_result_t ret = DA_RESULT_OK;
1602 int transaction_id = DA_INVALID_ID;
1604 DA_LOG_FUNC_START(HTTPManager);
1607 = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
1609 DA_LOG(HTTPManager, "transaction_id = %d", transaction_id);
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);
1618 ret = PI_http_cancel_transaction(transaction_id, DA_FALSE);
1619 _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
1625 void __parsing_user_request_header(char *user_request_header,
1626 char **out_field, char **out_value)
1630 char *temp_pos = NULL;
1634 DA_LOG_FUNC_START(HTTPManager);
1636 if (!user_request_header) {
1637 DA_LOG_ERR(HTTPManager, "user_request_header is NULL");
1641 pos = strchr(user_request_header, ':');
1643 DA_LOG_ERR(HTTPManager, "Fail to parse");
1646 temp_pos = (char *)user_request_header;
1649 if (temp_pos == pos || *temp_pos == ' ') {
1650 len = temp_pos - user_request_header;
1656 DA_LOG_ERR(HTTPManager, "Wrong field name");
1659 field = (char *)calloc(1, len + 1);
1661 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1664 strncpy(field, user_request_header, len);
1672 len = strlen(pos) + 1;
1673 value = (char *)calloc(1, len + 1);
1675 DA_LOG_ERR(HTTPManager, "Fail to calloc");
1678 strncpy(value, pos, len);
1681 DA_LOG(HTTPManager, "field[%s], value[%s]", field, value);