how to download file by erlang cowboy?

2019-08-10 12:50发布

问题:

I want to download file from the browser and I try to achieve by cowboy, however I failed and the browser show me that "Repeat header received from the server.". I have no idea, everyone please help me. this is my code of handler: `

%% @doc GET echo handler.
-module(toppage_handler2).

-export([init/3]).
-export([handle/2]).
-export([terminate/3]).

init(_Transport, Req, []) ->
    {ok, Req, undefined}.

handle(Req, State) ->
    {Method, Req2} = cowboy_req:method(Req),
    {Echo, Req3} = cowboy_req:qs_val(<<"echo">>, Req2),
    {ok, Req4} = echo(Method, <<Echo/binary, " I am there ">>, Req3),
    {ok, Req4, State}.

echo(<<"GET">>, undefined, Req) ->
    cowboy_req:reply(400, [], <<"Missing echo parameter.">>, Req);

%% the main part of download the file is here
%% I just want to download the file README.md
echo(<<"GET">>, Echo, Req) ->
    F = fun (Socket, Transport) ->
    Transport:sendfile(Socket, "priv/README.md")
    end,
    Req2 = cowboy_req:set_resp_body_fun(1024, F, Req),
     Req3 = cowboy_req:set_resp_header(<<"Content-Disposition">>, "GET", Req2),
    Req4 = cowboy_req:set_resp_header(<<"attachment;filename=\"README.md\"">>, "GET", Req3),
     Req5 = cowboy_req:set_resp_header(<<"Content-Length">>, "GET",  Req4),
     Req6 = cowboy_req:set_resp_header(<<"1024">>, "GET",  Req5),
    cowboy_req:reply(200, [
        {<<"content-type">>, <<"application/octet-stream">>}
    ], "", Req6);

echo(_, _, Req) ->
    %% Method not allowed.
    cowboy_req:reply(405, Req).

terminate(_Reason, _Req, _State) ->
    ok.`

回答1:

Cowboy has a built in handler for serving static files. It is documented here:

http://ninenines.eu/docs/en/cowboy/HEAD/guide/static_handlers/

and there is example on github:

https://github.com/ninenines/cowboy/tree/master/examples/static_world/src

This way, you don't have to set headers manually, which should prevent the error.



回答2:

This is obviously way too late for OP but maybe it will help somebody finding this from Google.

Your problem is that you are overriding the response body function you set using set_resp_body_fun with your cowboy_req:reply/4 function. All you need to do is replace that line with a cowboy_req:reply/3 call which does not explicitly set the body

cowboy_req:reply(200, [
    {<<"content-type">>, <<"application/octet-stream">>}
], Req6);

and you should find that it works.



标签: erlang cowboy