Is it possible to disable Live Reload for certain routes?
A section of my Phoenix application serves files on a particular route by streaming them in chunks from an Elixir Stream sourced from a MongoDB document collection. Users upload zip files containing a small web application (HTML, Javascript, CSS, Images, etc…), and these are unzipped and stored in MongoDB. This works great in release mode AND in dev mode for non-html files. But in dev mode, if the content-type is “text/html”, Live Reload attempts to inject code into it and I get an error:
** (exit) an exception was raised:
** (ArgumentError) argument error
:erlang.iolist_to_binary(nil)
(phoenix_live_reload) lib/phoenix_live_reload/live_reloader.ex:95: anonymous fn/2 in Phoenix.LiveReloader.before_send_inject_reloader/2
(elixir) lib/enum.ex:1811: Enum."-reduce/3-lists^foldl/2-0-"/3
(plug) lib/plug/conn.ex:1133: Plug.Conn.run_before_send/2
(plug) lib/plug/conn.ex:452: Plug.Conn.send_chunked/2
The stack trace in the browser shows the error to occur only in HTML files, and fails in the call to IO.iodata_to_binary/1
defp before_send_inject_reloader(conn, endpoint) do
register_before_send(conn, fn conn ->
if html?(conn) do
resp_body = IO.iodata_to_binary(conn.resp_body)
if has_body?(resp_body) and :code.is_loaded(endpoint) do
[page | rest] = String.split(resp_body, "</body>")
body = page <> reload_assets_tag(conn) <> Enum.join(["</body>" | rest], "")
put_in conn.resp_body, body
Here’s the code I’m using to send the files. The call to TagRepo.Stream.stream/3 returns a tuple containing an Elixir Stream created with Stream.resource/3 and the content-type of the file.
defmodule ApiServicesWeb.Download do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
case TagRepo.Stream.stream(conn.params["username"], conn.params["webapp_name"], Enum.join(conn.params["path"], "/")) do
:not_found ->
conn = conn
|> send_resp(404, "file not found")
|> halt()
{stream, content_type} ->
conn = conn
|> put_resp_content_type(content_type)
|> send_chunked(200)
Enum.into(stream, conn)
end
end
end
My immediate thought was to turn off the Live Reload feature completely for this application. But, of course, it’s really handy for development mode, and I want it to work. Is there a way to prevent it from injecting the live reload code for HTML files? Or only for files on a certain route? Or a certain pipeline?