static int answer_articleselect(struct evbuffer *buf, const boardheader_t *bptr, const char *rest_key, select_part_func sfunc, void *ctx) { char path[PATH_MAX]; const char *ck, *filename; int cklen, offset, maxlen = 0; struct stat st; if (!parse_articlepart_key(rest_key, &ck, &cklen, &offset, &maxlen, &filename)) return -1; if (!is_valid_article_filename(filename)) return -1; setbfile(path, bptr->brdname, filename); if (answer_file(buf, path, &st, ck, cklen, offset, maxlen) < 0) return -1; int sel_offset, sel_size; int len = evbuffer_get_length(buf); if (sfunc(evbuffer_pullup(buf, len), len, &sel_offset, &sel_size, ctx) != 0 || evbuffer_slice(buf, sel_offset, sel_size) != 0) return -1; struct evbuffer *meta = evbuffer_new(); evbuffer_add_printf(meta, "%d-%d,%lu,%d,%d\n", (int) st.st_dev, (int) st.st_ino, st.st_size, sel_offset, sel_size); evbuffer_prepend_buffer(buf, meta); evbuffer_free(meta); return 0; }
static void drain_body(struct request_ctx *req, struct bufferevent *bev) { struct evbuffer *buf; struct evbuffer *saved; int before, after; if (req->chunked && req->chunk_size == -1) { /* Transfer-Encoding: chunked but we don't have size yet. */ if (read_chunk_size(req, bev) != 0) { verbose(ERROR, "%s(): could not read chunk size!\n", __func__); } } buf = bufferevent_get_input(bev); saved = NULL; before = evbuffer_get_length(buf); if (req->chunked && req->chunk_size > 0 && req->chunk_left < before) { /* * Save the real buffer away and give the callback * a temporary one, just the chunk that remains. */ saved = buf; buf = evbuffer_new(); evbuffer_remove_buffer(saved, buf, req->chunk_left); before = evbuffer_get_length(buf); } req->cb_ops->read(buf, req->cb_arg); after = evbuffer_get_length(buf); req->consumed += before - after; req->chunk_left -= (before - after); if (req->chunk_size > 0 && req->chunk_left == 0) { /* We've consumed the whole chunk. * Signal that we need another one. */ req->chunk_size = -1; } if (saved != NULL) { /* saved is actually the buffer in bev */ evbuffer_prepend_buffer(saved, buf); evbuffer_free(buf); } if ((req->chunked && req->chunk_size == 0) || (req->content_length > 0 && req->consumed == req->content_length)) { set_read_state(req, READ_DONE); } }
static void backend_cb(evhtp_request_t * backend_req, void * arg) { evhtp_request_t * frontend_req = (evhtp_request_t *)arg; evbuffer_prepend_buffer(frontend_req->buffer_out, backend_req->buffer_in); evhtp_headers_add_headers(frontend_req->headers_out, backend_req->headers_in); /* * char body[1024] = { '\0' }; * ev_ssize_t len = evbuffer_copyout(frontend_req->buffer_out, body, sizeof(body)); * printf("Backend %zu: %s\n", len, body); */ evhtp_send_reply(frontend_req, EVHTP_RES_OK); evhtp_request_resume(frontend_req); }