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