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

# はじめに
ElixirにてCowboyを直接動かすための記事となります。
[前回](http://qiita.com/hayabusa333/items/f661924467d29068f363)の記事では、PresetでResponseを少しずつ設定する方法に関して実装しました。
今回の記事ではブラウザ情報を判定してみます。

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

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

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

## 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 |

# Header情報からブラウザ情報を取得

今回はブラウザ情報の判定を実施します。
ブラウザ情報自体は`User-Agent`に設定されていますので、`User-Agent`を取得してから、どのブラウザであるかを確認していきます。

## cowboy 1.0の場合

``` elixir:lib/elixir_cowboy_example.ex
    routes = [
      {"/", ElixirCowboyExample.Handler, []},
      # Add it.
      {"/browser", ElixirCowboyExample.BrowserCheckHandler, []},
      {"/preset", ElixirCowboyExample.PresetResponseHandler, []},
      {"/stream", ElixirCowboyExample.StreamHandler, []},
      {"/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"}}
    ]
```

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

  def handle(req, state) do

    # Headerからuser-agentの情報を抜き出す
    {user_agent_val, req} = :cowboy_req.header(<<"user-agent">>, req)

    headers = [{"content-type", "text/html"}]

    # user-agentの情報から、どのブラウザであるかをチェックし
    # bodyにHTMLの値を設定する
    # 今回はchromeとsafariのみ対応
    body = cond do
      String.contains?(user_agent_val, "Chrome") 
        -> "<html><head>Chrome Hello world!</head>"
      String.contains?(user_agent_val, "Safari") 
        -> "<html><head>Safari Hello world!</head>"
      true 
        -> "<html><head>Hello world!</head>"
    end

    {:ok, resp} = :cowboy_req.reply(200, headers, body, req)
    {:ok, req, state}
  end

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

## cowboy 2.0の場合

``` elixir:lib/elixir_cowboy_example.ex
    routes = [
      {"/", ElixirCowboyExample.Handler, []},
      # Add it.
      {"/browser", ElixirCowboyExample.BrowserCheckHandler, []},
      {"/preset", ElixirCowboyExample.PresetResponseHandler, []},
      {"/stream", ElixirCowboyExample.StreamHandler, []},
      {"/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"}}
    ]
```

``` elixir:lib/elixir_cowboy_example/browser_check_handler.ex
defmodule ElixirCowboyExample.BrowserCheckHandler do
  def init(req, opts) do

    # Headerからuser-agentの情報を抜き出す
    user_agent_val = :cowboy_req.header(<<"user-agent">>, req)

    headers = %{"content-type" => "text/html"}

    # user-agentの情報から、どのブラウザであるかをチェックし
    # bodyにHTMLの値を設定する
    # 今回はchromeとsafariのみ対応
    body = cond do
      String.contains?(user_agent_val, "Chrome") 
        -> "<html><head>Chrome Hello world!</head>"
      String.contains?(user_agent_val, "Safari") 
        -> "<html><head>Safari Hello world!</head>"
      true 
        -> "<html><head>Hello world!</head>"
    end

    {:ok, resp} = :cowboy_req.reply(200, headers, body, req)

    {:ok, req, opts}
  end
end
```


# 記載したコードの実行
コードの記述が完了しましたので、それでは実行していきましょう。
いつも通り `iex -S mix` にて cowboy を実行していき、`http://localhost:4000/browser`にアクセスしてみましょう。
ChromeとSafariで別のHTML内容が出ていることが確認できます。

Chromeの場合
<img width="1176" alt="スクリーンショット 2017-01-18 14.39.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/3014/49158fc1-c310-ecbe-2055-c30ffb52a94b.png">

Safariの場合
<img width="1066" alt="スクリーンショット 2017-01-18 14.39.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/3014/991f5b80-95b0-1ce8-50da-84a9f62b8fe9.png">

# 最後に

今回はHeader情報からブラウザを判定してみました。
判定方法はElixirで書かないといけないので少し考えないといけないかもしれませんね。
それではまた次回

# 参考サイト
[Cowboy User Guide](https://ninenines.eu/docs/en/cowboy/1.0/guide/)
[Cowboy User Guide](https://ninenines.eu/docs/en/cowboy/2.0/guide/)