【问题标题】:get all the HTTP headers from HTTP server response in libevent从 libevent 中的 HTTP 服务器响应中获取所有 HTTP 标头
【发布时间】: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"));
}

谢谢。

【问题讨论】:

    标签: c http libevent


    【解决方案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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2014-02-26
      • 2016-06-04
      相关资源
      最近更新 更多