2

I'm using libevent2 in my application to host a http server. I cant find a built-in way to compress the output.

These are the options I'm considering:

  1. Apply gzip/deflate compression using zlib in my app before sending out the response
  2. Hack libevent's http.c to expose evhttp_connection->bufev (the bufferevent object), and apply a zlib filter for outgoing data

(Both read the supported compression formats from the Accept-Encoding header)

Is there some easier way I'm overlooking, or is this pretty much it?

tejas
  • 607
  • 6
  • 11
  • 1
    That's pretty much it AFAICT. If you did #2 cleanly, I'd love to apply a patch for it, though. Some people on the libevent mailing list have started talking about refactoring the evhttp backend lately: you might want to join in there, if you're still interested in hacking that. – nickm Apr 29 '11 at 06:07

2 Answers2

1

I use this little trick to obtain the file descriptor of an evhttp_connection, which is right next to the pointer you want. It's a nasty hack, but it's simple, and easier that having to rebuild libevent. It has been tested under x86_64 and runs fine.

static void
send_document_cb(struct evhttp_request *req, void *arg)
{
  // ....

  struct evhttp_connection *this_connection;
  this_connection = evhttp_request_get_connection(req);

  int *tricky;
  tricky = (((int *)this_connection) + 4);
  int fd = *tricky;

  printf("fd: %i\n", fd);

  // ....
}

Looking at the structure definition (beneath), it appears the bufev you want should be accessible using (((void *)this_connection) + 8) or something very similar.

struct evhttp_connection { 
    TAILQ_ENTRY(evhttp_connection) next; 

    evutil_socket_t fd; 
    struct bufferevent *bufev; 

    ...   
}
Orwellophile
  • 13,235
  • 3
  • 69
  • 45
  • This is the only answer, and has been for the last 2 years. Please stop voting it down (-2 this week). It may not be pretty, but it works. Take you issues up with the authors of libevent. N.B. The OP stated: "Hack libevent's http.c" as an option. – Orwellophile Dec 05 '13 at 22:24
0

Non-hacky way to get the FD socket in 2022:

static void _genericCallback( evhttp_request *req, void *arg )
{
    evhttp_connection *conn = evhttp_request_get_connection( req );
    if( conn )
    {
        bufferevent *buffevt = evhttp_connection_get_bufferevent( conn );
        if( buffevt )
        {
            evutil_socket_t fd = bufferevent_getfd( buffevt );
            if( fd >= 0 )
            {
                // Use the socket
                setsockopt( fd, ... );
            }
        }
    }
}

evhttp_set_gencb( server, _genericCallback, 0 );