Hi Mohamed,

> While we reading header add header <key, value> to hashtable and
> allow user to ask for specific header.
> ---
>  gweb/gweb.c |   36 ++++++++++++++++++++++++++++++++++++
>  gweb/gweb.h |    2 ++
>  2 files changed, 38 insertions(+), 0 deletions(-)
> 
> diff --git a/gweb/gweb.c b/gweb/gweb.c
> index eb31ae9..fbcb173 100644
> --- a/gweb/gweb.c
> +++ b/gweb/gweb.c
> @@ -44,6 +44,7 @@ struct _GWebResult {
>       guint16 status;
>       const guint8 *buffer;
>       gsize length;
> +     GHashTable *headers;
>  };
>  
>  struct web_session {
> @@ -122,6 +123,7 @@ static void free_session(struct web_session *session)
>       if (session->transport_channel != NULL)
>               g_io_channel_unref(session->transport_channel);
>  
> +     g_hash_table_destroy(session->result.headers);
>       g_string_free(session->current_header, TRUE);
>       g_free(session->receive_buffer);
>  
> @@ -391,6 +393,15 @@ static gboolean received_data(GIOChannel *channel, 
> GIOCondition cond,
>  
>               debug(session->web, "[header] %s", str);
>  
> +             pos = memchr(str, ':', session->current_header->len);
> +             if (pos != NULL) {
> +                     *pos = '\0';
> +                     pos++;
> +                     g_hash_table_insert(session->result.headers,
> +                                             g_strdup(str),
> +                                             g_strdup((char *)pos));
> +             }
> +

so I do have to quote the specification here:

4.2 Message Headers

   HTTP header fields, which include general-header (section 4.5),
   request-header (section 5.3), response-header (section 6.2), and
   entity-header (section 7.1) fields, follow the same generic format as
   that given in Section 3.1 of RFC 822 [9]. Each header field consists
   of a name followed by a colon (":") and the field value. Field names
   are case-insensitive. The field value MAY be preceded by any amount
   of LWS, though a single SP is preferred. Header fields can be
   extended over multiple lines by preceding each extra line with at
   least one SP or HT. Applications ought to follow "common form", where
   one is known or indicated, when generating HTTP constructs, since
   there might exist some implementations that fail to accept anything
   beyond the common forms.

So even if we ignore the multi line headers right now, you still need to
do a bit more for separating field name and value field.

And please use g_hash_table_replace() instead of insert. See the GLib
documentation for details or test it by yourself. There is a different.

>               g_string_truncate(session->current_header, 0);
>       }
>  
> @@ -602,6 +613,14 @@ guint g_web_request(GWeb *web, GWebMethod method, const 
> char *url,
>               return 0;
>       }
>  
> +     session->result.headers = g_hash_table_new_full(g_str_hash, g_str_equal,
> +                                                     g_free, g_free);
> +

This extra empty line is not needed. The NULL check should be always
close to the allocation.

> +     if (session->result.headers == NULL) {
> +             free_session(session);
> +             return 0;
> +     }
> +
>       session->receive_space = DEFAULT_BUFFER_SIZE;
>       session->current_header = g_string_sized_new(0);
>       session->header_done = FALSE;
> @@ -654,6 +673,23 @@ gboolean g_web_result_get_chunk(GWebResult *result,
>       return TRUE;
>  }
>  
> +gboolean g_web_result_get_header(GWebResult *result,
> +                             const char *header, const char **value)
> +{
> +     if (result == NULL)
> +             return FALSE;
> +
> +     if (value == NULL)
> +             return FALSE;
> +
> +     *value = g_hash_table_lookup(result->headers, header);
> +
> +     if (*value == NULL)
> +             return FALSE;
> +
> +     return TRUE;
> +}
> +
>  struct _GWebParser {
>       gint ref_count;
>       char *begin_token;
> diff --git a/gweb/gweb.h b/gweb/gweb.h
> index df947e0..48be1a8 100644
> --- a/gweb/gweb.h
> +++ b/gweb/gweb.h
> @@ -70,6 +70,8 @@ gboolean g_web_cancel(GWeb *web, guint id);
>  
>  guint16 g_web_result_get_status(GWebResult *result);
>  
> +gboolean g_web_result_get_header(GWebResult *result,
> +                             const char *header, const char **value);
>  gboolean g_web_result_get_chunk(GWebResult *result,
>                               const guint8 **chunk, gsize *length);

Rest looks fine to me.

Regards

Marcel


_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to