diff --git a/lib/camo/image.ex b/lib/camo/image.ex index 252b49ec..5f1bf5a7 100644 --- a/lib/camo/image.ex +++ b/lib/camo/image.ex @@ -2,7 +2,7 @@ defmodule Camo.Image do def image_url(input) do %{host: host} = URI.parse(input) - if !host or String.ends_with?(host, cdn_host()) do + if !host or String.ends_with?(host, cdn_host()) or is_nil(camo_key()) do input else camo_digest = :crypto.hmac(:sha, camo_key(), input) |> Base.encode16(case: :lower) diff --git a/lib/philomena_web/plugs/scraper_plug.ex b/lib/philomena_web/plugs/scraper_plug.ex index 7ec60ea4..1c329eeb 100644 --- a/lib/philomena_web/plugs/scraper_plug.ex +++ b/lib/philomena_web/plugs/scraper_plug.ex @@ -1,4 +1,6 @@ defmodule PhilomenaWeb.ScraperPlug do + @filename_regex ~r/filename="([^"]+)"/ + def init(opts) do opts end @@ -14,25 +16,30 @@ defmodule PhilomenaWeb.ScraperPlug do %{"scraper_cache" => url} when not is_nil(url) -> url |> Philomena.Http.get() - |> maybe_fixup_params(opts, conn) + |> maybe_fixup_params(url, opts, conn) _ -> conn end end - defp maybe_fixup_params({:ok, %Tesla.Env{body: body, status: 200}}, opts, conn) do + defp maybe_fixup_params( + {:ok, %Tesla.Env{body: body, status: 200, headers: headers}}, + url, + opts, + conn + ) do params_name = Keyword.get(opts, :params_name, "image") params_key = Keyword.get(opts, :params_key, "image") + name = extract_filename(url, headers) file = Briefly.create!() - now = DateTime.utc_now() |> DateTime.to_unix(:microsecond) File.write!(file, body) fake_upload = %Plug.Upload{ path: file, content_type: "application/octet-stream", - filename: "scraper-#{now}" + filename: name } updated_form = Map.put(conn.params[params_name], params_key, fake_upload) @@ -42,5 +49,16 @@ defmodule PhilomenaWeb.ScraperPlug do %Plug.Conn{conn | params: updated_params} end - defp maybe_fixup_params(_response, _opts, conn), do: conn + defp maybe_fixup_params(_response, _url, _opts, conn), do: conn + + defp extract_filename(url, resp_headers) do + {_, header} = + Enum.find(resp_headers, {nil, "filename=\"#{Path.basename(url)}\""}, fn {key, value} -> + key == "content-disposition" and Regex.match?(@filename_regex, value) + end) + + [name] = Regex.run(@filename_regex, header, capture: :all_but_first) + + String.slice(name, 0, 127) + end end