Hi Mohamed,

> Add proxy and http header notification plus address some
> comments from first patch.
> ---
>  gweb/gweb.c |  417 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 388 insertions(+), 29 deletions(-)
> 
> diff --git a/gweb/gweb.c b/gweb/gweb.c
> index 39f8ecf..7bee1e5 100644
> --- a/gweb/gweb.c
> +++ b/gweb/gweb.c
> @@ -35,6 +35,17 @@
>  #include "gresolv.h"
>  #include "gweb.h"
>  
> +#define MAX_CHUNK_LEN        17
> +
> +enum chunk_state {
> +     CHUNK_SIZE,
> +     CHUNK_R,
> +     CHUNK_R_BODY,
> +     CHUNK_N,
> +     CHUNK_N_BODY,
> +     CHUNK_DATA,
> +};
> +
>  struct web_session {
>       GWeb *web;
>  
> @@ -49,6 +60,21 @@ struct web_session {
>       guint resolv_action;
>       char *request;
>  
> +     enum chunk_state chunck_state;
> +     int chunk_size;
> +     int chunk_left;
> +
> +     GByteArray *line;
> +
> +     long int total_len;
> +     long int content_len;

would be consistently using size_t or ssize_t be better here?

> +     unsigned long int http_status;

So why is the http_status unsigned long int. The last time I checked it
is in the range from 100-900. So uint16_t would work just fine.

> +     gboolean use_chunk;
> +     gboolean header_ready;
> +     gboolean done;
> +

This might be better done as some sort of chunk_flags variable. Since a
gboolean is actually an int in the end.

> +     GWebReceivedFunc received_func;
>       GWebResultFunc result_func;
>       gpointer result_data;
>  };
> @@ -58,6 +84,10 @@ struct _GWeb {
>  
>       guint next_query_id;
>  
> +     char *proxy;
> +     uint16_t proxy_port;

We should leave the proxy part out for now. We can add that later. I
only mentioned it in the other email for something to keep in mind.

> +
> +     gboolean send_header;
>       int index;
>       GList *session_list;
>  
> @@ -101,6 +131,7 @@ static void free_session(struct web_session *session)
>       if (session->transport_channel != NULL)
>               g_io_channel_unref(session->transport_channel);
>  
> +     g_byte_array_free(session->line, TRUE);
>       g_free(session->host);
>       g_free(session->address);
>       g_free(session);
> @@ -118,33 +149,6 @@ static void flush_sessions(GWeb *web)
>       web->session_list = NULL;
>  }
>  

<snip>

I have not gone through these decoding functions yet. I still need to
have a deep look at them.

>  static gboolean received_data(GIOChannel *channel, GIOCondition cond,
>                                                       gpointer user_data)
>  {
>       struct web_session *session = user_data;
>       unsigned char buf[4096];
>       int sk, len;
> +     int err;
>  
>       if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
>               session->transport_watch = 0;
> @@ -216,7 +508,22 @@ static gboolean received_data(GIOChannel *channel, 
> GIOCondition cond,
>                       session->result_func(200, session->result_data);
>               return FALSE;
>       }
> -     printf("%s", buf);
> +
> +     err = decode_function(session, buf, len);
> +
> +     if (err < 0) {
> +             session->transport_watch = 0;
> +             if (session->result_func != NULL)
> +                     session->result_func(err, session->result_data);
> +             return FALSE;
> +     }
> +     if (session->done == TRUE) {
> +             session->transport_watch = 0;
> +             if (session->result_func != NULL)
> +                     session->result_func(session->http_status,
> +                                                     session->result_data);
> +             return FALSE;
> +     }
>  
>       return TRUE;
>  }
> @@ -265,6 +572,8 @@ static void start_request(struct web_session *session)
>       debug(session->web, "request %s from %s",
>                                       session->request, session->host);
>  
> +     init_download_data(session);
> +
>       sk = g_io_channel_unix_get_fd(session->transport_channel);
>  
>       buf = g_string_new(NULL);
> @@ -332,6 +641,43 @@ static int parse_url(struct web_session *session, const 
> char *url)
>       return 0;
>  }
>  
> +GWeb *g_web_new(int index, const char *proxy)
> +{
> +     GWeb *web;
> +
> +     if (index < 0)
> +             return NULL;
> +
> +     web = g_try_new0(GWeb, 1);
> +     if (web == NULL)
> +             return NULL;
> +
> +     web->ref_count = 1;
> +
> +     web->next_query_id = 1;
> +
> +     web->index = index;
> +     web->session_list = NULL;
> +
> +     web->resolv = g_resolv_new(index);
> +     if (web->resolv == NULL) {
> +             g_free(web);
> +             return NULL;
> +     }
> +
> +     if (proxy != NULL) {
> +             struct web_session session;
> +
> +             if (parse_url(&session, proxy) == 0) {
> +                     web->proxy = session.host;
> +                     web->proxy_port = session.port;
> +                     g_free(session.request);
> +             }
> +     }
> +
> +     return web;
> +}
> +

So here is a question. Do we really want to give a proxy URL? Or maybe
just a host (maybe plus port number) to connect to?

I don't really know the best answer here. So I am happy if others shim
in let me know their thoughts.

>  static void resolv_result(GResolvResultStatus status,
>                                       char **results, gpointer user_data)
>  {
> @@ -366,6 +712,7 @@ static void resolv_result(GResolvResultStatus status,
>  }
>  
>  guint g_web_request(GWeb *web, GWebMethod method, const char *url,
> +                             GWebReceivedFunc rec_func,
>                               GWebResultFunc func, gpointer user_data)
>  {
>       struct web_session *session;
> @@ -390,9 +737,21 @@ guint g_web_request(GWeb *web, GWebMethod method, const 
> char *url,
>  
>       session->result_func = func;
>       session->result_data = user_data;
> +     session->received_func = rec_func;
>  
> -     session->resolv_action = g_resolv_lookup_hostname(web->resolv,
> +     session->line = g_byte_array_new();
> +     if (session->line == NULL) {
> +             free_session(session);
> +             return 0;
> +     }

Please add an empty line here. These blocks a separate and you should
split them out.

That way it is a lot easier to read through that code and more important
to read over the error handling piece.

Also can g_byte_array_new() actually fail? Some of GLib functions are a
bit funny this way.

The documentation is not clear, but I looked into the code and it uses
g_slice_new which will halt the program if it runs out of memory. So the
error handling is rather pointless here.

> +     if (web->proxy != NULL) {
> +             session->port = web->proxy_port;
> +             session->resolv_action = g_resolv_lookup_hostname(web->resolv,
> +                                     web->proxy, resolv_result, session);
> +     } else
> +             session->resolv_action = g_resolv_lookup_hostname(web->resolv,
>                                       session->host, resolv_result, session);
> +
>       if (session->resolv_action == 0) {
>               free_session(session);
>               return 0;

Regards

Marcel


_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to