从 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->key
或header->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.c
和include/event2/http.h
中的适当声明(原型)(你可能在你的程序中使用它)。
有点奇怪,我的程序只要不使用宏TAILQ_FOREACH就可以编译。似乎宏仅在内部头文件中。你怎么看?
@codingFun:它是内部函数式宏,不打算暴露给公共 API(所以你的程序不会编译),本质上只是一个 for
循环和另一个 TAILQ_FIRST
, TAILQ_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 + Comet(长轮询/Http-Stream)