Почему evhttp_request_get_connection() всегда возвращает NULL?

В следующем примере программы:

#include <event2/event.h>
#include <event2/http.h>
#include <assert.h>

void response_cb(struct evhttp_request* req, void *arg) {
    assert(evhttp_request_get_response_code(req)<400);/* passes */
    assert(evhttp_request_get_connection(req));/* FAILS ??? */
}

int main(int argc, char **argv) {
    struct event_base* ev_base;
    struct evhttp_connection *http_conn;
    struct evhttp_request *req;

    ev_base = event_base_new();
    http_conn = evhttp_connection_base_new(ev_base, NULL, "google.com", 80);
    req = evhttp_request_new(response_cb, NULL);

    evhttp_make_request(http_conn, req, EVHTTP_REQ_GET, "/");

    event_base_dispatch(ev_base);
    return -1;
}

в response_cb первое утверждение проходит, как и ожидалось, но секунды терпят неудачу, т.е. evhttp_request_get_connection(req) возвращает NULL. Почему это?

Документация для утверждений evhttp_request_get_connection:

Возвращает объект соединения, связанный с запросом, или NULL.

Но у меня все еще есть связь. Я его никуда не выбрасываю.

Я что-то не так делаю или это баг или какая-то непонятная фича?


person Svetlin Mladenov    schedule 22.07.2013    source источник


Ответы (1)


Вы не можете получить указатель на соединение в ответном обратном вызове, потому что соединение уже было освобождено (закрыто или оставлено открытым для повторного использования, если включена поддержка активности HTTP).

Вы можете видеть в evhttp_connection_done() (http.c, строки с 780 по 817), что обратный вызов ответа вызывается после того, как поле соединения запроса (evcon) было установлено в NULL. Я согласен с тем, что API evhttp не очень ясен.

person Remi Gacogne    schedule 22.07.2013
comment
keep-alive, похоже, не имеет ничего общего с этой проблемой. Согласно http.c: evhttp_connection_done() req-›evcon = NULL устанавливается для всех исходящих соединений, а не только для соединений без поддержки активности. - person Svetlin Mladenov; 22.07.2013
comment
Ну, это был пример, а не тщательная проверка всех случаев, когда соединение может быть использовано повторно. Извините, если так показалось. - person Remi Gacogne; 22.07.2013