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