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.
19 #include <curl/curl.h>
22 #include "download-agent-dl-info.h"
23 #include "download-agent-http-mgr.h"
24 #include "download-agent-http-msg-handler.h"
26 static pthread_mutex_t mutex_da_info_list = PTHREAD_MUTEX_INITIALIZER;
27 da_info_t *da_info_list[DA_MAX_ID];
29 static void __init_da_info(int id)
31 da_info_t *da_info = DA_NULL;
32 file_info_t *file_info = DA_NULL;
33 http_info_t *http_info = DA_NULL;
34 req_info_t *req_info = DA_NULL;
36 da_info = (da_info_t *)calloc(1, sizeof(da_info_t));
38 DA_LOGE("Fail to calloc. id[%d]", id);
39 da_info_list[id] = DA_NULL;
42 file_info = (file_info_t *)calloc(1, sizeof(file_info_t));
44 DA_LOGE("Fail to calloc. id[%d]", id);
46 da_info_list[id] = DA_NULL;
49 http_info = (http_info_t *)calloc(1, sizeof(http_info_t));
51 DA_LOGE("Fail to calloc. id[%d]", id);
54 da_info_list[id] = DA_NULL;
57 req_info = (req_info_t *)calloc(1, sizeof(req_info_t));
59 DA_LOGE("Fail to calloc. id[%d]", id);
63 da_info_list[id] = DA_NULL;
67 da_info->da_id = DA_INVALID_ID;
68 da_info->thread_id = 0;
69 memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
70 da_info->is_cb_update = DA_FALSE;
71 da_info->http_info = http_info;
72 da_info->file_info = file_info;
73 da_info->req_info = req_info;
74 da_info->update_time = 0;
75 da_info_list[id] = da_info;
78 da_ret_t init_http_msg_t(http_msg_t **http_msg)
80 da_ret_t ret = DA_RESULT_OK;
81 http_msg_t *temp = DA_NULL;
82 temp = (http_msg_t *)calloc(1, sizeof(http_msg_t));
84 DA_LOGE("Fail to calloc. id");
85 return DA_ERR_FAIL_TO_MEMALLOC;
91 void destroy_http_msg_t(http_msg_t *http_msg)
99 da_ret_t get_available_da_id(int *available_id)
101 da_ret_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
104 DA_MUTEX_LOCK(&mutex_da_info_list);
105 for (i = 0; i < DA_MAX_ID; i++) {
106 if (da_info_list[i] == DA_NULL) {
108 DA_LOGV("available download id[%d]", *available_id);
114 DA_MUTEX_UNLOCK(&mutex_da_info_list);
119 da_ret_t get_da_info_with_da_id(int id, da_info_t **out_info)
121 da_ret_t ret = DA_ERR_INVALID_ARGUMENT;
124 DA_MUTEX_LOCK(&mutex_da_info_list);
125 for (i = 0; i < DA_MAX_ID; i++) {
126 if (DA_NULL != da_info_list[i] && da_info_list[i]->da_id == id) {
127 *out_info = da_info_list[i];
132 DA_MUTEX_UNLOCK(&mutex_da_info_list);
137 da_ret_t __is_supporting_protocol(const char *url)
139 da_ret_t ret = DA_RESULT_OK;
140 int wanted_str_len = 0;
141 char *protocol = NULL;
142 char *wanted_str_start = NULL;
143 char *wanted_str_end = NULL;
145 if (DA_NULL == url || strlen(url) < 1)
146 return DA_ERR_INVALID_URL;
148 wanted_str_start = (char*)url;
149 wanted_str_end = strstr(url, "://");
150 if (!wanted_str_end) {
151 DA_LOGE("No protocol on this url");
152 return DA_ERR_INVALID_URL;
155 wanted_str_len = wanted_str_end - wanted_str_start;
156 protocol = (char*)calloc(1, wanted_str_len + 1);
158 DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
159 return DA_ERR_FAIL_TO_MEMALLOC;
161 strncpy(protocol, wanted_str_start, wanted_str_len);
163 if (strlen(protocol) < 1)
164 ret = DA_ERR_UNSUPPORTED_PROTOCAL;
165 else if (strcasecmp(protocol, "http") != 0 &&
166 strcasecmp(protocol, "https") != 0)
167 ret = DA_ERR_UNSUPPORTED_PROTOCAL;
173 da_ret_t copy_user_input_data(da_info_t *da_info, const char *url,
174 req_data_t *ext_data, da_cb_t *da_cb_data)
176 da_ret_t ret = DA_RESULT_OK;
178 if (!url || !da_info) {
179 DA_LOGE("Invalid Param");
180 return DA_ERR_INVALID_ARGUMENT;
183 ret = __is_supporting_protocol(url);
184 if (ret != DA_RESULT_OK) {
185 DA_SECURE_LOGE("url[%s]", url);
190 req_info_t *req_info = da_info->req_info;
192 if (ext_data->request_header_count > 0) {
194 int count = ext_data->request_header_count;
195 req_info->req_header = (char **)calloc(count, sizeof(char *));
196 if (DA_NULL == req_info->req_header) {
197 DA_LOGE("Fail to calloc");
199 da_info->req_info = DA_NULL;
200 return DA_ERR_FAIL_TO_MEMALLOC;
202 for (i = 0; i < count; i++) {
203 if (ext_data->request_header[i])
204 req_info->req_header[i] =
205 strdup(ext_data->request_header[i]);
207 req_info->req_header_count = count;
211 req_info->url = strdup(url);
213 req_info->proxy = strdup(ext_data->proxy);
214 if (ext_data->install_path)
215 req_info->install_path = strdup(ext_data->install_path);
216 if (ext_data->file_name)
217 req_info->file_name = strdup(ext_data->file_name);
219 req_info->etag = strdup(ext_data->etag);
220 if (ext_data->temp_file_path)
221 req_info->temp_file_path = strdup(ext_data->temp_file_path);
222 if (ext_data->pkg_name)
223 req_info->pkg_name = strdup(ext_data->pkg_name);
224 if (ext_data->user_req_data)
225 req_info->user_req_data = ext_data->user_req_data;
226 if (ext_data->user_client_data)
227 req_info->user_client_data = ext_data->user_client_data;
229 req_info->network_bonding = ext_data->network_bonding;
230 req_info->disable_verify_host = ext_data->disable_verify_host;
231 req_info->cache = ext_data->cache;
233 da_info->req_info = req_info;
236 da_info->is_cb_update = DA_TRUE;
237 memcpy(&(da_info->cb_info), da_cb_data, sizeof(da_cb_t));
242 static void __destroy_http_msg(http_msg_t *msg)
248 static void __destroy_http_msg_request(http_msg_request_t *msg)
251 http_msg_request_destroy(&msg);
256 static void __destroy_http_msg_response(http_msg_response_t *msg)
259 http_msg_response_destroy(&msg);
264 static void __destroy_req_info(req_info_t *req_info)
267 NULL_CHECK_AND_FREE(req_info->url);
268 if (req_info->req_header && req_info->req_header_count > 0) {
270 int count = req_info->req_header_count;
271 for (i = 0; i < count; i++) {
272 NULL_CHECK_AND_FREE(req_info->req_header[i]);
273 req_info->req_header[i] = DA_NULL;
275 NULL_CHECK_AND_FREE(req_info->req_header);
276 req_info->req_header = DA_NULL;
277 req_info->req_header_count = 0;
279 NULL_CHECK_AND_FREE(req_info->proxy);
280 NULL_CHECK_AND_FREE(req_info->install_path);
281 NULL_CHECK_AND_FREE(req_info->file_name);
282 NULL_CHECK_AND_FREE(req_info->etag);
283 NULL_CHECK_AND_FREE(req_info->temp_file_path);
284 NULL_CHECK_AND_FREE(req_info->pkg_name);
285 req_info->user_req_data = DA_NULL;
286 req_info->user_client_data = DA_NULL;
287 NULL_CHECK_AND_FREE(req_info);
291 static void __destroy_proxy_info(proxy_info_t *proxy_info)
294 NULL_CHECK_AND_FREE(proxy_info->addr);
295 proxy_info->addr = DA_NULL;
296 NULL_CHECK_AND_FREE(proxy_info->user_name);
297 proxy_info->user_name = DA_NULL;
298 NULL_CHECK_AND_FREE(proxy_info->password);
299 proxy_info->password = DA_NULL;
300 NULL_CHECK_AND_FREE(proxy_info);
304 void destroy_http_info(http_info_t *http_info)
307 NULL_CHECK_AND_FREE(http_info->location_url);
308 NULL_CHECK_AND_FREE(http_info->content_type_from_header);
309 NULL_CHECK_AND_FREE(http_info->etag_from_header);
310 NULL_CHECK_AND_FREE(http_info->cache_control_from_header);
311 NULL_CHECK_AND_FREE(http_info->last_modified_from_header);
312 NULL_CHECK_AND_FREE(http_info->file_name_from_header);
313 if (http_info->proxy_info) {
314 __destroy_proxy_info(http_info->proxy_info);
315 http_info->proxy_info = DA_NULL;
317 if (http_info->http_msg_request) {
318 __destroy_http_msg_request(http_info->http_msg_request);
319 http_info->http_msg_request = DA_NULL;
321 if (http_info->http_msg_response) {
322 __destroy_http_msg_response(http_info->http_msg_response);
323 http_info->http_msg_response = DA_NULL;
325 if (http_info->http_msg) {
326 __destroy_http_msg(http_info->http_msg);
327 http_info->http_msg = DA_NULL;
329 DA_MUTEX_DESTROY(&(http_info->mutex_state));
330 DA_MUTEX_DESTROY(&(http_info->mutex_http));
331 DA_COND_DESTROY(&(http_info->cond_http));
332 NULL_CHECK_AND_FREE(http_info);
336 void destroy_file_info(file_info_t *file_info)
339 file_info->file_handle = DA_NULL;
340 NULL_CHECK_AND_FREE(file_info->pure_file_name);
341 NULL_CHECK_AND_FREE(file_info->extension);
342 NULL_CHECK_AND_FREE(file_info->file_path);
343 NULL_CHECK_AND_FREE(file_info->mime_type);
344 NULL_CHECK_AND_FREE(file_info->buffer);
345 file_info->buffer_len = 0;
346 file_info->file_size = 0;
348 file_info->file_size_of_temp_file = 0;
350 file_info->bytes_written_to_file = 0;
351 file_info->is_updated = DA_FALSE;
352 NULL_CHECK_AND_FREE(file_info);
356 // For pause and resume case
357 void reset_http_info_for_resume(http_info_t *http_info)
360 DA_LOGI("[TEST] location_url[%p]", http_info->location_url);
361 NULL_CHECK_AND_FREE(http_info->location_url);
362 http_info->location_url = DA_NULL;
363 NULL_CHECK_AND_FREE(http_info->content_type_from_header);
364 http_info->content_type_from_header = DA_NULL;
365 if (http_info->proxy_info) {
366 __destroy_proxy_info(http_info->proxy_info);
367 http_info->proxy_info = DA_NULL;
369 if (http_info->http_msg_response) {
370 __destroy_http_msg_response(http_info->http_msg_response);
371 http_info->http_msg_response = DA_NULL;
373 if (http_info->http_msg) {
374 __destroy_http_msg(http_info->http_msg);
375 http_info->http_msg = DA_NULL;
377 http_info->http_method = HTTP_METHOD_GET;
378 http_info->content_len_from_header = 0;
379 http_info->total_size = 0;
383 da_bool_t is_valid_download_id(int download_id)
385 da_ret_t ret = DA_RESULT_OK;
388 DA_MUTEX_LOCK(&mutex_da_info_list);
389 if (DA_NULL == da_info_list[download_id]) {
390 DA_MUTEX_UNLOCK(&mutex_da_info_list);
393 if (is_stopped_state(da_info_list[download_id])) {
394 DA_MUTEX_UNLOCK(&mutex_da_info_list);
397 if (da_info_list[download_id]->da_id != DA_INVALID_ID) {
398 DA_MUTEX_UNLOCK(&mutex_da_info_list);
401 DA_MUTEX_UNLOCK(&mutex_da_info_list);
404 DA_MUTEX_UNLOCK(&mutex_da_info_list);
408 void destroy_da_info_list()
411 DA_MUTEX_LOCK(&mutex_da_info_list);
412 for (i = 0; i < DA_MAX_ID; i++) {
413 if (DA_NULL != da_info_list[i]) {
414 if (da_info_list[i]->thread_id) {
415 DA_LOGI("%lu is running. wait for the download thread.",
416 da_info_list[i]->thread_id);
417 pthread_join(da_info_list[i]->thread_id, NULL);
420 if (da_info_list[i]->req_info) {
421 __destroy_req_info(da_info_list[i]->req_info);
422 da_info_list[i]->req_info = DA_NULL;
424 if (da_info_list[i]->http_info) {
425 destroy_http_info(da_info_list[i]->http_info);
426 da_info_list[i]->http_info = DA_NULL;
428 if (da_info_list[i]->file_info) {
429 destroy_file_info(da_info_list[i]->file_info);
430 da_info_list[i]->file_info = DA_NULL;
432 free(da_info_list[i]);
433 da_info_list[i] = DA_NULL;
436 DA_MUTEX_UNLOCK(&mutex_da_info_list);
439 void destroy_da_info(int id)
441 da_info_t *da_info = DA_NULL;
442 DA_MUTEX_LOCK(&mutex_da_info_list);
443 da_info = da_info_list[id];
445 if (da_info->req_info) {
446 __destroy_req_info(da_info->req_info);
447 da_info->req_info = DA_NULL;
449 if (da_info->http_info) {
450 destroy_http_info(da_info->http_info);
451 da_info->http_info = DA_NULL;
453 if (da_info->file_info) {
454 destroy_file_info(da_info->file_info);
455 da_info->file_info = DA_NULL;
457 da_info->da_id = DA_INVALID_ID;
458 da_info->thread_id = 0;
459 memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
461 da_info_list[id] = DA_NULL;
463 DA_MUTEX_UNLOCK(&mutex_da_info_list);