@@ -2,15 +2,20 @@ alias Dispatcher.Log
22
33defmodule Matcher do
44 defmacro __using__ ( _opts ) do
5+ # Set this attribute _BEFORE_ any code is ran
6+ Module . register_attribute ( __CALLER__ . module , :websocket , accumulate: true )
7+
58 quote do
69 require Matcher
710 import Matcher
11+ import Plug.Router , only: [ forward: 2 ]
812 import Plug.Conn , only: [ send_resp: 3 ]
913 import Proxy , only: [ forward: 3 ]
1014
1115 def layers do
12- [ :service , :last_call ]
16+ [ :service , :last_call ]
1317 end
18+
1419 defoverridable layers: 0
1520
1621 def dispatch ( conn ) do
@@ -28,6 +33,34 @@ defmodule Matcher do
2833 end
2934 end
3035
36+ defmacro ws ( conn , host ) do
37+ # host = "ws://localhost:8000/test"
38+
39+ parsed =
40+ URI . parse ( host )
41+ |> Log . inspect ( :log_ws_all , label: "Creating websocket route" )
42+
43+ id = for _ <- 1 .. 24 , into: "" , do: << Enum . random ( '0123456789abcdef' ) >>
44+
45+ host = parsed . host || "localhost"
46+ port = parsed . port || 80
47+ path = parsed . path || "/"
48+
49+ Module . put_attribute ( __CALLER__ . module , :websocket , % {
50+ host: host ,
51+ port: port ,
52+ path: path ,
53+ id: id
54+ } )
55+
56+ # Return redirect things
57+ quote do
58+ unquote ( conn )
59+ |> Plug.Conn . resp ( :found , "" )
60+ |> Plug.Conn . put_resp_header ( "location" , "/ws?target=" <> unquote ( id ) )
61+ end
62+ end
63+
3164 defmacro get ( path , options \\ quote ( do: % { } ) , do: block ) do
3265 quote do
3366 match_method ( get , unquote ( path ) , unquote ( options ) , do: unquote ( block ) )
@@ -98,7 +131,6 @@ defmodule Matcher do
98131 defmacro __before_compile__ ( _env ) do
99132 matchers =
100133 Module . get_attribute ( __CALLER__ . module , :matchers )
101- # |> IO.inspect(label: "Discovered matchers")
102134 |> Enum . map ( fn { call , path , options , block } ->
103135 make_match_method ( call , path , options , block , __CALLER__ )
104136 end )
@@ -110,7 +142,18 @@ defmodule Matcher do
110142 end
111143 end
112144
113- [ last_match_def | matchers ]
145+ socket_dict_f =
146+ quote do
147+ def websockets ( ) do
148+ Enum . reduce ( @ websocket , % { } , fn x , acc -> Map . put ( acc , x . id , x ) end )
149+ end
150+
151+ def get_websocket ( id ) do
152+ Enum . find ( @ websocket , fn x -> x . id == id end )
153+ end
154+ end
155+
156+ [ socket_dict_f , last_match_def | matchers ]
114157 |> Enum . reverse ( )
115158 end
116159
@@ -171,24 +214,29 @@ defmodule Matcher do
171214
172215 new_accept =
173216 case value do
174- [ item ] -> # convert item
217+ # convert item
218+ [ item ] ->
175219 { :%{} , [ ] , [ { item , true } ] }
220+
176221 [ _item | _rest ] ->
177222 raise "Multiple items in accept arrays are not supported."
223+
178224 { :%{} , _ , _ } ->
179225 value
180226 end
181227
182228 new_list =
183229 list
184- |> Keyword . drop ( [ :accept ] )
185- |> Keyword . merge ( [ accept: new_accept ] )
230+ |> Keyword . drop ( [ :accept ] )
231+ |> Keyword . merge ( accept: new_accept )
186232
187233 { :%{} , any , new_list }
188234 else
189235 options
190236 end
191- _ -> options
237+
238+ _ ->
239+ options
192240 end
193241 end
194242
@@ -223,8 +271,6 @@ defmodule Matcher do
223271 str -> str
224272 end ) . ( )
225273
226- # |> IO.inspect(label: "call name")
227-
228274 # Creates the variable(s) for the parsed path
229275 process_derived_path_elements = fn elements ->
230276 reversed_elements = Enum . reverse ( elements )
@@ -310,7 +356,6 @@ defmodule Matcher do
310356 def dispatch_call ( conn , accept_types , layers_fn , call_handler ) do
311357 # Extract core info
312358 { method , path , accept_header , host } = extract_core_info_from_conn ( conn )
313- # |> IO.inspect(label: "extracted header")
314359
315360 # Extract core request info
316361 accept_hashes =
@@ -321,10 +366,11 @@ defmodule Matcher do
321366
322367 # layers |> IO.inspect(label: "layers" )
323368 # Try to find a solution in each of the layers
324- layers = layers_fn . ( )
325- |> Log . inspect ( :log_available_layers , "Available layers" )
369+ layers =
370+ layers_fn . ( )
371+ |> Log . inspect ( :log_available_layers , "Available layers" )
326372
327- reverse_host = Enum . reverse ( host )
373+ reverse_host = Enum . reverse ( host )
328374
329375 response_conn =
330376 layers
@@ -432,7 +478,7 @@ defmodule Matcher do
432478 defp sort_and_group_accept_headers ( accept ) do
433479 accept
434480 |> safe_parse_accept_header ( )
435- # |> IO.inspect(label: "parsed_accept_header")
481+ |> IO . inspect ( label: "parsed_accept_header" )
436482 |> Enum . sort_by ( & elem ( & 1 , 3 ) )
437483 |> Enum . group_by ( & elem ( & 1 , 3 ) )
438484 |> Map . to_list ( )
0 commit comments