ElixirからCowboy 1.0を使ってみる Part 2

# はじめに
ElixirにてCowboyを直接動かすための記事となります。
[前回](http://qiita.com/hayabusa333/items/17be5e95510141f52c47)の記事では、cowboyでplain textを表示しました。
cowboy にて plain textを表示しても。。。っということもありますので、今回はHTMLを表示します。

[サンプルコードはこちらになります](https://github.com/hayabusa333/elixir_cowboy_example/tree/static_html_cowboy)

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

|  | Version |
|:-----------|--------:|
| Elixir | 1.3.2 |
| Erlang | 19.2 |
| Cowboy | 1.0.4 |

# HTMLを表示してみる

HTMLを表示するだけならば、Handlerにて `content-type`を`text/html`に変更し、`body`に htmlタグをつけてレスポンスを返すだけで実現可能です。

``` elixir:lib/elixir_cowboy_example/handler.ex
defmodule ElixirCowboyExample.Handler do
  def init({:tcp, :http}, req, opts) do
    {:ok, req, opts}
  end

  def handle(req, state) do
    {method, req} = :cowboy_req.method(req)
    {:ok, req} = html_example(method, req)
    {:ok, req, state}
  end

  def html_example("GET", req) do
    headers = [{"content-type", "text/html"}]
    body = """
      <html>
        <head>
          <meta charset=\"utf-8\">
                <title>Cowboy Hello!</title>
        </head>
        <body>
          <h1>Cowboy Hello!!</h1>
        </body>
      </html>
    """
    {:ok, resp} = :cowboy_req.reply(200, headers, body, req)
  end

  def terminate(_reason, _req, _state) do
    :ok
  end
end
```

# 記載したコードの実行
コードの記述が完了しましたので、それでは実行していきましょう。
いつも通り `iex -S mix` にて cowboy を実行していきます。
起動後に、ブラウザからアクセスを実施しましょう。
`http://localhost:4000`にブラウザからアクセスすると、`Hello Cowboy!`が今度はHTMLタグにて修飾されてでてくるはずです。

<img width="1176" alt="スクリーンショット 2017-01-07 9.08.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/3014/bd95621d-4ddd-d3bf-9378-826a8f53ed6b.png">

# ファイルからHTMLの内容を取得
さてさて、HTMLの内容を表示しましたが、HTMLの内容をすべてElixirのコードの中に記載するのはよくはないですよね。
ですので、 index.html ファイルを作成し、その内容を表示するように修正していきます。
また今まで使用していたURLでは、今まで通りの画面にアクセスできるように `route`の追加も行っていきます。

```html:priv/static/html/index.html
<html>
  <head>
    <meta charset=\"utf-8\">
      <title>Cowboy Hello!</title>
  </head>
  <body>
    <h1>Cowboy Hello!!</h1>
    <h2>file load test<h2>
  </body>
</html>
```

下記のコードにて、新たな`route`の追加を行います。

```elixir:lib/elixir_cowboy_example.ex
defmodule ElixirCowboyExample do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(__MODULE__, [], function: :run)
    ]

    opts = [strategy: :one_for_one, name: ElixirCowboyExample.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def run do
    routes = [
      # http://localhost:4000 にアクセスしたら今までのページを
      # http://localhost:4000/xxx にアクセスしたらindex.htmlを表示するように route を追加
      {"/", ElixirCowboyExample.Handler, []},
      {"/:html", ElixirCowboyExample.Handler, []}
    ]

    dispatch = :cowboy_router.compile([{:_, routes}])

    opts = [port: 4000]
    env = [dispatch: dispatch]

    {:ok, _pid} = :cowboy.start_http(:http, 100, opts, [env: env])
  end
end
```

下記のコードでは、http通信時の内容によって表示するHTMLの内容の変更を行っています。

```elixir:lib/elixir_cowboy_example/handler.ex
defmodule ElixirCowboyExample.Handler do
  def init({:tcp, :http}, req, opts) do
    {:ok, req, opts}
  end

  def handle(req, state) do
    # http通信時の method を取得
    {method, req} = :cowboy_req.method(req)
    # http//localhost:4000/xxx の xxx を取得
    {param, req} = :cowboy_req.binding(:html, req)
    {:ok, req} = html_example(method, param, req)
    {:ok, req, state}
  end

  # :undefined つまりは、 /xxx が存在していない場合の処理
  def html_example("GET", :undefined, req) do
    headers = [{"content-type", "text/html"}]
    body = """
      <html>
        <head>
          <meta charset=\"utf-8\">
                <title>Cowboy Hello!</title>
        </head>
        <body>
          <h1>Cowboy Hello!!</h1>
        </body>
      </html>
    """
    {:ok, resp} = :cowboy_req.reply(200, headers, body, req)
  end

  # priv/static/html/index.html を取得し、その内容をレスポンス
  def html_example("GET", param, req) do
    headers = [{"content-type", "text/html"}]
    {:ok, file} = File.read "priv/static/html/index.html"
    body = file
    {:ok, resp} = :cowboy_req.reply(200, headers, body, req)
  end

  def terminate(_reason, _req, _state) do
    :ok
  end
end
```

# 記載したコードの実行
さて、再びコードの記述が完了しましたので実行していきます。
起動後に、ブラウザからアクセスを実施しますが、今回は`http://localhost:4000/hoge`にブラウザからアクセスすると、下記の画像のように表示されるはずです。

<img width="1176" alt="スクリーンショット 2017-01-07 11.39.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/3014/ddb38f50-c0b0-d46f-288d-02a1b44fc391.png">

また、 `http://localhost:4000` にアクセスすると、今まで通りの `Hello Cowboy!`のみの画面が出てくるはずです。

# 最後に
いかがだったでしょうか？
今回はstaticなhtmlファイルを表示してみました。エラー時の処理などはもう少し必要かもしれませんが、htmlを表示するだけならば、これだけでも使おうと思えば使えます。
次回も楽しみにしていただければ幸いです。

# 参考サイト
[Cowboy User Guide](https://ninenines.eu/docs/en/cowboy/1.0/guide/)
[Cowboy Tutorial Part 2: Creating Flat File Blog](http://www.elixirdose.com/post/elixirdose_flatfileblog)