Skip to content

Commit 72fa0e1

Browse files
committed
Fix raise_on_missing_only raising on non-matching paths with colons
When `Plug.Static` is mounted at `/` with `raise_on_missing_only: true`, application routes containing colons (e.g. `/app/resource:id`) would i raise `InvalidPathError` because `invalid_path?` ran before the file existence check. This fix splits the catch-all status branch into explicit `:allowed` and `:raise` clauses so that `:raise` only fires when a valid path resolves to a real file on disk.
1 parent 200d432 commit 72fa0e1

2 files changed

Lines changed: 21 additions & 10 deletions

File tree

lib/plug/static.ex

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ defmodule Plug.Static do
204204
:forbidden ->
205205
conn
206206

207-
status ->
207+
:allowed ->
208208
segments = Enum.map(segments, &URI.decode/1)
209209

210210
if invalid_path?(segments) do
@@ -215,17 +215,19 @@ defmodule Plug.Static do
215215
range = get_req_header(conn, "range")
216216

217217
case file_encoding(conn, path, range, encodings) do
218-
:error ->
219-
conn
218+
:error -> conn
219+
triplet -> serve_static(triplet, conn, segments, range, options)
220+
end
220221

221-
triplet ->
222-
if status == :raise do
223-
raise InvalidPathError,
224-
"static file exists but is not in the :only list: #{Enum.join(segments, "/")}. " <>
225-
"Add it to the :only list or use :only_matching for prefix matching"
226-
end
222+
:raise ->
223+
segments = Enum.map(segments, &URI.decode/1)
227224

228-
serve_static(triplet, conn, segments, range, options)
225+
if not invalid_path?(segments) and regular_file_info(path(from, segments)) do
226+
raise InvalidPathError,
227+
"static file exists but is not in the :only list: #{Enum.join(segments, "/")}. " <>
228+
"Add it to the :only list or use :only_matching for prefix matching"
229+
else
230+
conn
229231
end
230232
end
231233
end

test/plug/static_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,4 +895,13 @@ defmodule Plug.StaticTest do
895895

896896
assert conn.status == 200
897897
end
898+
899+
test "raise_on_missing_only does not raise on non-matching paths with colons" do
900+
conn =
901+
conn(:get, "/public/resource:identifier")
902+
|> call(only: ["assets"], raise_on_missing_only: true)
903+
904+
assert conn.status == 404
905+
assert conn.resp_body == "Passthrough"
906+
end
898907
end

0 commit comments

Comments
 (0)