LoginSignup
0
0

More than 5 years have passed since last update.

ElixirからCowboy 1.0と2.0を使ってみる Part 10

Last updated at Posted at 2017-01-15

はじめに

ElixirにてCowboyを直接動かすための記事となります。
前回の記事では、リクエストに含まれているcookie情報の確認を行う方法を実装しました。
今回はCowboyのドキュメントに記載されている、 Sending files のメソッドについて記載していきます。

Cowboy1.0のサンプルコードはこちらになります

Cowboy2.0のサンプルコードはこちらになります

バージョン

使用した言語やライブラリのバージョンは下記となります。

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が表示されます

スクリーンショット 2017-01-15 15.10.13.png

最後に

今回はsendfileメソッドを使用してのファイルの送信を実施しました。
これは普通に送るのと、sendfileメソッドを使用して送る場合の違いなどはあるのか気になりますね。
それではまた次回

参考サイト

Cowboy User Guide
Cowboy User Guide

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0