Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get all the HTTP headers from HTTP server response in libevent

Tags:

c

http

libevent

Using libevent to do HTTP request. I would like to print all the HTTP headers in the server response, but not sure how.

static void http_request_done(struct evhttp_request *req, void *ctx) {
    //how do I print out all the http headers in the server response 
}

evhttp_request_new(http_request_done,NULL);

I know I can get an individual header like the following, but how do I get all the headers?

static void http_request_done(struct evhttp_request *req, void *ctx) {
    struct evkeyvalq * kv = evhttp_request_get_input_headers(req);
    printf("%s\n", evhttp_find_header(kv, "SetCookie"));
}

Thanks.

like image 446
packetie Avatar asked Mar 19 '23 00:03

packetie


2 Answers

Though I don't have any previous experience with libevent library, it's rather clear for me that API doesn't provide such functionality (see its API for reference). However what you can do is to write your own method using TAILQ_FOREACH internal macro, which is defined in event-internal.h. Definition of evhttp_find_header is rather straightforward:

const char *
evhttp_find_header(const struct evkeyvalq *headers, const char *key)
{
    struct evkeyval *header;

    TAILQ_FOREACH(header, headers, next) {
        if (evutil_ascii_strcasecmp(header->key, key) == 0)
            return (header->value);
    }

    return (NULL);
}

Instead of doing evutil_ascii_strcasecmp you can just simply obtain header->key or header->value entries from evkeyval struct (defined in include/event2/keyvalq_struct.h):

/*
 * Key-Value pairs.  Can be used for HTTP headers but also for
 * query argument parsing.
 */
struct evkeyval {
    TAILQ_ENTRY(evkeyval) next;

    char *key;
    char *value;
};
like image 66
Grzegorz Szpetkowski Avatar answered Apr 08 '23 20:04

Grzegorz Szpetkowski


Thanks to helpful tips from @Grzegorz Szpetkowski, I created the following routine which works fine. The reason that "kv = kv->next.tqe_next" was used was because of "TAILQ_ENTRY(evkeyval) next" in the definition of struct evkeyval.

static void http_request_done(struct evhttp_request *req, void *ctx) {
    struct evkeyvalq *header = evhttp_request_get_input_headers(req);
    struct evkeyval* kv = header->tqh_first;
    while (kv) {
        printf("%s: %s\n", kv->key, kv->value);
        kv = kv->next.tqe_next;
    }
}
like image 28
packetie Avatar answered Apr 08 '23 22:04

packetie