[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Connections not closed by evhttp



Hi,

I'm getting some weird behavior from evhttp that looks like a bug.

First, I connect to the server.  The server then replies with some
headers and the start of a chunked body.  After that, I close the
connection by closing the browser tab.  lsof reports that the
connection goes into the CLOSE_WAIT state and stays there
indefinitely.  (Calling 'lsof -c ehttpd | grep TCP' to check that).  I
would expect that the server would close the connection and most
likely call the close callback.

If I comment out bufferevent_disable(evcon->bufev, EV_READ); I then
get the close event correctly.  Otherwise, I don't get a close until I
try to send data.  I'm doing an expensive computation in another
thread that takes a long time and ties up resources, so I need to get
the close event as close to when it happens as reasonably possible.

The included code produces the problem for me.

Is there something that I'm doing wrong, and how can I fix this behavior?

Thanks,
    Austin Schuh

----------------------------------------------------------------------

#include <signal.h>
#include <assert.h>
#include <stddef.h>

#include "event2/thread.h"
#include "evhttp.h"

void close_cb(struct evhttp_connection *con, void *dummy) {
  assert(false);
}

void StreamingCloseTest(struct evhttp_request *request, void *dummy) {
  evhttp_connection_set_closecb(
      evhttp_request_get_connection(request),
      &close_cb, NULL);

  struct evkeyvalq *output_headers =
      evhttp_request_get_output_headers(request);

  evhttp_add_header(output_headers, "Content-Type",
                    "multipart/x-mixed-replace;"
                    "boundary=boundarydonotcross");

  evbuffer *evoutput = evbuffer_new();
  evbuffer_add_printf(evoutput, "<html>");

  evhttp_send_reply_start(request, HTTP_OK, NULL);

  evhttp_send_reply_chunk(request, evoutput);
}

int main(int argc, char **argv) {
  assert(evthread_use_pthreads() == 0);

  struct event_base *evbase = event_init();
  struct evhttp *evhttp = evhttp_new(evbase);

  evhttp_set_gencb(evhttp, &StreamingCloseTest, NULL);
  evhttp_bind_socket_with_handle(evhttp, NULL, 4242);
  event_base_dispatch(evbase);

  return 0;
}
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.