X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gweb%2Fgweb.c;h=9c9fcd1be19abbc02f3a3cd21299e20066eac90a;hb=b2e8ddc37278588c7364770a6e98cda76cc9b540;hp=2f4644585bca4f9512de68c27eb197d0e3c07f11;hpb=07be2d2c1b6a96535535108092bde5d4a1f714c7;p=framework%2Fconnectivity%2Fconnman.git diff --git a/gweb/gweb.c b/gweb/gweb.c index 2f46445..9c9fcd1 100644 --- a/gweb/gweb.c +++ b/gweb/gweb.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "giognutls.h" #include "gresolv.h" @@ -63,6 +64,7 @@ struct web_session { char *host; uint16_t port; unsigned long flags; + struct addrinfo *addr; char *content_type; @@ -106,6 +108,7 @@ struct _GWeb { char *proxy; char *accept_option; char *user_agent; + char *user_agent_profile; char *http_version; gboolean close_connection; @@ -151,16 +154,25 @@ static void free_session(struct web_session *session) g_io_channel_unref(session->transport_channel); g_free(session->result.last_key); - g_hash_table_destroy(session->result.headers); - g_string_free(session->send_buffer, TRUE); - g_string_free(session->current_header, TRUE); + if (session->result.headers != NULL) + g_hash_table_destroy(session->result.headers); + + if (session->send_buffer != NULL) + g_string_free(session->send_buffer, TRUE); + + if (session->current_header != NULL) + g_string_free(session->current_header, TRUE); + g_free(session->receive_buffer); g_free(session->content_type); g_free(session->host); g_free(session->address); + if (session->addr != NULL) + freeaddrinfo(session->addr); + g_free(session); } @@ -233,6 +245,7 @@ void g_web_unref(GWeb *web) g_free(web->accept_option); g_free(web->user_agent); + g_free(web->user_agent_profile); g_free(web->http_version); g_free(web); @@ -255,7 +268,14 @@ gboolean g_web_set_proxy(GWeb *web, const char *proxy) return FALSE; g_free(web->proxy); - web->proxy = g_strdup(proxy); + + if (proxy == NULL) { + web->proxy = NULL; + debug(web, "clearing proxy"); + } else { + web->proxy = g_strdup(proxy); + debug(web, "setting proxy %s", web->proxy); + } return TRUE; } @@ -330,6 +350,19 @@ gboolean g_web_set_user_agent(GWeb *web, const char *format, ...) return result; } +gboolean g_web_set_ua_profile(GWeb *web, const char *profile) +{ + if (web == NULL) + return FALSE; + + g_free(web->user_agent_profile); + + web->user_agent_profile = g_strdup(profile); + debug(web, "setting user agent profile %s", web->user_agent); + + return TRUE; +} + gboolean g_web_set_http_version(GWeb *web, const char *version) { if (web == NULL) @@ -342,7 +375,7 @@ gboolean g_web_set_http_version(GWeb *web, const char *version) debug(web, "clearing HTTP version"); } else { web->http_version = g_strdup(version); - debug(web, "setting HTTP version %s", web->http_version); + debug(web, "setting HTTP version %s", web->http_version); } return TRUE; @@ -466,6 +499,11 @@ static void start_request(struct web_session *session) g_string_append_printf(buf, "User-Agent: %s\r\n", session->web->user_agent); + if (session->web->user_agent_profile != NULL) { + g_string_append_printf(buf, "x-wap-profile: %s\r\n", + session->web->user_agent_profile); + } + if (session->web->accept_option != NULL) g_string_append_printf(buf, "Accept: %s\r\n", session->web->accept_option); @@ -848,10 +886,9 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond, static int connect_session_transport(struct web_session *session) { GIOFlags flags; - struct sockaddr_in sin; int sk; - sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + sk = socket(session->addr->ai_family, SOCK_STREAM, IPPROTO_TCP); if (sk < 0) return -EIO; @@ -877,12 +914,8 @@ static int connect_session_transport(struct web_session *session) g_io_channel_set_close_on_unref(session->transport_channel, TRUE); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(session->port); - sin.sin_addr.s_addr = inet_addr(session->address); - - if (connect(sk, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + if (connect(sk, session->addr->ai_addr, + session->addr->ai_addrlen) < 0) { if (errno != EINPROGRESS) { close(sk); return -EIO; @@ -914,7 +947,8 @@ static int create_transport(struct web_session *session) return 0; } -static int parse_url(struct web_session *session, const char *url) +static int parse_url(struct web_session *session, + const char *url, const char *proxy) { char *scheme, *host, *port, *path; @@ -945,7 +979,52 @@ static int parse_url(struct web_session *session, const char *url) if (path != NULL) *(path++) = '\0'; - session->request = g_strdup_printf("/%s", path ? path : ""); + if (proxy == NULL) + session->request = g_strdup_printf("/%s", path ? path : ""); + else + session->request = g_strdup(url); + + port = strrchr(host, ':'); + if (port != NULL) { + char *end; + int tmp = strtol(port + 1, &end, 10); + + if (*end == '\0') { + *port = '\0'; + session->port = tmp; + } + + if (proxy == NULL) + session->host = g_strdup(host); + else + session->host = g_strdup_printf("%s:%u", host, tmp); + } else + session->host = g_strdup(host); + + g_free(scheme); + + if (proxy == NULL) + return 0; + + scheme = g_strdup(proxy); + if (scheme == NULL) + return -EINVAL; + + host = strstr(proxy, "://"); + if (host != NULL) { + *host = '\0'; + host += 3; + + if (strcasecmp(scheme, "http") != 0) { + g_free(scheme); + return -EINVAL; + } + } else + host = scheme; + + path = strchr(host, '/'); + if (path != NULL) + *(path++) = '\0'; port = strrchr(host, ':'); if (port != NULL) { @@ -958,7 +1037,7 @@ static int parse_url(struct web_session *session, const char *url) } } - session->host = g_strdup(host); + session->address = g_strdup(host); g_free(scheme); @@ -969,6 +1048,9 @@ static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data) { struct web_session *session = user_data; + struct addrinfo hints; + char *port; + int ret; if (results == NULL || results[0] == NULL) { call_result_func(session, 404); @@ -977,7 +1059,18 @@ static void resolv_result(GResolvResultStatus status, debug(session->web, "address %s", results[0]); - if (inet_aton(results[0], NULL) == 0) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + + if (session->addr != NULL) { + freeaddrinfo(session->addr); + session->addr = NULL; + } + + port = g_strdup_printf("%u", session->port); + ret = getaddrinfo(results[0], port, &hints, &session->addr); + g_free(port); + if (ret != 0 || session->addr == NULL) { call_result_func(session, 400); return; } @@ -1005,13 +1098,16 @@ static guint do_request(GWeb *web, const char *url, if (session == NULL) return 0; - if (parse_url(session, url) < 0) { + if (parse_url(session, url, web->proxy) < 0) { free_session(session); return 0; } - debug(web, "host %s:%u", session->host, session->port); + debug(web, "address %s", session->address); + debug(web, "port %u", session->port); + debug(web, "host %s", session->host); debug(web, "flags %lu", session->flags); + debug(web, "request %s", session->request); if (type != NULL) { session->content_type = g_strdup(type); @@ -1044,7 +1140,7 @@ static guint do_request(GWeb *web, const char *url, session->header_done = FALSE; session->body_done = FALSE; - if (inet_aton(session->host, NULL) == 0) { + if (session->address == NULL && inet_aton(session->host, NULL) == 0) { session->resolv_action = g_resolv_lookup_hostname(web->resolv, session->host, resolv_result, session); if (session->resolv_action == 0) { @@ -1052,7 +1148,29 @@ static guint do_request(GWeb *web, const char *url, return 0; } } else { - session->address = g_strdup(session->host); + struct addrinfo hints; + char *port; + int ret; + + if (session->address == NULL) + session->address = g_strdup(session->host); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + + if (session->addr != NULL) { + freeaddrinfo(session->addr); + session->addr = NULL; + } + + port = g_strdup_printf("%u", session->port); + ret = getaddrinfo(session->address, port, &hints, + &session->addr); + g_free(port); + if (ret != 0 || session->addr == NULL) { + free_session(session); + return 0; + } if (create_transport(session) < 0) { free_session(session);