int add_data_to_buf(void) { struct evbuffer *bufin = evbuffer_new(); struct evbuffer *bufout = evbuffer_new(); evbuffer_add_printf(bufin, "%s/%d", "hello", 1); size_t len = evbuffer_get_length(bufin); assert(7 == len); evbuffer_add_buffer(bufout, bufin); /* read from @bufin to @bufout. */ assert(evbuffer_get_length(bufin) == 0); assert(evbuffer_get_length(bufout) == 7); evbuffer_add(bufout, "nihao", 5); /* you can set num=6, include the '\0' */ assert(evbuffer_get_length(bufout) == 12); evbuffer_add_printf(bufout, "%s/%d", "word", 1); assert(evbuffer_get_length(bufout) == 18); /* hello/1nihaoword/1 */ evbuffer_prepend(bufout, "ppppp", 5); assert(evbuffer_get_length(bufout) == 23); /* hello/1nihaoword/1 */ char *b = evbuffer_pullup(bufout, -1); assert(strcmp(b, "ppppphello/1nihaoword/1") == 0); evbuffer_drain(bufout, -1); assert(evbuffer_get_length(bufout) == 0); }
void send_search_result(struct bufferevent *bev, struct evbuffer *result, size_t count) { struct packet_search_result data; data.hdr.proto = PROTO_EDONKEY; data.hdr.length = sizeof(data) - sizeof(data.hdr) + evbuffer_get_length(result); data.opcode = OP_SEARCHRESULT; data.files_count = count; evbuffer_prepend(result, &data, sizeof(data)); bufferevent_write_buffer(bev, result); }
static void test_evbuffer(void *ptr) { static char buffer[512], *tmp; struct evbuffer *evb = evbuffer_new(); struct evbuffer *evb_two = evbuffer_new(); size_t sz_tmp; int i; evbuffer_validate(evb); evbuffer_add_printf(evb, "%s/%d", "hello", 1); evbuffer_validate(evb); tt_assert(evbuffer_get_length(evb) == 7); tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1)); evbuffer_add_buffer(evb, evb_two); evbuffer_validate(evb); evbuffer_drain(evb, strlen("hello/")); evbuffer_validate(evb); tt_assert(evbuffer_get_length(evb) == 1); tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1)); evbuffer_add_printf(evb_two, "%s", "/hello"); evbuffer_validate(evb); evbuffer_add_buffer(evb, evb_two); evbuffer_validate(evb); tt_assert(evbuffer_get_length(evb_two) == 0); tt_assert(evbuffer_get_length(evb) == 7); tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0); memset(buffer, 0, sizeof(buffer)); evbuffer_add(evb, buffer, sizeof(buffer)); evbuffer_validate(evb); tt_assert(evbuffer_get_length(evb) == 7 + 512); tmp = (char *)evbuffer_pullup(evb, 7 + 512); tt_assert(tmp); tt_assert(!strncmp(tmp, "1/hello", 7)); tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer))); evbuffer_validate(evb); evbuffer_prepend(evb, "something", 9); evbuffer_validate(evb); evbuffer_prepend(evb, "else", 4); evbuffer_validate(evb); tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7); tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7)); evbuffer_validate(evb); evbuffer_drain(evb, -1); evbuffer_validate(evb); evbuffer_drain(evb_two, -1); evbuffer_validate(evb); for (i = 0; i < 3; ++i) { evbuffer_add(evb_two, buffer, sizeof(buffer)); evbuffer_validate(evb_two); evbuffer_add_buffer(evb, evb_two); evbuffer_validate(evb); evbuffer_validate(evb_two); } tt_assert(evbuffer_get_length(evb_two) == 0); tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer)); /* test remove buffer */ sz_tmp = (size_t)(sizeof(buffer)*2.5); evbuffer_remove_buffer(evb, evb_two, sz_tmp); tt_assert(evbuffer_get_length(evb_two) == sz_tmp); tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2); evbuffer_validate(evb); if (memcmp(evbuffer_pullup( evb, -1), buffer, sizeof(buffer) / 2) != 0 || memcmp(evbuffer_pullup( evb_two, -1), buffer, sizeof(buffer) != 0)) tt_abort_msg("Pullup did not preserve content"); evbuffer_validate(evb); /* testing one-vector reserve and commit */ { struct evbuffer_iovec v[1]; char *buf; int i, j, r; for (i = 0; i < 3; ++i) { r = evbuffer_reserve_space(evb, 10000, v, 1); tt_int_op(r, ==, 1); tt_assert(v[0].iov_len >= 10000); tt_assert(v[0].iov_base != NULL); evbuffer_validate(evb); buf = v[0].iov_base; for (j = 0; j < 10000; ++j) { buf[j] = j; } evbuffer_validate(evb); tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0); evbuffer_validate(evb); tt_assert(evbuffer_get_length(evb) >= 10000); evbuffer_drain(evb, j * 5000); evbuffer_validate(evb); } } end: evbuffer_free(evb); evbuffer_free(evb_two); }
void evhtp_send_reply_chunk_start(evhtp_request_t * request, evhtp_res code) { evhtp_header_t * content_len; if (evhtp_response_needs_body(code, request->method)) { content_len = evhtp_headers_find_header(request->headers_out, "Content-Length"); switch (request->proto) { case EVHTP_PROTO_11: /* * prefer HTTP/1.1 chunked encoding to closing the connection; * note RFC 2616 section 4.4 forbids it with Content-Length: * and it's not necessary then anyway. */ evhtp_kv_rm_and_free(request->headers_out, content_len); request->chunked = 1; break; case EVHTP_PROTO_10: /* * HTTP/1.0 can be chunked as long as the Content-Length header * is set to 0 */ evhtp_kv_rm_and_free(request->headers_out, content_len); evhtp_headers_add_header(request->headers_out, evhtp_header_new("Content-Length", "0", 0, 0)); request->chunked = 1; break; default: request->chunked = 0; break; } /* switch */ } else { request->chunked = 0; } if (request->chunked == 1) { evhtp_headers_add_header(request->headers_out, evhtp_header_new("Transfer-Encoding", "chunked", 0, 0)); /* * if data already exists on the output buffer, we automagically convert * it to the first chunk. */ if (evbuffer_get_length(request->buffer_out) > 0) { char lstr[128]; int sres; sres = snprintf(lstr, sizeof(lstr), "%x\r\n", (unsigned)evbuffer_get_length(request->buffer_out)); if (sres >= sizeof(lstr) || sres < 0) { /* overflow condition, shouldn't ever get here, but lets * terminate the connection asap */ goto end; } evbuffer_prepend(request->buffer_out, lstr, strlen(lstr)); evbuffer_add(request->buffer_out, "\r\n", 2); } } end: evhtp_send_reply_start(request, code); } /* evhtp_send_reply_chunk_start */