Packages
livebook
0.2.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/controllers/session_controller.ex
defmodule LivebookWeb.SessionController do
use LivebookWeb, :controller
alias Livebook.{SessionSupervisor, Session}
def show_image(conn, %{"id" => id, "image" => image}) do
with true <- SessionSupervisor.session_exists?(id),
%{images_dir: images_dir} <- Session.get_summary(id),
path <- Path.join(images_dir, image),
true <- File.exists?(path) do
serve_static(conn, path)
else
_ ->
send_resp(conn, 404, "Not found")
end
end
defp serve_static(conn, path) do
case put_cache_header(conn, path) do
{:stale, conn} ->
filename = Path.basename(path)
content_type = MIME.from_path(filename)
conn
|> put_resp_header("content-type", content_type)
|> send_file(200, path)
{:fresh, conn} ->
send_resp(conn, 304, "")
end
end
defp put_cache_header(conn, path) do
etag = etag_for_path(path)
conn =
conn
|> put_resp_header("cache-control", "public")
|> put_resp_header("etag", etag)
if etag in get_req_header(conn, "if-none-match") do
{:fresh, conn}
else
{:stale, conn}
end
end
defp etag_for_path(path) do
%{size: size, mtime: mtime} = File.stat!(path)
hash = {size, mtime} |> :erlang.phash2() |> Integer.to_string(16)
<<?", hash::binary, ?">>
end
end