Skip to content

Commit

Permalink
Enable definging routes for custom http methods. Closes #1236
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismccord committed Oct 4, 2015
1 parent 7940c51 commit 6490f2c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
32 changes: 25 additions & 7 deletions lib/phoenix/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ defmodule Phoenix.Router do
"""
def call(conn, opts), do: do_call(conn, opts)

defp match(conn, []) do
match(conn, conn.method, Enum.map(conn.path_info, &URI.decode/1), conn.host)
defp match_route(conn, []) do
match_route(conn, conn.method, Enum.map(conn.path_info, &URI.decode/1), conn.host)
end

defp dispatch(conn, []) do
Expand All @@ -271,7 +271,7 @@ defmodule Phoenix.Router do
Helpers.define(env, routes_with_exprs)
matches = Enum.map(routes_with_exprs, &build_match/1)

plugs = [{:dispatch, [], true}, {:match, [], true}]
plugs = [{:dispatch, [], true}, {:match_route, [], true}]
{conn, pipeline} = Plug.Builder.compile(env, plugs, [])

call =
Expand All @@ -287,7 +287,7 @@ defmodule Phoenix.Router do
# line: -1 is used here to avoid warnings if forwarding to root path
match_404 =
quote line: -1 do
defp match(conn, _method, _path_info, _host) do
defp match_route(conn, _method, _path_info, _host) do
raise NoRouteError, conn: conn, router: __MODULE__
end
end
Expand All @@ -310,19 +310,38 @@ defmodule Phoenix.Router do

defp build_match({_route, exprs}) do
quote do
defp match(var!(conn), unquote(exprs.verb_match), unquote(exprs.path),
defp match_route(var!(conn), unquote(exprs.verb_match), unquote(exprs.path),
unquote(exprs.host)) do
unquote(exprs.dispatch)
end
end
end

@doc """
Generates a route match based on an arbitrary HTTP method
Useful for defining routes not included in the builtin macros:
#{Enum.map_join(@http_methods, ", ", &"`#{&1}`")}
## Examples
match(:move, "/events/:id", EventController, :move)
"""
defmacro match(verb, path, plug, plug_opts, options \\ []) do
add_route(:match, verb, path, plug, plug_opts, options)
end

for verb <- @http_methods do
@doc """
Generates a route to handle a #{verb} request to the given path.
"""
defmacro unquote(verb)(path, plug, plug_opts, options \\ []) do
add_route(:match, unquote(verb), path, plug, plug_opts, options)
verb = unquote(verb)
quote bind_quoted: binding do
match(verb, path, plug, plug_opts, options)
end
end
end

Expand Down Expand Up @@ -625,5 +644,4 @@ defmodule Phoenix.Router do
unquote(add_route(:forward, :*, path, plug, plug_opts, router_opts))
end
end

end
9 changes: 9 additions & 0 deletions test/phoenix/router/routing_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Phoenix.Router.RoutingTest do
def trace(conn, _params), do: text(conn, "users trace")
def not_found(conn, _params), do: text(put_status(conn, :not_found), "not found")
def image(conn, _params), do: text(conn, conn.params["path"] || "show files")
def move(conn, _params), do: text(conn, "users move")
end

defmodule Router do
Expand All @@ -30,6 +31,7 @@ defmodule Phoenix.Router.RoutingTest do
trace "/trace", UserController, :trace
options "/options", UserController, :options
connect "/connect", UserController, :connect
match :move, "/move", UserController, :move

get "/users/:user_id/files/:id", UserController, :image
get "/*path", UserController, :not_found
Expand Down Expand Up @@ -132,4 +134,11 @@ defmodule Phoenix.Router.RoutingTest do
assert conn.params == %{"path" => ~w"foo bar baz"}
assert conn.resp_body == "not found"
end

test "match on arbitrary http methods" do
conn = call(Router, :move, "/move")
assert conn.method == "MOVE"
assert conn.status == 200
assert conn.resp_body == "users move"
end
end

0 comments on commit 6490f2c

Please sign in to comment.