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