@@ -6,7 +6,7 @@ defmodule Membrane.RTSP do
66
77 require Logger
88 alias Membrane.RTSP
9- alias Membrane.RTSP . { Request , Response , TCPSocket }
9+ alias Membrane.RTSP . { Request , Response , Transport }
1010
1111 @ type t ( ) :: pid ( )
1212
@@ -19,15 +19,6 @@ defmodule Membrane.RTSP do
1919
2020 defmodule State do
2121 @ moduledoc false
22- @ enforce_keys [ :socket , :uri ]
23- defstruct @ enforce_keys ++
24- [
25- :response_timeout ,
26- :session_id ,
27- cseq: 0 ,
28- auth: nil
29- ]
30-
3122 @ type digest_opts ( ) :: % {
3223 realm: String . t ( ) | nil ,
3324 nonce: String . t ( ) | nil
@@ -41,8 +32,20 @@ defmodule Membrane.RTSP do
4132 uri: URI . t ( ) ,
4233 session_id: binary ( ) | nil ,
4334 auth: auth ( ) ,
44- response_timeout: non_neg_integer ( )
35+ response_timeout: non_neg_integer ( ) | nil ,
36+ receive_from: :socket | :external_process ,
37+ retries: non_neg_integer ( )
4538 }
39+
40+ @ enforce_keys [ :socket , :uri , :response_timeout ]
41+ defstruct @ enforce_keys ++
42+ [
43+ session_id: nil ,
44+ cseq: 0 ,
45+ auth: nil ,
46+ receive_from: :socket ,
47+ retries: 0
48+ ]
4649 end
4750
4851 @ doc """
@@ -67,15 +70,14 @@ defmodule Membrane.RTSP do
6770 GenServer . call ( session , { :execute , request } , :infinity )
6871 end
6972
70- @ spec request_no_response ( pid ( ) , binary ( ) , RTSP . headers ( ) , binary ( ) , nil | binary ( ) ) :: :ok
71- def request_no_response ( session , method , headers \\ [ ] , body \\ "" , path \\ nil ) do
72- request = % Request { method: method , headers: headers , body: body , path: path }
73- GenServer . cast ( session , { :execute , request } )
74- end
75-
7673 @ spec close ( pid ( ) ) :: :ok
7774 def close ( session ) , do: GenServer . cast ( session , :terminate )
7875
76+ @ doc """
77+ Transfer the control of the TCP socket the session was using to a new process. For more information see `:gen_tcp.controlling_process/2`.
78+ From now on the session won't try to receive responses to requests from the socket, since now an other process is controlling it.
79+ Instead of this, the session will synchronously wait for the response to be supplied with `handle_response/2`.
80+ """
7981 @ spec transfer_socket_control ( t ( ) , pid ( ) ) ::
8082 :ok | { :error , :closed | :not_owner | :badarg | :inet . posix ( ) }
8183 def transfer_socket_control ( session , new_controlling_process ) do
@@ -87,19 +89,13 @@ defmodule Membrane.RTSP do
8789 GenServer . call ( session , :get_socket )
8890 end
8991
90- @ type headers :: [ { binary ( ) , binary ( ) } ]
91-
92- @ spec handle_response ( t ( ) , binary ( ) ) :: Response . result ( )
93- def handle_response ( session , raw_response ) ,
94- do: GenServer . call ( session , { :parse_response , raw_response } )
95-
96- @ spec get_parameter_no_response ( t ( ) , headers ( ) , binary ( ) ) :: :ok
97- def get_parameter_no_response ( session , headers \\ [ ] , body \\ "" ) ,
98- do: request_no_response ( session , "GET_PARAMETER" , headers , body )
92+ @ spec handle_response ( t ( ) , binary ( ) ) :: :ok
93+ def handle_response ( session , raw_response ) do
94+ send ( session , { :raw_response , raw_response } )
95+ :ok
96+ end
9997
100- @ spec play_no_response ( t ( ) , headers ( ) ) :: :ok
101- def play_no_response ( session , headers \\ [ ] ) ,
102- do: request_no_response ( session , "PLAY" , headers , "" )
98+ @ type headers :: [ { binary ( ) , binary ( ) } ]
10399
104100 @ spec describe ( t ( ) , headers ( ) ) :: Response . result ( )
105101 def describe ( session , headers \\ [ ] ) , do: request ( session , "DESCRIBE" , headers , "" )
@@ -148,7 +144,7 @@ defmodule Membrane.RTSP do
148144 % URI { userinfo: info } when is_binary ( info ) -> :basic
149145 end
150146
151- with { :ok , socket } <- TCPSocket . connect ( url , options [ :connection_timeout ] ) do
147+ with { :ok , socket } <- Transport . connect ( url , options [ :connection_timeout ] ) do
152148 state = % State {
153149 socket: socket ,
154150 uri: url ,
@@ -164,53 +160,28 @@ defmodule Membrane.RTSP do
164160
165161 @ impl true
166162 def handle_call ( { :execute , request } , _from , state ) do
167- with { :ok , raw_response } <- execute ( request , state ) ,
168- { :ok , response , state } <- parse_response ( raw_response , state ) do
169- { :reply , { :ok , response } , state }
170- else
171- { :error , reason } -> { :reply , { :error , reason } , state }
172- end
163+ handle_execute_call ( request , true , state )
173164 end
174165
175166 @ impl true
176- def handle_call (
177- { :transfer_socket_control , new_controlling_process } ,
178- _from ,
179- % State { socket: socket } = state
180- ) do
181- { :reply , :gen_tcp . controlling_process ( socket , new_controlling_process ) , state }
167+ def handle_call ( { :transfer_socket_control , new_controlling_process } , _from , state ) do
168+ {
169+ :reply ,
170+ :gen_tcp . controlling_process ( state . socket , new_controlling_process ) ,
171+ % { state | receive_from: :external_process }
172+ }
182173 end
183174
184175 @ impl true
185176 def handle_call ( :get_socket , _from , % State { socket: socket } = state ) do
186177 { :reply , socket , state }
187178 end
188179
189- @ impl true
190- def handle_call ( { :parse_response , raw_response } , _from , state ) do
191- with { :ok , response , state } <- parse_response ( raw_response , state ) do
192- { :reply , { :ok , response } , state }
193- else
194- { :error , reason } -> { :reply , { :error , reason } , state }
195- end
196- end
197-
198180 @ impl true
199181 def handle_cast ( :terminate , % State { } = state ) do
200182 { :stop , :normal , state }
201183 end
202184
203- @ impl true
204- def handle_cast ( { :execute , request } , % State { cseq: cseq } = state ) do
205- case execute ( request , state , false ) do
206- :ok ->
207- { :noreply , % State { state | cseq: cseq + 1 } }
208-
209- { :error , reason } ->
210- raise "Error executing request #{ inspect ( request ) } , reason: #{ inspect ( reason ) } "
211- end
212- end
213-
214185 @ impl true
215186 def handle_info ( { :tcp , _socket , data } , state ) do
216187 Logger . warning ( "Received an unexpected packet, ignoring: #{ inspect ( data ) } " )
@@ -224,7 +195,7 @@ defmodule Membrane.RTSP do
224195
225196 @ impl true
226197 def terminate ( _reason , state ) do
227- TCPSocket . close ( state . socket )
198+ Transport . close ( state . socket )
228199 end
229200
230201 @ spec do_start ( binary ( ) | URI . t ( ) , options ( ) , ( module ( ) , any ( ) -> GenServer . on_start ( ) ) ) ::
@@ -242,9 +213,8 @@ defmodule Membrane.RTSP do
242213 end
243214 end
244215
245- @ spec execute ( Request . t ( ) , State . t ( ) , boolean ( ) ) ::
246- :ok | { :ok , binary ( ) } | { :error , reason :: any ( ) }
247- defp execute ( request , state , get_response \\ true ) do
216+ @ spec execute ( Request . t ( ) , State . t ( ) ) :: { :ok , binary ( ) } | { :error , reason :: any ( ) }
217+ defp execute ( request , state ) do
248218 % State {
249219 cseq: cseq ,
250220 socket: socket ,
@@ -260,10 +230,10 @@ defmodule Membrane.RTSP do
260230 |> Request . with_header ( "User-Agent" , @ user_agent )
261231 |> apply_credentials ( uri , state . auth )
262232 |> Request . stringify ( uri )
263- |> TCPSocket . execute ( socket , response_timeout , get_response )
233+ |> Transport . execute ( socket , response_timeout , state . receive_from )
264234 end
265235
266- @ spec inject_session_header ( Request . t ( ) , binary ( ) ) :: Request . t ( )
236+ @ spec inject_session_header ( Request . t ( ) , binary ( ) | nil ) :: Request . t ( )
267237 defp inject_session_header ( request , session_id ) do
268238 case session_id do
269239 nil -> request
@@ -303,6 +273,23 @@ defmodule Membrane.RTSP do
303273 end
304274 end
305275
276+ @ spec handle_execute_call ( Request . t ( ) , boolean ( ) , State . t ( ) ) ::
277+ { :reply , Response . result ( ) , State . t ( ) }
278+ defp handle_execute_call ( request , retry , state ) do
279+ with { :ok , raw_response } <- execute ( request , state ) ,
280+ { :ok , response , state } <- parse_response ( raw_response , state ) do
281+ case response do
282+ % Response { status: 401 } when retry ->
283+ handle_execute_call ( request , false , state )
284+
285+ response ->
286+ { :reply , { :ok , response } , state }
287+ end
288+ else
289+ { :error , reason } -> { :reply , { :error , reason } , state }
290+ end
291+ end
292+
306293 @ spec do_apply_credentials ( Request . t ( ) , URI . t ( ) , State . auth ( ) ) :: Request . t ( )
307294 defp do_apply_credentials ( request , % URI { userinfo: info } , :basic ) do
308295 encoded = Base . encode64 ( info )
0 commit comments