libevent2中的分块响应

时间:2010-03-18 07:15:02

标签: c libevent transfer-encoding chunked-encoding

我试图用这种方式做一个chunked响应(大文件)::

evhttp_send_reply_start(request, HTTP_OK, "OK");

int fd = open("filename", O_RDONLY);
size_t fileSize = <get_file_size>;
struct evbuffer *databuff = NULL;
for (off_t offset = 0;offset < fileSize;)
{
    databuff = evbuffer_new();

    size_t bytesLeft = fileSize - offset;
    size_t bytesToRead = bytesLeft > MAX_READ_SIZE ? MAX_READ_SIZE : bytesLeft;

    evbuffer_add_file(databuff, fd, offset, bytesToRead);
    offset += bytesToRead;

    evhttp_send_reply_chunk(request, databuff); // send it
    evbuffer_free(databuff);                    // destroy it
}

evhttp_send_reply_end(request);

fclose(fptr);

问题在于我有一种感觉add_file是异步的,所以第3个左右evhttp_send_reply_chunk给了我一个错误(或类似的东西):

  

[warn] evhttp_send_chain已关闭(45):错误的文件描述符

我将MAX_READ_SIZE设置为8以实际测试分块传输编码。

我注意到我可以使用evhttp_request_set_chunked_cb (struct evhttp_request *, void(*cb)(struct evhttp_request *, void *))方法,但找不到任何关于如何使用的示例。

例如,如何将参数传递给回调?参数似乎是传递给请求处理程序的相同参数,这不是我想要的,因为我想创建一个保存文件描述符和我发送的文件偏移量的对象。

感谢所有帮助。

提前致谢 斯

2 个答案:

答案 0 :(得分:0)

libevent v2 documentation并没有说它是异步的,但确实说它会关闭你的代码没有考虑的文件描述符。

我相信你需要在你的循环中移动int fd = open("filename", O_RDONLY);

您还可以通过从头开始构建字符串缓冲区来测试文件代码之外的块处理。

除此之外,(和最后一行fclose(fp);你的例子看起来是正确的

答案 1 :(得分:0)

尼斯的好朋友。感谢那。我只是意识到我想要进行分块传输的唯一原因是避免缓冲区读取。但是由于evbuffer_add_file已经使用了sendfile(如果它找到了),这不是一个真正的问题。

所以我完全删除了循环并尝试了。但内容仍未发送。但至少这次我没有错误的文件描述符错误(你是对的 - 这是由于文件被关闭 - 文件句柄的检查证实了这一点!)。