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.
21 #include "download-agent-http-msg-handler.h"
22 #include "download-agent-debug.h"
23 #include "download-agent-http-misc.h"
24 #include "download-agent-encoding.h"
26 // '.' and ';' are request from Vodafone
27 #define IS_TERMINATING_CHAR(c) ( ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
28 #define IS_TERMINATING_CHAR_EX(c) ( ((c) == '"') || ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
29 #define IS_URI_TERMINATING_CHAR(c) ( ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
33 WITHOUT_PARSING_OPTION
36 static da_result_t __http_header_add_field(http_header_t **head,
37 const char *field, const char *value, enum parsing_type type);
38 static void __http_header_destroy_all_field(http_header_t **head);
39 static da_bool_t __get_http_header_for_field(
40 http_msg_response_t *http_msg_response, const char *in_field,
41 http_header_t **out_header);
42 static void __exchange_header_value(http_header_t *header,
43 const char *in_raw_value);
45 static http_header_options_t *__create_http_header_option(const char *field,
47 static void __http_header_destroy_all_option(http_header_options_t **head);
48 static da_bool_t __get_http_header_option_for_field(
49 http_header_options_t *header_option, const char *in_field,
52 static http_header_options_t *__parsing_N_create_option_str(char *org_str);
53 static http_header_options_t *__parsing_options(char *org_str);
54 static void __parsing_raw_value(http_header_t *http_header);
56 da_result_t http_msg_request_create(http_msg_request_t **http_msg_request)
58 http_msg_request_t *temp_http_msg_request = NULL;
60 DA_LOG_FUNC_LOGV(HTTPManager);
62 temp_http_msg_request = (http_msg_request_t *)calloc(1,
63 sizeof(http_msg_request_t));
64 if (!temp_http_msg_request) {
65 *http_msg_request = NULL;
66 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
67 return DA_ERR_FAIL_TO_MEMALLOC;
70 temp_http_msg_request->http_method = NULL;
71 temp_http_msg_request->url = NULL;
72 temp_http_msg_request->head = NULL;
73 temp_http_msg_request->http_body = NULL;
75 *http_msg_request = temp_http_msg_request;
76 DA_LOG_DEBUG(HTTPManager, "http_msg_request: %x", (unsigned int)(*http_msg_request));
81 void http_msg_request_destroy(http_msg_request_t **http_msg_request)
83 http_msg_request_t *temp_http_msg_request = *http_msg_request;
85 DA_LOG_FUNC_LOGV(HTTPManager);
87 if (temp_http_msg_request) {
88 if (temp_http_msg_request->http_method) {
89 free(temp_http_msg_request->http_method);
90 temp_http_msg_request->http_method = NULL;
93 if (temp_http_msg_request->url) {
94 free(temp_http_msg_request->url);
95 temp_http_msg_request->url = NULL;
98 if (temp_http_msg_request->http_body) {
99 free(temp_http_msg_request->http_body);
100 temp_http_msg_request->http_body = NULL;
103 __http_header_destroy_all_field(&(temp_http_msg_request->head));
105 free(temp_http_msg_request);
106 *http_msg_request = NULL;
111 da_result_t http_msg_request_set_method(http_msg_request_t *http_msg_request,
114 DA_LOG_FUNC_LOGD(HTTPManager);
116 if (!http_msg_request || !method) {
117 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
118 return DA_ERR_INVALID_ARGUMENT;
121 // ToDo: check method is valid
123 http_msg_request->http_method = strdup(method);
125 DA_LOG(HTTPManager, "http method : %s", http_msg_request->http_method);
130 da_result_t http_msg_request_get_method(http_msg_request_t *http_msg_request,
133 DA_LOG_FUNC_LOGV(HTTPManager);
135 if (!http_msg_request) {
136 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
137 return DA_ERR_INVALID_ARGUMENT;
140 if (http_msg_request->http_method) {
141 *method = http_msg_request->http_method;
145 return DA_ERR_INVALID_ARGUMENT;
149 da_result_t http_msg_request_set_url(http_msg_request_t *http_msg_request,
152 DA_LOG_FUNC_LOGV(HTTPManager);
154 if (!http_msg_request) {
155 DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
156 return DA_ERR_INVALID_ARGUMENT;
160 DA_LOG_ERR(HTTPManager, "url is NULL; DA_ERR_INVALID_ARGUMENT");
161 return DA_ERR_INVALID_URL;
164 http_msg_request->url = strdup(url);
166 //DA_SECURE_LOGD("http url : %s", http_msg_request->url);
171 da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request,
174 DA_LOG_FUNC_LOGV(HTTPManager);
176 if (!http_msg_request) {
177 DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
178 return DA_ERR_INVALID_ARGUMENT;
181 if (http_msg_request->url) {
182 *url = http_msg_request->url;
186 return DA_ERR_INVALID_ARGUMENT;
190 da_result_t http_msg_request_set_body(http_msg_request_t *http_msg_request,
193 DA_LOG_FUNC_LOGV(HTTPManager);
195 if (!http_msg_request) {
196 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
197 return DA_ERR_INVALID_ARGUMENT;
203 http_msg_request->http_body = strdup(body);
205 DA_SECURE_LOGD("http body : %s", http_msg_request->http_body);
210 da_result_t http_msg_request_get_body(http_msg_request_t *http_msg_request,
213 DA_LOG_FUNC_LOGV(HTTPManager);
215 if (!http_msg_request) {
216 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
217 return DA_ERR_INVALID_ARGUMENT;
220 if (http_msg_request->http_body) {
221 *body = http_msg_request->http_body;
225 return DA_ERR_INVALID_ARGUMENT;
229 /* FIXME later : check to free filed and value after this API is called */
230 da_result_t http_msg_request_add_field(http_msg_request_t *http_msg_request,
231 const char *field, const char *value)
233 DA_LOG_FUNC_LOGV(HTTPManager);
235 if (!http_msg_request) {
236 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
237 return DA_ERR_INVALID_ARGUMENT;
240 return __http_header_add_field(&(http_msg_request->head), field, value, WITHOUT_PARSING_OPTION);
243 da_result_t http_msg_response_create(http_msg_response_t **http_msg_response)
245 http_msg_response_t *temp_http_msg_response = NULL;
247 DA_LOG_FUNC_LOGV(HTTPManager);
249 temp_http_msg_response = (http_msg_response_t *)calloc(1,
250 sizeof(http_msg_response_t));
251 if (!temp_http_msg_response) {
252 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
253 return DA_ERR_FAIL_TO_MEMALLOC;
255 temp_http_msg_response->status_code = 0;
256 temp_http_msg_response->head = NULL;
258 *http_msg_response = temp_http_msg_response;
264 void http_msg_response_destroy(http_msg_response_t **http_msg_response)
266 http_msg_response_t *temp_http_msg_response = *http_msg_response;
268 DA_LOG_FUNC_LOGV(HTTPManager);
269 if (temp_http_msg_response) {
270 __http_header_destroy_all_field(&(temp_http_msg_response->head));
272 free(temp_http_msg_response);
273 *http_msg_response = DA_NULL;
277 da_result_t http_msg_response_set_status_code(
278 http_msg_response_t *http_msg_response, int status_code)
280 DA_LOG_FUNC_LOGV(HTTPManager);
282 if (!http_msg_response) {
283 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
284 return DA_ERR_INVALID_ARGUMENT;
287 http_msg_response->status_code = status_code;
292 da_result_t http_msg_response_get_status_code(
293 http_msg_response_t *http_msg_response, int *status_code)
295 DA_LOG_FUNC_LOGD(HTTPManager);
297 if (!http_msg_response) {
298 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
299 return DA_ERR_INVALID_ARGUMENT;
302 *status_code = http_msg_response->status_code;
307 da_result_t http_msg_response_add_field(http_msg_response_t *http_msg_response,
308 const char *field, const char *value)
310 DA_LOG_FUNC_LOGV(HTTPManager);
312 if (!http_msg_response) {
313 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
314 return DA_ERR_INVALID_ARGUMENT;
317 return __http_header_add_field(&(http_msg_response->head), field, value, WITH_PARSING_OPTION);
320 da_result_t __http_header_add_field(http_header_t **head,
321 const char *field, const char *value, enum parsing_type type)
323 http_header_t *pre = NULL;
324 http_header_t *cur = NULL;
326 //DA_SECURE_LOGD("[%s][%s]", field, value);
331 /* Replace default value with user wanted value
332 * Remove the value which is stored before and add a new value.
334 if (cur->field && cur->raw_value &&
335 strncasecmp(cur->field, field, strlen(field)) == 0) {
336 DA_SECURE_LOGD("Remove value for replacement [%s][%s]", cur->field, cur->raw_value);
341 if (cur->raw_value) {
342 free(cur->raw_value);
343 cur->raw_value= NULL;
349 cur = (http_header_t *)calloc(1, sizeof(http_header_t));
351 cur->field = strdup(field);
352 cur->raw_value = strdup(value);
356 if (type == WITHOUT_PARSING_OPTION) {
357 cur->value = strdup(value);
360 __parsing_raw_value(cur);
368 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
369 return DA_ERR_FAIL_TO_MEMALLOC;
375 void __http_header_destroy_all_field(http_header_t **head)
377 http_header_t *pre = NULL;
378 http_header_t *cur = NULL;
380 DA_LOG_FUNC_LOGV(HTTPManager);
387 cur->field = DA_NULL;
392 cur->value = DA_NULL;
395 if (cur->raw_value) {
396 free(cur->raw_value);
397 cur->raw_value = DA_NULL;
400 __http_header_destroy_all_option(&(cur->options));
411 http_header_options_t *__create_http_header_option(const char *field,
414 http_header_options_t *option = NULL;
416 option = (http_header_options_t *)calloc(1,
417 sizeof(http_header_options_t));
420 option->field = strdup(field);
423 option->value = strdup(value);
431 void __http_header_destroy_all_option(http_header_options_t **head)
433 http_header_options_t *pre = NULL;
434 http_header_options_t *cur = NULL;
436 DA_LOG_FUNC_LOGV(HTTPManager);
442 DA_LOG_VERBOSE("field= %s", cur->field);
444 cur->field = DA_NULL;
449 cur->value = DA_NULL;
461 da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request,
462 http_msg_iter_t *http_msg_iter)
464 DA_LOG_FUNC_LOGV(HTTPManager);
466 if (!http_msg_request) {
467 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
468 return DA_ERR_INVALID_ARGUMENT;
471 *http_msg_iter = http_msg_request->head;
476 da_result_t http_msg_response_get_iter(http_msg_response_t *http_msg_response,
477 http_msg_iter_t *http_msg_iter)
479 if (!http_msg_response) {
480 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
481 return DA_ERR_INVALID_ARGUMENT;
484 *http_msg_iter = http_msg_response->head;
485 // DA_LOG_VERBOSE(HTTPManager, "retrieve iter = 0x%x", (unsigned int)http_msg_iter);
490 da_bool_t http_msg_get_field_with_iter(http_msg_iter_t *http_msg_iter,
491 char **out_field, char **out_value)
493 http_header_t *cur = *http_msg_iter;
495 // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur);
498 *out_field = cur->field;
499 *out_value = cur->value;
500 *http_msg_iter = cur->next;
504 // DA_LOG_VERBOSE(HTTPManager, "end of iter");
509 da_bool_t http_msg_get_header_with_iter(http_msg_iter_t *http_msg_iter,
510 char **out_field, http_header_t **out_header)
512 http_header_t *cur = *http_msg_iter;
514 // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur);
517 *out_field = cur->field;
519 *http_msg_iter = cur->next;
523 // DA_LOG_VERBOSE(HTTPManager, "end of iter");
528 http_header_options_t *__parsing_N_create_option_str(char *org_str)
530 char *option_field = NULL;
531 char *option_value = NULL;
532 int option_field_len = 0;
533 int option_value_len = 0;
535 char *org_pos = NULL;
538 char *working_str = NULL;
539 char *working_pos = NULL;
540 char *working_pos_field_start = NULL;
541 char *working_pos_value_start = NULL;
543 da_bool_t is_inside_quotation = DA_FALSE;
544 da_bool_t is_working_for_field = DA_TRUE;
546 http_header_options_t *option = NULL;
548 DA_LOG_FUNC_LOGV(HTTPManager);
553 org_str_len = strlen(org_str);
554 if (org_str_len <= 0)
557 working_str = (char *)calloc(1, org_str_len + 1);
562 working_pos_field_start = working_pos = working_str;
564 for (i = 0; i < org_str_len; i++) {
566 is_inside_quotation = !is_inside_quotation;
568 if (is_inside_quotation) {
569 // Leave anything including blank if it is inside of double quotation mark.
570 *working_pos = *org_pos;
571 is_working_for_field ? option_field_len++
572 : option_value_len++;
576 if (*org_pos == ' ') {
578 } else if (*org_pos == '=') {
579 if (is_working_for_field) {
580 is_working_for_field = DA_FALSE;
581 working_pos_value_start = working_pos;
586 *working_pos = *org_pos;
587 is_working_for_field ? option_field_len++
588 : option_value_len++;
595 if (option_field_len > 0 && working_pos_field_start) {
596 option_field = (char *)calloc(1, option_field_len + 1);
598 strncpy(option_field, working_pos_field_start,
602 if (option_value_len > 0 && working_pos_value_start) {
603 option_value = (char *)calloc(1, option_value_len + 1);
605 strncpy(option_value, working_pos_value_start,
611 working_pos = working_str = NULL;
614 // DA_SECURE_LOGD("option_field = [%s], option_value = [%s]",
615 // option_field, option_value);
617 if (option_field || option_value) {
618 option = __create_http_header_option(
619 option_field, option_value);
633 http_header_options_t *__parsing_options(char *org_str)
635 da_result_t ret = DA_RESULT_OK;
636 http_header_options_t *head = NULL;
637 http_header_options_t *pre = NULL;
638 http_header_options_t *cur = NULL;
640 int wanted_str_len = 0;
641 char *wanted_str = NULL;
642 char *wanted_str_start = NULL;
643 char *wanted_str_end = NULL;
644 char *cur_pos = NULL;
646 DA_LOG_FUNC_LOGV(HTTPManager);
651 /* Do Not use strtok(). It's not thread safe. */
652 // DA_SECURE_LOGD("org_str = %s", org_str);
657 wanted_str_start = cur_pos;
658 wanted_str_end = strchr(cur_pos, ';');
659 if (wanted_str_end) {
660 cur_pos = wanted_str_end + 1;
662 wanted_str_end = org_str + strlen(org_str);
666 wanted_str_len = wanted_str_end - wanted_str_start;
667 wanted_str = (char *)calloc(1, wanted_str_len + 1);
669 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
670 ret = DA_ERR_FAIL_TO_MEMALLOC;
673 strncpy(wanted_str, wanted_str_start, wanted_str_len);
675 // DA_SECURE_LOGD("wanted_str = [%s]", wanted_str);
676 cur = __parsing_N_create_option_str(wanted_str);
689 if (ret != DA_RESULT_OK)
690 __http_header_destroy_all_option(&head);
695 void __parsing_raw_value(http_header_t *http_header_field)
697 char *raw_value = NULL;
698 char *option_str_start = NULL;
700 char *trimed_value = NULL;
701 int trimed_value_len = 0;
703 char *trimed_value_start = NULL;
704 char *trimed_value_end = NULL;
706 raw_value = http_header_field->raw_value;
707 // DA_SECURE_LOGD("raw_value = [%s]", raw_value);
712 trimed_value_start = raw_value;
714 trimed_value_end = strchr(raw_value, ';');
715 if (!trimed_value_end) {
717 http_header_field->value = strdup(raw_value);
718 http_header_field->options = NULL;
724 trimed_value_len = trimed_value_end - trimed_value_start;
726 trimed_value = (char *)calloc(1, trimed_value_len + 1);
728 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
731 strncpy(trimed_value, trimed_value_start, trimed_value_len);
732 http_header_field->value = trimed_value;
734 // for option parsing
735 option_str_start = trimed_value_end + 1;
737 http_header_field->options = __parsing_options(option_str_start);
740 http_header_options_t *cur = NULL;
742 cur = http_header_field->options;
744 // DA_SECURE_LOGD("field = [%s], value = [%s]", cur->field, cur->value);
750 da_bool_t __get_http_header_option_for_field(
751 http_header_options_t *header_option, const char *in_field,
754 http_header_options_t *cur = NULL;
756 DA_LOG_FUNC_LOGV(HTTPManager);
758 if (!header_option) {
759 DA_LOG_ERR(HTTPManager, "input header_option is NULL.");
766 if (!strncasecmp(cur->field, in_field, strlen(cur->field)) &&
768 DA_SECURE_LOGD("[%s][%s]", cur->field, cur->value);
769 *out_value = cur->value;
780 da_bool_t __get_http_header_for_field(http_msg_response_t *http_msg_response,
781 const char *in_field, http_header_t **out_header)
783 http_msg_iter_t http_msg_iter;
784 http_header_t *header = NULL;
787 DA_LOG_FUNC_LOGV(HTTPManager);
789 http_msg_response_get_iter(http_msg_response, &http_msg_iter);
790 while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) {
791 if (field && header && !strncasecmp(field, in_field, strlen(field))) {
792 // DA_SECURE_LOGD("[%s][%s]", field, header->value);
793 *out_header = header;
801 void __exchange_header_value(http_header_t *header, const char *in_raw_value)
803 DA_LOG_FUNC_LOGV(HTTPManager);
805 if (!header || !in_raw_value)
808 __http_header_destroy_all_option(&(header->options));
812 header->value = DA_NULL;
815 if (header->raw_value)
816 free(header->raw_value);
817 header->raw_value = strdup(in_raw_value);
819 __parsing_raw_value(header);
822 da_bool_t http_msg_response_get_content_type(
823 http_msg_response_t *http_msg_response, char **out_type)
825 da_bool_t b_ret = DA_FALSE;
826 http_header_t *header = NULL;
828 DA_LOG_FUNC_LOGV(HTTPManager);
830 b_ret = __get_http_header_for_field(http_msg_response, "Content-Type",
833 DA_LOG(HTTPManager, "no Content-Type");
838 *out_type = strdup(header->value);
843 void http_msg_response_set_content_type(http_msg_response_t *http_msg_response,
846 da_bool_t b_ret = DA_FALSE;
847 http_header_t *header = NULL;
849 DA_LOG_FUNC_LOGV(HTTPManager);
851 if (!http_msg_response || !in_type)
854 b_ret = __get_http_header_for_field(http_msg_response, "Content-Type",
857 if (header->raw_value && (!strncmp(header->raw_value, in_type,
858 strlen(header->raw_value))))
861 DA_SECURE_LOGD("exchange Content-Type to [%s] from [%s]", in_type, header->value);
862 __exchange_header_value(header, in_type);
864 __http_header_add_field(&(http_msg_response->head),
865 "Content-Type", in_type, WITH_PARSING_OPTION);
869 da_bool_t http_msg_response_get_content_length(
870 http_msg_response_t *http_msg_response, unsigned long long *out_length)
872 da_bool_t b_ret = DA_FALSE;
873 http_header_t *header = NULL;
875 DA_LOG_FUNC_LOGV(HTTPManager);
877 b_ret = __get_http_header_for_field(http_msg_response,
878 "Content-Length", &header);
880 DA_LOG(HTTPManager, "no Content-Length");
885 *out_length = atoll(header->value);
890 da_bool_t http_msg_response_get_content_disposition(
891 http_msg_response_t *http_msg_response, char **out_disposition,
892 char **out_file_name)
894 da_bool_t b_ret = DA_FALSE;
895 http_header_t *header = NULL;
896 char *file_name = NULL;
898 char *wanted_str = NULL;
899 char *wanted_str_start = NULL;
900 char *wanted_str_end = NULL;
901 char *decoded_str = NULL;
902 int wanted_str_len = 0;
904 DA_LOG_FUNC_LOGV(HTTPManager);
906 b_ret = __get_http_header_for_field(http_msg_response,
907 "Content-Disposition", &header);
909 DA_LOG_VERBOSE(HTTPManager, "no Content-Disposition");
914 *out_disposition = strdup(header->value);
919 b_ret = __get_http_header_option_for_field(header->options, "filename",
922 DA_LOG(HTTPManager, "no option");
926 // eliminate double quotation mark if it exists on derived value
927 wanted_str_start = strchr(file_name, '"');
928 if (!wanted_str_start) {
929 *out_file_name = strdup(file_name);
932 // DA_SECURE_LOGD("wanted_str_start = [%s]", wanted_str_start);
934 wanted_str_end = strchr(wanted_str_start, '"');
935 if (wanted_str_end) {
936 wanted_str_len = wanted_str_end - wanted_str_start;
937 wanted_str = (char*)calloc(1, wanted_str_len + 1);
939 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
942 strncpy(wanted_str, wanted_str_start, wanted_str_len);
944 b_ret = is_base64_encoded_word(wanted_str);
946 DA_LOG(HTTPManager, "It's base64 encoded-word string");
947 if (DA_RESULT_OK == decode_base64_encoded_str(
948 wanted_str, &decoded_str)) {
949 DA_SECURE_LOGD("base64 decoded str = [%s]", decoded_str);
951 wanted_str = decoded_str;
954 DA_LOG(HTTPManager, "Fail to base64 decode. Just use un-decoded string.");
957 DA_LOG(HTTPManager, "It's NOT base64 encoded-word string");
959 decode_url_encoded_str(wanted_str, &decoded_str);
960 /* If it is url encoded string */
962 DA_SECURE_LOGD("Url decoded str = [%s]", decoded_str);
964 wanted_str = decoded_str;
968 *out_file_name = wanted_str;
970 DA_SECURE_LOGD("out_file_name = [%s]", *out_file_name);
974 DA_LOG_ERR(HTTPManager, "Not matched \" !");
980 da_bool_t http_msg_response_get_ETag(http_msg_response_t *http_msg_response,
983 da_bool_t b_ret = DA_FALSE;
984 http_header_t *header = NULL;
986 DA_LOG_FUNC_LOGV(HTTPManager);
988 b_ret = __get_http_header_for_field(http_msg_response, "ETag", &header);
990 DA_LOG_VERBOSE(HTTPManager, "no ETag");
995 *out_value = strdup(header->value);
1000 da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response,
1003 da_bool_t b_ret = DA_FALSE;
1004 http_header_t *header = NULL;
1006 DA_LOG_FUNC_LOGV(HTTPManager);
1008 b_ret = __get_http_header_for_field(http_msg_response, "Date", &header);
1010 DA_LOG(HTTPManager, "no Date");
1015 *out_value = strdup(header->value);
1020 da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response,
1023 da_bool_t b_ret = DA_FALSE;
1024 http_header_t *header = NULL;
1026 DA_LOG_FUNC_LOGV(HTTPManager);
1028 b_ret = __get_http_header_for_field(http_msg_response, "Location", &header);
1030 DA_LOG(HTTPManager, "no Location");
1034 *out_value = strdup(header->value);
1039 da_result_t http_msg_response_get_boundary(
1040 http_msg_response_t *http_msg_response, char **out_val)
1042 da_result_t ret = DA_RESULT_OK;
1044 http_msg_iter_t http_msg_iter;
1047 char *boundary = NULL;
1049 DA_LOG_FUNC_LOGV(HTTPManager);
1051 if (!http_msg_response) {
1052 DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
1053 return DA_ERR_INVALID_ARGUMENT;
1056 http_msg_response_get_iter(http_msg_response, &http_msg_iter);
1057 while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) {
1058 if ((field != DA_NULL) && (value != DA_NULL)) {
1059 if (!strncasecmp(field, "Content-Type",
1060 strlen("Content-Type"))) {
1061 char *org_str = NULL;
1062 char *boundary_str_start = NULL;
1063 char *boundary_value_start = NULL;
1064 char *boundary_value_end = NULL;
1065 int boundary_value_len = 0;
1070 = strstr(org_str, "boundary");
1071 if (boundary_str_start) {
1072 DA_LOG(HTTPManager, "boundary_str_start = %s", boundary_str_start);
1073 // this "Content-Type" value has "boundary" in it, so get the value
1074 boundary_value_start = strchr(
1075 boundary_str_start, '"');
1076 boundary_value_start += 1; // start without "
1078 boundary_value_end = strchr(
1079 boundary_value_start, '"');
1080 boundary_value_len = boundary_value_end
1081 - boundary_value_start;
1083 DA_LOG(HTTPManager, "boundary_value_start = %s", boundary_value_start);
1084 DA_LOG(HTTPManager, "boundary_value_end = %s", boundary_value_end);
1085 DA_LOG(HTTPManager, "boundary_value_len = %d", boundary_value_len);
1088 // no "boundary" field on this "Content-Type" value
1089 ret = DA_ERR_INVALID_ARGUMENT;
1094 boundary = (char *)calloc(1,
1095 boundary_value_len + 1);
1097 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
1098 ret = DA_ERR_FAIL_TO_MEMALLOC;
1102 strncpy(boundary, boundary_value_start,
1103 boundary_value_len);
1104 DA_SECURE_LOGD("[boundary][%s]", boundary);
1110 *out_val = boundary;
1116 char *get_http_response_header_raw(http_msg_response_t *http_msg_response)
1118 http_msg_iter_t http_msg_iter;
1119 http_header_t *header = NULL;
1121 char tmp_buf[1024*4] = {0,};
1122 char line_buf[1024] = {0,};
1126 DA_LOG_FUNC_LOGV(HTTPManager);
1128 http_msg_response_get_iter(http_msg_response, &http_msg_iter);
1129 while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) {
1130 if (field && header) {
1131 // FIXME later :: buffer length is more than total length. think about getting header's conent length from libsoup
1132 len = strlen(field) + strlen(header->value) + 2;
1133 snprintf(line_buf, len,"%s:%s", field, header->value);
1134 strncat(tmp_buf, line_buf, len);
1135 strcat(tmp_buf, "\n");
1138 if (strlen(tmp_buf) > 0) {
1139 buff = (char *)calloc(1, strlen(tmp_buf) + 1);
1140 if (buff == DA_NULL) {
1141 DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
1144 memcpy(buff, tmp_buf, strlen(tmp_buf));
1145 DA_SECURE_LOGD("\n---raw response header---\n%s\n------\n",buff);
1152 char *_stristr(const char *long_str, const char *find_str)
1155 int length_long = 0;
1156 int length_find = 0;
1157 char *ret_ptr = NULL;
1158 char *org_ptr = NULL;
1159 char *look_ptr = NULL;
1161 if (long_str == NULL || find_str == NULL) {
1162 DA_LOG_ERR(Default,"INVALID ARGUMENT");
1166 length_long = strlen(long_str);
1167 length_find = strlen(find_str);
1169 org_ptr = (char*)calloc(1, length_long + 1);
1171 if (org_ptr == NULL) {
1172 DA_LOG_ERR(Default,"INVALID ARGUMENT");
1176 look_ptr = (char*)calloc(1, length_find + 1);
1178 if (look_ptr == NULL) {
1179 DA_LOG_ERR(Default,"INVALID ARGUMENT");
1184 while (i < length_long) {
1185 if (isalpha(long_str[i]) != 0) {
1186 if (isupper(long_str[i]) != 0) {
1187 org_ptr[i] = long_str[i];
1189 org_ptr[i] = toupper(long_str[i]);
1192 org_ptr[i] = long_str[i];
1200 while (i < length_find) {
1201 if (isalpha(find_str[i]) != 0) {
1202 if (isupper(find_str[i]) != 0) {
1203 look_ptr[i] = find_str[i];
1205 look_ptr[i] = toupper(find_str[i]);
1208 look_ptr[i] = find_str[i];
1214 ret_ptr = strstr(org_ptr, look_ptr);
1221 i = ret_ptr - org_ptr;
1227 return (char*)(long_str + i);
1230 /* This is not used. But it can be needed if there is no http header parser at http library.*/
1231 da_bool_t extract_attribute_from_header(
1233 const char *szFindStr,
1237 char *pValuePos = NULL;
1241 int need_to_end_quataion_mark = 0;
1243 if (szHeadStr == DA_NULL || szFindStr == DA_NULL) {
1244 DA_LOG_ERR(Default,"INVALID ARGUMENT");
1248 if (strlen(szHeadStr) <= 0 || strlen(szFindStr) <= 0) {
1249 DA_LOG_ERR(Default,"INVALID ARGUMENT");;
1254 if (ppRtnValue == NULL) {
1258 pValuePos = _stristr(szHeadStr, (char*)szFindStr);
1259 if (pValuePos == NULL) {
1264 index = strlen(szFindStr);
1266 while (pValuePos[index] != ':' && pValuePos[index] != '=') {
1269 if (pValuePos[index] == '\0') {
1277 while (pValuePos[index] == ' ') {
1281 /* jump quatation mark */
1282 while (pValuePos[index] == '"') {
1283 need_to_end_quataion_mark = 1;
1289 /* Find the end of data. */
1290 if (0 == strncasecmp(szFindStr, "Location", strlen("Location")))//terminate character list does not contain ';' in case of URI
1292 while (DA_FALSE == IS_URI_TERMINATING_CHAR(pValuePos[index])) {
1295 } else if (need_to_end_quataion_mark) {
1296 while (DA_FALSE == IS_TERMINATING_CHAR_EX(pValuePos[index])) {
1300 while (DA_FALSE == IS_TERMINATING_CHAR(pValuePos[index])) {
1305 strLen = index - startPos;
1308 DA_LOG_ERR(Default," strLen is < 1");
1312 *ppRtnValue = (char*)calloc(1, sizeof(char) * (strLen + 1));
1314 if (*ppRtnValue == NULL) {
1315 DA_LOG_ERR(Default," *ppRtnValue is NULL");
1319 strncpy(*ppRtnValue, pValuePos + startPos, strLen);
1320 *(*ppRtnValue + strLen) = '\0';