0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Add sendfile support to cowboy_req:stream_body

It is now possible to stream one or more sendfile tuples.
A simple example of what can now be done would be for
example to build a tar file on the fly using the sendfile
syscall for sending the files, or to support Range requests
with more than one range with the sendfile syscall.

When using cowboy_compress_h unfortunately we have to read
the file in order to send it. More options will be added
at a later time to make sure users don't read too much
into memory. This is a new feature however so existing
code is not affected.

Also rework cowboy_http's data sending to be flatter.
This commit is contained in:
Loïc Hoguin 2018-11-09 17:42:37 +01:00
parent 29043aa7b4
commit d7b7580b39
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
12 changed files with 219 additions and 100 deletions

View file

@ -885,21 +885,44 @@ stream_reply3(Config) ->
{500, _, _} = do_get("/resp/stream_reply3/error", Config),
ok.
stream_body_multiple(Config) ->
doc("Streamed body via multiple calls."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body/multiple", Config),
ok.
stream_body_fin0(Config) ->
doc("Streamed body with last chunk of size 0."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body/fin0", Config),
ok.
stream_body_multiple(Config) ->
doc("Streamed body via multiple calls."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body/multiple", Config),
ok.
stream_body_nofin(Config) ->
doc("Unfinished streamed body."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body/nofin", Config),
ok.
stream_body_sendfile(Config) ->
doc("Streamed body via multiple calls, including sendfile calls."),
{ok, AppFile} = file:read_file(code:where_is_file("cowboy.app")),
ExpectedBody = iolist_to_binary([
<<"Hello ">>,
AppFile,
<<" interspersed ">>,
AppFile,
<<" world!">>
]),
{200, _, ExpectedBody} = do_get("/resp/stream_body/sendfile", Config),
ok.
stream_body_sendfile_fin(Config) ->
doc("Streamed body via multiple calls, including a sendfile final call."),
{ok, AppFile} = file:read_file(code:where_is_file("cowboy.app")),
ExpectedBody = iolist_to_binary([
<<"Hello! ">>,
AppFile
]),
{200, _, ExpectedBody} = do_get("/resp/stream_body/sendfile_fin", Config),
ok.
stream_body_content_length_multiple(Config) ->
doc("Streamed body via multiple calls."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body_content_length/multiple", Config),