5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Elixir]Plugを自作してみる[Phoenix]

Last updated at Posted at 2024-09-14

今回の目標

  • Plugを作る
    • user-agentで判定してiPadであればiPadのベージにリダイレクト
    • 上記以外は通常のアクセスできる

特に意味はないがPlugの勉強の題材にしたまでです
昔のガラケー時代は、着メロは機種依存するからこんな感じで判定してましたね

プロジェクト作成

$ mix phx.new plug_experiment --no-ecto
$ cd plug_experiment

他の端末でもアクセス可能にする

config/dev.exs
# 〜省略〜
- http: [ip: {127, 0, 0, 1}, port: 4000],
+ http: [ip: {0, 0, 0, 0}, port: 4000],
  check_origin: false,
  code_reloader: true,
  debug_errors: true,
  # 〜省略〜

Plug作成

defmodule PlugExperimentWeb.Plugs.Ymn do
  import Plug.Conn
  alias Phoenix.Controller

  def init(opts \\ []) do
    IO.inspect("------------ #{__MODULE__}.init ------------")

    opts
    |> IO.inspect()
  end

  def call(conn, _opts) do
    IO.inspect("------------ #{__MODULE__}.call ------------")

    os =
      conn.req_headers
      |> Enum.filter(fn {key, _val} -> key == "user-agent" end)
      |> List.first()
      |> elem(1)
      |> IO.inspect()
      |> get_os_name()
      |> IO.inspect()

    conn
    |> redirect(os)
  end

  defp redirect(conn, "iPadOS") do
    IO.inspect("redirect https://www.apple.com/jp/ipad/")

    conn
    |> Controller.redirect(external: "https://www.apple.com/jp/ipad/")
    |> halt()
  end

  defp redirect(conn, _), do: conn

  defp get_os_name(agent) do
    cond do
      String.match?(agent, ~r/iPad/) -> "iPadOS"
      String.match?(agent, ~r/X11/) -> "Linux"
      String.match?(agent, ~r/Android/) -> "Android"
      true -> "unknown"
    end
  end
end

lib/plug_experiment_web/router.ex
defmodule PlugExperimentWeb.Router do
  use PlugExperimentWeb, :router
  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {PlugExperimentWeb.Layouts, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
+   plug PlugExperimentWeb.Plugs.Ymn
  end
# 〜省略〜

実行

$ mix phx.server

http://サーバーのIP:4000にアクセス

サーバーのログ

iPad
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.init ------------"
[]
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.call ------------"
"Mozilla/5.0 (iPad; CPU OS 17_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/128.0.6613.98 Mobile/15E148 Safari/604.1"
"iPadOS"
"redirect https://www.apple.com/jp/ipad/"
Android
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.init ------------"
[]
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.call ------------"
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36"
"Android"
Ubuntu
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.init ------------"
[]
"------------ Elixir.PlugExperimentWeb.Plugs.Ymn.call ------------"
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
"Linux"

ソース(github)

5
2
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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?