How to configure the Plug.Static without Phoenix

后端 未结 3 1713
小蘑菇
小蘑菇 2021-02-05 21:22

I am trying to figure out how to configure Plug.Static without any other framework (Phoenix, Sugar, etc); just Cowboy, Plug and Elixir. I just don\'t know how t

相关标签:
3条回答
  • 2021-02-05 21:24

    This is the answer I was looking for.

    In the application start method use the Plug.Router with Cowboy:

    defmodule HttpServer.Application do
      require Logger
      use Application
    
      def start(_type, _args) do
        children = [
          {Plug.Adapters.Cowboy2, scheme: :http, plug: HttpServer.Router, options: [port: 4002]}
        ]
    
        opts = [strategy: :one_for_one, name: HttpServer.Supervisor]
    
        Supervisor.start_link(children, opts)
      end
    end
    

    The router module looks like this:

    defmodule HttpServer.Router do
      use Plug.Router
    
      plug(Plug.Logger)
      plug(:redirect_index)
      plug(:match)
      plug(:dispatch)
    
      forward("/static", to: HttpServer.StaticResources)
    
      get "/sse" do
        # some other stuff...
        conn
      end
    
      match _ do
        send_resp(conn, 404, "not found")
      end
    
      def redirect_index(%Plug.Conn{path_info: path} = conn, _opts) do
        case path do
          [] ->
            %{conn | path_info: ["static", "index.html"]}
    
          ["favicon.ico"] ->
            %{conn | path_info: ["static", "favicon.ico"]}
    
          _ ->
            conn
        end
      end
    end
    

    Here requests to "/static" are forwarded to the HttpServer.StaticResources module, but first, the request path is modified for "/" and "/favicon.ico" with plug(:redirect_index). All static files (*.html, *.ico, *.css, *.js etc.) are placed in the default location (project_dir/priv/static).

    Finally, the StaticResource module:

    defmodule HttpServer.StaticResources do
      use Plug.Builder
    
      plug(
        Plug.Static,
        at: "/",
        from: :http_server
      )
    
      plug(:not_found)
    
      def not_found(conn, _) do
        send_resp(conn, 404, "static resource not found")
      end
    end
    
    0 讨论(0)
  • 2021-02-05 21:28

    Everything that José Valim said. And here's a most simple example to add to it:

    defmodule Server do
      use Plug.Builder
      plug Plug.Logger
      plug Plug.Static, at: "/", from: "/path/to/static"
    end
    

    This will serve all static files in "/path/to/static" at the "/" endpoint.

    Have a look at the docs for more options and a deeper explanation.

    0 讨论(0)
  • 2021-02-05 21:40

    Take a look at Plug.Router docs for how :match and :dispatch works. :match will try to find a matching route and :dispatch is going to invoke it. This means Plug.Static in your setup will only be invoked if you have a matching route in your router, which doesn't make sense. You want plug Plug.Static before everything. Remember plugs are just functions that are invoked in the order they are declared.

    Other than that, your Plug.Static setup seems ok. Your current configuration will serve assets at "/pub", meaning "/pub/index.html" will look for "priv/static/index.html" in your app. More info here: http://hexdocs.pm/plug/Plug.Static.html

    0 讨论(0)
提交回复
热议问题