From: Seonah Moon Date: Tue, 12 Nov 2019 11:39:34 +0000 (+0900) Subject: Support proxy authentication X-Git-Tag: submit/tizen_5.5/20191212.014826^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c129163856a1f20b10aeefbd9459b495b094fd54;p=platform%2Fframework%2Fweb%2Fdownload-provider.git Support proxy authentication Change-Id: I66b65fe2417db65bb2b0973ca950de2abd7dfea8 --- diff --git a/agent/download-agent-dl-info.c b/agent/download-agent-dl-info.c index fbb0233..26150c0 100644 --- a/agent/download-agent-dl-info.c +++ b/agent/download-agent-dl-info.c @@ -346,14 +346,30 @@ static void __destroy_req_info(req_info_t *req_info) } } +static void __destroy_proxy_info(proxy_info_t *proxy_info) +{ + if (proxy_info) { + NULL_CHECK_AND_FREE(proxy_info->addr); + proxy_info->addr = DA_NULL; + NULL_CHECK_AND_FREE(proxy_info->user_name); + proxy_info->user_name = DA_NULL; + NULL_CHECK_AND_FREE(proxy_info->password); + proxy_info->password = DA_NULL; + NULL_CHECK_AND_FREE(proxy_info); + } +} + void destroy_http_info(http_info_t *http_info) { if (http_info) { NULL_CHECK_AND_FREE(http_info->location_url); - NULL_CHECK_AND_FREE(http_info->proxy_addr); NULL_CHECK_AND_FREE(http_info->content_type_from_header); NULL_CHECK_AND_FREE(http_info->etag_from_header); NULL_CHECK_AND_FREE(http_info->file_name_from_header); + if (http_info->proxy_info) { + __destroy_proxy_info(http_info->proxy_info); + http_info->proxy_info = DA_NULL; + } if (http_info->http_msg_request) { __destroy_http_msg_request(http_info->http_msg_request); http_info->http_msg_request = DA_NULL; @@ -400,10 +416,12 @@ void reset_http_info_for_resume(http_info_t *http_info) DA_LOGI("[TEST] location_url[%p]", http_info->location_url); NULL_CHECK_AND_FREE(http_info->location_url); http_info->location_url = DA_NULL; - NULL_CHECK_AND_FREE(http_info->proxy_addr); - http_info->proxy_addr = DA_NULL; NULL_CHECK_AND_FREE(http_info->content_type_from_header); http_info->content_type_from_header = DA_NULL; + if (http_info->proxy_info) { + __destroy_proxy_info(http_info->proxy_info); + http_info->proxy_info = DA_NULL; + } if (http_info->http_msg_response) { __destroy_http_msg_response(http_info->http_msg_response); http_info->http_msg_response = DA_NULL; @@ -424,10 +442,12 @@ void reset_http_info(http_info_t *http_info) DA_LOGI("[TEST] location_url[%p]", http_info->location_url); free(http_info->location_url); http_info->location_url = DA_NULL; - free(http_info->proxy_addr); - http_info->proxy_addr = DA_NULL; free(http_info->content_type_from_header); http_info->content_type_from_header = DA_NULL; + if (http_info->proxy_info) { + __destroy_proxy_info(http_info->proxy_info); + http_info->proxy_info = DA_NULL; + } if (http_info->http_msg_request) { __destroy_http_msg_request(http_info->http_msg_request); http_info->http_msg_request = DA_NULL; diff --git a/agent/download-agent-http-mgr.c b/agent/download-agent-http-mgr.c index 56228db..c09567f 100755 --- a/agent/download-agent-http-mgr.c +++ b/agent/download-agent-http-mgr.c @@ -30,6 +30,7 @@ #include "download-provider-client-manager.h" void __http_update_cb(http_raw_data_t *data, void *user_param); +static proxy_info_t *__get_proxy_info(); #define CONVERT_STR(NAME) (#NAME) @@ -346,13 +347,7 @@ da_ret_t __start_transaction(da_info_t *da_info) return DA_ERR_INVALID_ARGUMENT; } http_info->http_method = HTTP_METHOD_GET; - char* proxy_addr = da_info->req_info->proxy; - if (proxy_addr && strlen(proxy_addr) > 0) { - DA_LOGI("User proxy : %s", proxy_addr); - http_info->proxy_addr = strdup(proxy_addr); - } else { - http_info->proxy_addr = get_proxy_address(); - } + http_info->proxy_info = __get_proxy_info(); ret = PI_http_start(da_info); @@ -1128,6 +1123,65 @@ static void __handle_empty_file(da_info_t *da_info) free(transfer_encoding); } +static proxy_info_t *__get_proxy_info() +{ + proxy_info_t *proxy_info = DA_NULL; + char scheme[DA_MAX_SCHEME_LEN] = {0, }; + char user_name[DA_MAX_USER_NAME_LEN] = {0, }; + char password[DA_MAX_PASSWORD_LEN] = {0, }; + char host[DA_MAX_PROXY_ADDR_LEN] = {0, }; // ip:port + char *proxy_uri = get_proxy_address(); // scheme://userinfo@ip:port + + if (proxy_uri && !strstr(proxy_uri, "0.0.0.0")) { + proxy_info = (proxy_info_t *)calloc(1, sizeof(proxy_info_t)); + if (!proxy_info) { + DA_LOGE("Failed to calloc"); + free(proxy_uri); + return DA_NULL; + } + + char *found = strrchr(proxy_uri, '@'); + if (found) { + char userinfo[DA_MAX_USER_NAME_LEN + DA_MAX_PASSWORD_LEN + 1] = {0, }; + strncpy(userinfo, proxy_uri, strlen(proxy_uri) - strlen(found)); + if (strstr(userinfo, SCHEME_DELIMETER)) + sscanf(userinfo, "%7[^:/]://%255[^:]:%255s", scheme, user_name, password); + else + sscanf(userinfo, "%255[^:]:%255s", user_name, password); + + sscanf(found + 1, "%63s", host); + if (strlen(host) == 0) { + DA_LOGE("Invalid proxy address"); + free(proxy_info); + free(proxy_uri); + return DA_NULL; + } + + if (strlen(scheme) == 0) + strncpy(scheme, DEFAULT_SCHEME, DA_MAX_SCHEME_LEN - 1); + + size_t addr_len = strlen(scheme) + strlen(host) + 4; + proxy_info->addr = (char *)calloc(1, addr_len); + if (!proxy_info->addr) { + DA_LOGE("Failed to calloc"); + free(proxy_info); + free(proxy_uri); + return DA_NULL; + } + snprintf(proxy_info->addr, addr_len - 1, "%s://%s", scheme, host); + } else { + proxy_info->addr = strdup(proxy_uri); + } + proxy_info->user_name = strlen(user_name) > 0 ? strdup(user_name) : DA_NULL; + proxy_info->password = strlen(password) > 0 ? strdup(password) : DA_NULL; + free(proxy_uri); + } + + DA_LOGD("host[%s] user_name[%s] password[***]", host, user_name); + + return proxy_info; +} + da_ret_t __handle_event_http_header(http_raw_data_t *raw_data, da_info_t *da_info) { da_ret_t ret = DA_RESULT_OK; diff --git a/agent/download-agent-plugin-libcurl.c b/agent/download-agent-plugin-libcurl.c index 60b51a9..f28949e 100755 --- a/agent/download-agent-plugin-libcurl.c +++ b/agent/download-agent-plugin-libcurl.c @@ -306,38 +306,22 @@ long __http_finished_cb(void *ptr) } -da_ret_t __set_proxy_on_soup_session(char *proxy_addr, CURL *curl) +da_ret_t __set_proxy_on_soup_session(proxy_info_t *proxy_info, CURL *curl) { da_ret_t ret = DA_RESULT_OK; - if (proxy_addr && strlen(proxy_addr) > 0) { - DA_SECURE_LOGI("received proxy[%s]", proxy_addr); - if (!strstr(proxy_addr, "0.0.0.0")) { - if (strstr((const char *)proxy_addr, "http") == DA_NULL) { - char *tmp_str = DA_NULL; - int needed_len = 0; - - needed_len = strlen(proxy_addr) + strlen( - SCHEME_HTTP) + 1; - tmp_str = (char *) calloc(1, needed_len); - if (!tmp_str) { - DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - snprintf(tmp_str, needed_len, "%s%s", - SCHEME_HTTP, proxy_addr); - - curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr); - - free(tmp_str); - } else { - DA_LOGV("There is \"http\" on uri, so, push this address to soup directly."); - curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr); - } + if (proxy_info && strlen(proxy_info->addr) > 0) { + if (!strstr(proxy_info->addr, "0.0.0.0")) { + curl_easy_setopt(curl, CURLOPT_PROXY, proxy_info->addr); + if (proxy_info->user_name || proxy_info->password) + curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + if (proxy_info->user_name) + curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxy_info->user_name); + if (proxy_info->password) + curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxy_info->password); } } -ERR: + return ret; } @@ -487,7 +471,7 @@ da_ret_t PI_http_start(da_info_t *da_info) curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, LOW_SPEED_TIME); curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1L); - __set_proxy_on_soup_session(http_info->proxy_addr, curl); + __set_proxy_on_soup_session(http_info->proxy_info, curl); curl_easy_setopt(curl, CURLOPT_URL, url); switch (http_method) { diff --git a/agent/include/download-agent-dl-info.h b/agent/include/download-agent-dl-info.h index 44ebe25..6e0e674 100644 --- a/agent/include/download-agent-dl-info.h +++ b/agent/include/download-agent-dl-info.h @@ -120,6 +120,12 @@ typedef struct { typedef void (*http_update_cb) (http_raw_data_t *data, void *user_param); typedef struct { + char *addr; + char *user_name; + char *password; +} proxy_info_t; + +typedef struct { char *location_url; http_state_t state; pthread_mutex_t mutex_state; @@ -129,7 +135,7 @@ typedef struct { http_msg_response_t *http_msg_response; http_method_t http_method; http_msg_t *http_msg; - char *proxy_addr; + proxy_info_t *proxy_info; char *content_type_from_header; char *file_name_from_header; da_size_t content_len_from_header; diff --git a/agent/include/download-agent-type.h b/agent/include/download-agent-type.h index 41aa67b..b433b6b 100755 --- a/agent/include/download-agent-type.h +++ b/agent/include/download-agent-type.h @@ -33,8 +33,12 @@ typedef unsigned long long da_size_t; #define DA_MAX_STR_LEN 256 #define DA_MAX_MIME_STR_LEN 256 #define DA_MAX_PROXY_ADDR_LEN 64 // e.g. 100.200.300.400:10000 +#define DA_MAX_SCHEME_LEN 8 +#define DA_MAX_USER_NAME_LEN 256 +#define DA_MAX_PASSWORD_LEN 256 -#define SCHEME_HTTP "http://" +#define DEFAULT_SCHEME "http" +#define SCHEME_DELIMETER "://" #define DA_DEFAULT_INSTALL_PATH_FOR_PHONE tzplatform_getenv(TZ_USER_DOWNLOADS) // #define DA_DEFAULT_INSTALL_PATH_FOR_PHONE "/home/owner/content/Downloads"