4

I am using libevent and its http API to write a simple HTTP server capable of writing C servlets. This servlet is working ok with GET but now I am sending some data with POST and I would like to read the incoming event buffer evb. I would like to print/inspect the data present in evb but I cannot. Do you know how I can put the data in evb (evbuffer) in char* variable? I saw only methods to manipulate buffers but not reading it. I tried:

evb->

This is the code:

    #include <stdio.h>
    #include "servlet.h"

    void servlet(struct evhttp_request *req, struct evbuffer *evb) {
        time_t now;
        time(&now);
        evbuffer_add_printf(evb, "<html>\n <head>\n"
            "  <title>%s</title>\n"
            " </head>\n"
            " <body>\n"
            "  <h1>%s</h1>\n"
            " <p>Current time is: %s</p>",
            "C servlet engine", "C servlet", ctime(&now));
        evhttp_add_header(evhttp_request_get_output_headers(req),
            "Content-Type", "text/html");
        evhttp_send_reply(req, 200, "OK", evb);
    }

I am trying this 

void servlet(struct evhttp_request *req, struct evbuffer *evb) {
    size_t len = evbuffer_get_length(evhttp_request_get_input_buffer(req));
    struct evbuffer *in_evb = evhttp_request_get_input_buffer(req);
    char *data;
    evbuffer_copyout(in_evb, data, len);

but I get Bus error: 10 (I am on a mac)

rtacconi
  • 14,317
  • 20
  • 66
  • 84

3 Answers3

3

Sounds like you want to use

ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data, size_t datalen)

It copies the buffer contents (at most datalen bytes) to the memory area data. It's documented in the libevent book

johlo
  • 5,422
  • 1
  • 18
  • 32
2

here's a method that works:

static void echo_read_cb(struct bufferevent *bev, void *ctx)
{
/* This callback is invoked when there is data to read on bev. */
struct evbuffer *input = bufferevent_get_input(bev);
struct evbuffer *output = bufferevent_get_output(bev);

size_t len = evbuffer_get_length(input);
char *data;
data = malloc(len);
evbuffer_copyout(input, data, len);

printf("we got some data: %s\n", data);

/* Copy all the data from the input buffer to the output buffer. */
evbuffer_add_buffer(output, input);
free(data);
}
collo21
  • 105
  • 1
  • 10
2

According the source code in buffer.h of libevent, we should use

int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);

instead of

ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen);

Here is the code borrowed from buffer.h

/**
  Read data from an evbuffer and drain the bytes read.

  If more bytes are requested than are available in the evbuffer, we
  only extract as many bytes as were available.

  @param buf the evbuffer to be read from
  @param data the destination buffer to store the result
  @param datlen the maximum size of the destination buffer
  @return the number of bytes read, or -1 if we can't drain the buffer.
 */
int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);

/**
  Read data from an evbuffer, and leave the buffer unchanged.

  If more bytes are requested than are available in the evbuffer, we
  only extract as many bytes as were available.

  @param buf the evbuffer to be read from
  @param data_out the destination buffer to store the result
  @param datlen the maximum size of the destination buffer
  @return the number of bytes read, or -1 if we can't drain the buffer.
 */
ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen);
charles.cc.hsu
  • 689
  • 11
  • 15