Update test program for redirection checks.
authorMohamed Abbas <mohamed.abbas@intel.com>
Tue, 19 Jan 2010 22:24:42 +0000 (14:24 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 20 Jan 2010 22:25:43 +0000 (14:25 -0800)
Parse the HTTP response header for redirection. This patch
also checks for proxy setting.

tools/portal-test.c

index 6aac971eb8aec47b915d084f738f75c5204d7959..da00cc663146df3930eeee03c17f436992009b02 100644 (file)
 #include <arpa/inet.h>
 
 #include <glib.h>
+#include <glib/gprintf.h>
 
 #define PORT 80
+#define PROXY_PORT 911
 #define PAGE "/"
+#define HOST "connman.net"
 #define USER_APP "connman"
 
-#define CONNECT_TIMEOUT         120
+#define CONNECT_TIMEOUT        120
+#define MAX_COUNTER    80
 
 enum get_page_status {
-       GET_PAGE_SUCCESS  = 0,
-       GET_PAGE_TIMEOUT  = 1,
-       GET_PAGE_FAILED   = 2,
+       GET_PAGE_SUCCESS        = 0,
+       GET_PAGE_TIMEOUT        = 1,
+       GET_PAGE_FAILED         = 2,
+       GET_PAGE_REDIRECTED     = 3,
 };
 
 struct server_data {
-       char host[80];
-       char page[80];
+       char host[MAX_COUNTER];
+       char page[MAX_COUNTER];
+       char proxy[MAX_COUNTER];
        GIOChannel *channel;
        guint watch;
        guint timeout;
        int connection_ready;
        int sock;
+       int proxy_port;
        int (*get_page) (struct server_data *data, char *page, int len,
                                                enum get_page_status status);
 };
@@ -79,14 +86,12 @@ static char *get_ip_from_host(char *host)
        char *ip;
        struct hostent *host_ent;
 
-       ip = malloc(ip_len + 1);
-       memset(ip, 0, ip_len + 1);
+       ip = g_try_malloc0(ip_len + 1);
        if ((host_ent = gethostbyname(host)) == NULL) {
                perror("Error: Can not get IP");
                exit(1);
        }
 
-       fprintf(stderr, "inside get_ip_from_host %d\n", 2);
        if (inet_ntop(AF_INET, (void *) host_ent->h_addr_list[0],
                                                        ip, ip_len) == NULL) {
                perror("Error: Can not resolve host");
@@ -105,7 +110,7 @@ static char *build_get_query(char *host, char *page)
        if(host_page[0] == '/')
                host_page = host_page + 1;
 
-       query = malloc(strlen(host) + strlen(host_page) +
+       query = g_try_malloc0(strlen(host) + strlen(host_page) +
                                        strlen(USER_APP) + strlen(tpl) - 5);
        sprintf(query, tpl, host_page, host, USER_APP);
 
@@ -140,8 +145,8 @@ static gboolean tcp_event(GIOChannel *channel, GIOCondition condition,
        int sk;
        struct server_data *data = user_data;
 
-       remove_timeout(data);
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               remove_timeout(data);
                data->watch = 0;
                if (data->get_page)
                        data->get_page(data, NULL, 0, GET_PAGE_FAILED);
@@ -153,6 +158,7 @@ static gboolean tcp_event(GIOChannel *channel, GIOCondition condition,
        len = recv(sk, buf, BUFSIZ, 0);
 
        if (len > 0) {
+               remove_timeout(data);
                if (data->get_page)
                        data->get_page(data, buf, len, GET_PAGE_SUCCESS);
        }
@@ -174,7 +180,7 @@ static gboolean socket_event(GIOChannel *channel, GIOCondition condition,
                sk = g_io_channel_unix_get_fd(channel);
 
                query = build_get_query(data->host, data->page);
-               fprintf(stderr, "qury is:\n%s\n", query);
+               fprintf(stderr, "query is:\n%s\n", query);
 
                while (send_counter < strlen(query)) {
                        ret = send(sk, query+send_counter,
@@ -185,13 +191,12 @@ static gboolean socket_event(GIOChannel *channel, GIOCondition condition,
                                if (data->get_page)
                                        data->get_page(data, NULL, 0,
                                                        GET_PAGE_FAILED);
-                               free(query);
+                               g_free(query);
                                return FALSE;
                        }
                        send_counter += ret;
                }
-               free(query);
-               fprintf(stdout, "%s \n", "Connection ready");
+               g_free(query);
        } else if (condition & G_IO_IN)
                tcp_event(channel, condition, user_data);
 
@@ -217,10 +222,12 @@ static int get_html(struct server_data *data, int ms_time)
        char *ip;
 
        data->connection_ready = 0;
-       fprintf(stderr, "create socket %d\n", 1); 
        data->sock = create_socket();
-       fprintf(stderr, "call get ip %d\n", 1);
-       ip = get_ip_from_host(data->host);
+       if (strlen(data->proxy) > 0)
+               ip = get_ip_from_host(data->proxy);
+       else
+               ip = get_ip_from_host(data->host);
+
        fprintf(stderr, "IP from host %s is %s\n", data->host, ip); 
 
        remote_host = g_try_new0(struct sockaddr_in, 1);
@@ -233,7 +240,10 @@ static int get_html(struct server_data *data, int ms_time)
                fprintf(stderr, "Error: wrong IP address:%s\n", ip);
                goto error;
        }
-       remote_host->sin_port = htons(PORT);
+       if (strlen(data->proxy) > 0)
+               remote_host->sin_port = htons(data->proxy_port);
+       else
+               remote_host->sin_port = htons(PORT);
 
        data->channel = g_io_channel_unix_new(data->sock);
        g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, NULL);
@@ -245,19 +255,18 @@ static int get_html(struct server_data *data, int ms_time)
        ret = connect(data->sock, (struct sockaddr *)remote_host,
                                                sizeof(struct sockaddr));
        if (ret < 0 && errno != EINPROGRESS) {
-               fprintf(stdout, "%d %d \n", ret, EINPROGRESS);
                perror("Could not connect");
                remove_timeout(data);
                goto error;
        }
 
        g_free(remote_host);
-       free(ip);
+       g_free(ip);
        return 0;
 
 error:
        g_free(remote_host);
-       free(ip);
+       g_free(ip);
 
        if (data->get_page)
                data->get_page(data, NULL, 0, GET_PAGE_FAILED);
@@ -265,32 +274,65 @@ error:
        return ret;
 }
 
-static int get_page_cb(struct server_data *data, char *page, int len,
-               enum get_page_status status)
+static int get_status(struct server_data *data, char *page, int len)
 {
-       fprintf(stdout, "\npage status %d\n", status);
-       if (status == GET_PAGE_SUCCESS && page != NULL && len > 0)
-               fprintf(stdout, "%s \n", page);
-       return 0;
+       gchar **lines;
+       gchar *str;
+       int i;
+       int ret = GET_PAGE_REDIRECTED;
+
+       lines = g_strsplit(page, "\n", 13);
+
+       str = g_strrstr(lines[0], "200 OK");
+       if (str != NULL) {
+               for (i = 0; lines[i] != NULL && i < 12; i++) {
+                       str = g_strstr_len(lines[i], 12, "Set-Cookie");
+                       if (str != NULL)
+                               ret = GET_PAGE_SUCCESS;
+               }
+       }
+       g_strfreev(lines);
+
+       return ret;
 }
 
-static void usage()
+static int get_page_cb(struct server_data *data, char *page, int len,
+               enum get_page_status status)
 {
-       fprintf(stderr, "USAGE: protal-test <host> [page]\n");
+       int ret = status;
+
+       if (page)
+               ret = get_status(data, page, len);
+
+       switch (ret) {
+       case GET_PAGE_SUCCESS:
+               fprintf(stderr, "%s\n", "Page was fetched");
+               break;
+       case GET_PAGE_REDIRECTED:
+               fprintf(stderr, "%s\n", "Page was redirected");
+               break;
+       case GET_PAGE_FAILED:
+               fprintf(stderr, "%s\n", "error can not get the page");
+               break;
+       case GET_PAGE_TIMEOUT:
+               fprintf(stderr, "%s\n", "Page was timeout");
+               break;
+       }
+       g_main_loop_quit(main_loop);
+
+       return ret;
 }
 
 int main(int argc, char **argv)
 {
-       char *host;
+       char *host = HOST;
        char *page = PAGE;
+       char *proxy;
        struct server_data *data;
 
-       if (argc == 1) {
-               usage();
-               exit(2);
-       }
+       if (argc > 1)
+               host = argv[1];
 
-       host = argv[1];
        if (argc > 2)
                page = argv[2];
 
@@ -298,6 +340,7 @@ int main(int argc, char **argv)
        if (data == NULL)
                exit(1);
 
+       memset(data, 0, sizeof(struct server_data));
        strcpy(data->host, host);
        strcpy(data->page, page);
        data->get_page = get_page_cb;
@@ -305,6 +348,26 @@ int main(int argc, char **argv)
 
        main_loop = g_main_loop_new(NULL, FALSE);
 
+       proxy = getenv("http_proxy");
+       if (proxy) {
+               char *delim;
+
+               if (strncmp(proxy, "http://", 7) == 0)
+                       strcpy(data->proxy, proxy + 7);
+               else
+                       strcpy(data->proxy, proxy);
+
+               delim = strchr(data->proxy, ':');
+               if (delim) {
+                       int len;
+
+                       len = delim - data->proxy;
+                       data->proxy[len] = '\0';
+
+                       data->proxy_port = atoi(delim + 1);
+               } else
+                       data->proxy_port = PROXY_PORT;
+       }
        get_html(data, CONNECT_TIMEOUT);
 
        g_main_loop_run(main_loop);