从 libevent 中的 HTTP 服务器响应中获取所有 HTTP 标头

Posted

技术标签:

【中文标题】从 libevent 中的 HTTP 服务器响应中获取所有 HTTP 标头【英文标题】:get all the HTTP headers from HTTP server response in libevent 【发布时间】:2014-07-19 15:41:09 【问题描述】:

使用 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"));

谢谢。

【问题讨论】:

【参考方案1】:

虽然我以前没有使用 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 复制到目录中,但犹豫了一下,因为这更像是一个杂物。 @codingFun:这是“hard-way”方法,需要下载libevent源码,需要手动编译。正如我检查的定义应该放在http.cinclude/event2/http.h 中的适当声明(原型)(你可能在你的程序中使用它)。 有点奇怪,我的程序只要不使用宏TAILQ_FOREACH就可以编译。似乎宏仅在内部头文件中。你怎么看? @codingFun:它是内部函数式宏,不打算暴露给公共 API(所以你的程序不会编译),本质上只是一个 for 循环和另一个 TAILQ_FIRSTTAILQ_END, TAILQ_NEXT f-l 宏。【参考方案2】:

感谢@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;
    

【讨论】:

以上是关于从 libevent 中的 HTTP 服务器响应中获取所有 HTTP 标头的主要内容,如果未能解决你的问题,请参考以下文章

Libevent HTTP 服务器和压缩?

同一 fd 上不同线程中的多个 libevent 基础

Libevent + Comet(长轮询/Http-Stream)

带有 libevent 的多线程 HTTP 服务器

libevent学习笔记 —— 牛刀小试:简易的响应式服务器

libevent2 http 未检测到客户端网络中断