Closed Rashidwi closed 1 month ago
For other newbies struggling with this or similar problems, my solution was to understand the nature of plugs and the sequence of network operations when a browser loads a web page. When you are creating the server, all the needs of the browser need to be serviced.
There is documentation, but it's very hard to piece together what is relevant, what seems to be missing is an overview of the process. With so many different packages involved: Bandit, Plug, ThousandIsland, Router not to mention Websocket, it's hard to know where to start reading. Two articles were very helpful here:
Jean-Hadrien Chabran Ilija Eftimov
My solution to the problem was an asset plug. Requests are checked for the file suffix and the correct mime type is set, as is the location of the asset (which means you don't need to have hard coded paths in the html or css)
defmodule AssetPlug do
import Plug.Conn
@behaviour Plug
def init(opts) do
opts
end
def get_mime(conn) do
mimes = %{
".css" => %{mimetype: "text/css", path: "assets/css"},
".png" => %{mimetype: "image/png", path: "assets/graphics"},
".ico" => %{mimetype: "image/vnd.microsoft.icon", path: "assets/graphics"},
}
conn.path_info
|> List.last
|> Path.extname
|> (&(Map.get(mimes, &1))).()
end
def call(conn, _opts) when conn.path_info != [] do
case get_mime(conn) do
nil ->
conn
|> send_resp(404, "mime type not found #{conn.request_path}")
|> halt()
%{mimetype: mime, path: path} ->
f = Path.join(path, conn.request_path)
case File.read(f) do
{ :ok, data} ->
conn
|> put_resp_content_type(mime)
|> send_resp(200,data)
|> halt()
{ :error, reason} ->
conn
|> send_resp(404, inspect(reason))
|> halt()
end
end
end
def call(conn, _opts) do
conn
end
I'm sure there are many improvements possible, It's not tuned for efficiency, I've simply got something working.
Thanks for the issue @Rashidwi! Glad you got it sorted (and left a helpful breadcrumb for future viewers! Thank you!) In the future, user issues such as this are better suited to Elixir forum or slack; it's a more interactive and 'help' based avenue rather than here, which we try to keep focused on actual issues with the library.
<link href="my_page.css" rel="stylesheet" type="text/css">
when served from bandit produces the following console:
When the same html is captured with curl and presented to a browser the css is correctly handled.
I've searched (and searched...) but I can find nothing about handling css links. I believe the problem is in my plug specifying text/html which is overriding the text/css in the code.
Could some kind soul please point me in the right direction...