在libevent中获取HTTP服务器响应的所有HTTP头信息

4
使用libevent进行HTTP请求。我想打印服务器响应中的所有HTTP标头,但不确定如何操作。
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);

我知道我可以像下面这样获取单个标题,但是如何获取所有标题?

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"));
}

谢谢。
2个回答

4
尽管我之前没有使用过libevent库,但对我来说很明显它的API没有提供这样的功能(参见其API)。但是,您可以使用TAILQ_FOREACH内部宏编写自己的方法,该宏在event-internal.h中定义。 evhttp_find_header的定义非常简单:
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);
}

您可以直接从evkeyval结构体(在include/event2/keyvalq_struct.h中定义)获取header->keyheader->value条目,而不是使用evutil_ascii_strcasecmp函数:

/*
 * 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;
};

感谢@Grzegorz Szpetkowski的快速回复,我在/usr/local/include/event2中没有找到“event-internal.h”。我可以将event-internal.h复制到该目录中,但犹豫不决,因为这更像是一个临时解决方案。 - packetie
@codingFun: 这是一种“hard-way”方法,因此需要下载libevent源代码,因此需要手动编译。根据我的检查,定义应该放在http.c中,适当的声明(原型)应该放在include/event2/http.h中(您可能正在程序中使用它)。 - Grzegorz Szpetkowski
我的程序如果不使用宏TAILQ_FOREACH就可以编译,这有点奇怪。看起来这个宏只在内部头文件中存在。你觉得呢? - packetie
@codingFun:这是一个内部函数宏,不打算公开到公共API(因此您的程序无法编译),本质上只是一个带有另一个TAILQ_FIRSTTAILQ_ENDTAILQ_NEXT函数宏的for循环。 - Grzegorz Szpetkowski

4
感谢@Grzegorz Szpetkowski提供的有用提示,我创建了以下有效的例程。使用"kv = kv->next.tqe_next"的原因是在struct evkeyval的定义中包含了"TAILQ_ENTRY(evkeyval) next"。
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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接