はじめに
ElixirにてCowboyを直接動かすための記事となります。
前回の記事では、リクエストに含まれているcookie情報の確認を行う方法を実装しました。
今回はCowboyのドキュメントに記載されている、 Sending files のメソッドについて記載していきます。
バージョン
使用した言語やライブラリのバージョンは下記となります。
cowboy 1.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 1.0.4 |
cowboy 2.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 2.0.0-pre4 |
ファイルの送信
今回はファイルの送信処理となります。
以前の記事から何度も行ってはありますが、下記のsendfile
メソッドを使用するとディスクからファイルを読み込んでからおくるのではなく、直接ファイルを送信してくれるようです。
cowboy 1.0の場合
lib/elixir_cowboy_example.ex
routes = [
{"/", ElixirCowboyExample.Handler, []},
# Add it
{"/sendfile", ElixirCowboyExample.SendFileHandler, []},
{"/cookie", ElixirCowboyExample.CookieHandler, []},
{"/upload", ElixirCowboyExample.UploadHandler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []},
{"/priv/static/image/[...]", :cowboy_static, {:priv_dir, :elixir_cowboy_example, "static/image"}}
]
lib/elixir_cowboy_example/send_file_handler.ex
defmodule ElixirCowboyExample.SendFileHandler do
def init({:tcp, :http}, req, opts) do
{:ok, req, opts}
end
def handle(req, state) do
# fileの指定
path = "priv/static/image/button.png"
# fileのサイズを取得
%File.Stat{size: file_size} = File.stat!(path)
# bodyにて送る際のメソッドを指定
body_fun = fn(socket, transport) ->
transport.sendfile(socket, path)
end
headers = [ {"content-type", "image/png"} ]
# fileの送信
{:ok, req} = :cowboy_req.reply(200, headers, :cowboy_req.set_resp_body_fun(file_size, body_fun, req))
{:ok, req, state}
end
def terminate(_reason, _req, _state) do
:ok
end
end
cowboy 2.0の場合
lib/elixir_cowboy_example.ex
routes = [
{"/", ElixirCowboyExample.Handler, []},
# Add it
{"/sendfile", ElixirCowboyExample.SendFileHandler, []},
{"/cookie", ElixirCowboyExample.CookieHandler, []},
{"/upload", ElixirCowboyExample.UploadHandler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []},
{"/priv/static/image/[...]", :cowboy_static, {:priv_dir, :elixir_cowboy_example, "static/image"}}
]
lib/elixir_cowboy_example/send_file_handler.ex
defmodule ElixirCowboyExample.SendFileHandler do
def init(req, opts) do
# fileを指定
path = "priv/static/image/button.png"
# fileサイズを取得
%File.Stat{size: file_size} = File.stat!(path)
header = %{"content-type" => "image/png"}
# sendfileメソッドを使用してファイル送信するように指定を実施
req = :cowboy_req.reply(200, header ,
{:sendfile, 0, file_size, path}, req)
{:ok, req, opts}
end
end
記載したコードの実行
コードの記述が完了しましたので、それでは実行していきましょう。
いつも通り iex -S mix
にて cowboy を実行していき、http://localhost:4000/sendfile
にアクセスしてみましょう。
下記のように以前に作成したbutton.pngが表示されます
最後に
今回はsendfileメソッドを使用してのファイルの送信を実施しました。
これは普通に送るのと、sendfileメソッドを使用して送る場合の違いなどはあるのか気になりますね。
それではまた次回