Чанкованные ответы в libevent2 - PullRequest
0 голосов
/ 18 марта 2010

Я пытаюсь сделать частичный ответ (больших файлов) в libevent следующим образом: *

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 *)), который я мог бы использовать, но не смог найти примеров того, как его использовать.

Например, как я могу передать аргумент обратному вызову? Кажется, что аргумент - это тот же аргумент, который был передан в обработчик запроса, но это не то, что мне нужно, потому что я хочу создать объект, содержащий дескриптор файла и смещение файла, которое я отправляю.

Ценю всю помощь.

Заранее спасибо Sri

Ответы [ 2 ]

0 голосов
/ 24 марта 2010

Хороший Хороший приятель. Спасибо за это. Я только что понял, что единственная причина, по которой я хотел разделить передачи на части, состояла в том, чтобы избежать чтения из буфера. Но поскольку evbuffer_add_file уже использует sendfile (если он его находит), на самом деле это не проблема.

Итак, я полностью удалил цикл и попытался. Но содержимое все еще не отправляется. но, по крайней мере, на этот раз у меня нет ошибки неверного дескриптора файла (вы правы - это было из-за закрытия файла - проверка дескрипторов файла подтвердила это!).

0 голосов
/ 22 марта 2010

Документация libevent v2 не говорит, что это асинхронно, но говорит, что закрывает дескриптор файла, который не учитывается вашим кодом.

Я полагаю, вам нужно переместиться int fd = open("filename", O_RDONLY); в вашу петлю.

вы также можете проверить обработку чанков вне кода вашего файла, просто создав буфер строк с нуля.

кроме этого, (и последняя строка, которая должна быть fclose(fp);, ваш пример выглядит правильно

...