@@ -2,6 +2,7 @@ defmodule Bypass.Instance do
22 use GenServer , restart: :transient
33
44 import Bypass.Utils
5+ import Plug.Router.Utils , only: [ build_path_match: 1 ]
56
67 def start_link ( opts \\ [ ] ) do
78 GenServer . start_link ( __MODULE__ , [ opts ] )
@@ -139,6 +140,7 @@ defmodule Bypass.Instance do
139140 route ,
140141 new_route (
141142 fun ,
143+ path ,
142144 case expect do
143145 :expect -> :once_or_more
144146 :expect_once -> :once
@@ -285,18 +287,47 @@ defmodule Bypass.Instance do
285287 end
286288
287289 defp route_info ( method , path , % { expectations: expectations } = _state ) do
288- route =
289- case Map . get ( expectations , { method , path } , :no_expectations ) do
290- :no_expectations ->
291- { :any , :any }
290+ segments = build_path_match ( path ) |> elem ( 1 )
292291
293- _ ->
294- { method , path }
295- end
292+ route =
293+ expectations
294+ |> Enum . reduce_while (
295+ { :any , :any , % { } } ,
296+ fn
297+ { { ^ method , path_pattern } , % { path_parts: path_parts } } , acc ->
298+ case match_route ( segments , path_parts ) do
299+ { true , params } -> { :halt , { method , path_pattern , params } }
300+ { false , _ } -> { :cont , acc }
301+ end
302+
303+ _ , acc ->
304+ { :cont , acc }
305+ end
306+ )
296307
297308 { route , Map . get ( expectations , route ) }
298309 end
299310
311+ defp match_route ( path , route ) when length ( path ) == length ( route ) do
312+ path
313+ |> Enum . zip ( route )
314+ |> Enum . reduce_while (
315+ { true , % { } } ,
316+ fn
317+ { value , { param , _ , _ } } , { _ , params } ->
318+ { :cont , { true , Map . put ( params , Atom . to_string ( param ) , value ) } }
319+
320+ { segment , segment } , acc ->
321+ { :cont , acc }
322+
323+ _ , _ ->
324+ { :halt , { false , nil } }
325+ end
326+ )
327+ end
328+
329+ defp match_route ( _ , _ ) , do: { false , nil }
330+
300331 defp do_up ( port , ref ) do
301332 plug_opts = [ self ( ) ]
302333 { :ok , socket } = :ranch_tcp . listen ( so_reuseport ( ) ++ [ ip: listen_ip ( ) , port: port ] )
@@ -353,16 +384,23 @@ defmodule Bypass.Instance do
353384 |> length
354385 end
355386
356- defp new_route ( fun , expected ) do
387+ defp new_route ( fun , path_parts , expected ) when is_list ( path_parts ) do
357388 % {
358389 fun: fun ,
359390 expected: expected ,
391+ path_parts: path_parts ,
360392 retained_plugs: % { } ,
361393 results: [ ] ,
362394 request_count: 0
363395 }
364396 end
365397
398+ defp new_route ( fun , :any , expected ) ,
399+ do: new_route ( fun , [ ] , expected )
400+
401+ defp new_route ( fun , path , expected ) ,
402+ do: new_route ( fun , build_path_match ( path ) |> elem ( 1 ) , expected )
403+
366404 defp cowboy_opts ( port , ref , socket ) do
367405 case Application . spec ( :plug_cowboy , :vsn ) do
368406 '1.' ++ _ -> [ ref: ref , acceptors: 5 , port: port , socket: socket ]
0 commit comments