Support proxy authentication 16/219916/1 accepted/tizen/unified/20191217.123000 submit/tizen/20191212.014813
authorSeonah Moon <seonah1.moon@samsung.com>
Tue, 12 Nov 2019 11:39:34 +0000 (20:39 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Wed, 11 Dec 2019 11:43:59 +0000 (20:43 +0900)
Change-Id: I66b65fe2417db65bb2b0973ca950de2abd7dfea8

agent/download-agent-dl-info.c
agent/download-agent-http-mgr.c
agent/download-agent-plugin-libcurl.c
agent/include/download-agent-dl-info.h
agent/include/download-agent-type.h

index 750cb1a..0b313e5 100644 (file)
@@ -345,14 +345,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;
@@ -399,10 +415,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;
@@ -423,10 +441,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;
index ad410b2..790c60b 100755 (executable)
@@ -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);
 
@@ -1117,6 +1112,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;
index 60b51a9..f28949e 100755 (executable)
@@ -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) {
index 44ebe25..6e0e674 100644 (file)
@@ -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;
index 41aa67b..b433b6b 100755 (executable)
@@ -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"