freeswitcher 0.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ require 'spec/helper'
2
+ require "fsr/app"
3
+ FSR::App.load_application("fs_break")
4
+
5
+ describe "Testing FSR::App::FsBreak" do
6
+
7
+ it "should break a connection" do
8
+ fs_break = FSR::App::FSBreak.new
9
+ fs_break.sendmsg.should == "call-command: execute\nexecute-app-name: break\n\n"
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec/helper'
2
+ require "fsr/app"
3
+ FSR::App.load_application("fs_sleep")
4
+
5
+ describe "Testing FSR::App::FsSleep" do
6
+
7
+ it "should put FreeSWITCH leg to sleep for 7000 miliseconds" do
8
+ fs_sleep = FSR::App::FSSleep.new(7000)
9
+ fs_sleep.sendmsg.should == "call-command: execute\nexecute-app-name: sleep\nexecute-app-arg: 7000\n\n"
10
+ end
11
+
12
+ end
@@ -3,10 +3,42 @@ require "fsr/cmd"
3
3
  FSR::Cmd.load_command("originate")
4
4
 
5
5
  describe "Testing FSR::Cmd::Originate" do
6
+ # Invalid originates
7
+ it "Must be passed an argument hash" do
8
+ lambda { FSR::Cmd::Originate.new(nil, :endpoint) }.should.raise(ArgumentError).
9
+ message.should.match(/args \(Passed: <<<.*?>>>\) must be a hash/)
10
+ end
11
+
12
+ it "Should require args[:target_options] to be a hash" do
13
+ lambda { FSR::Cmd::Originate.new(nil, :endpoint => "4000", :target => "user/bougyman", :target_options => 1) }.should.raise(ArgumentError).
14
+ message.should.match(/args\[:target_options\] \(Passed: <<<.*?>>>\) must be a hash/)
15
+ end
16
+
17
+ it "Can not originate without a target" do
18
+ lambda { FSR::Cmd::Originate.new(nil, :endpoint => "4000") }.should.raise(ArgumentError).
19
+ message.should.match(/Cannot originate without a :target set/)
20
+ end
21
+
22
+ it "Can not originate without an endpoint" do
23
+ lambda { FSR::Cmd::Originate.new(nil, :target => "4000") }.should.raise(ArgumentError).
24
+ message.should.match(/Cannot originate without an :endpoint set/)
25
+ end
26
+
6
27
  # Originate to an extension
7
28
  it "Originates calls to extensions" do
8
29
  originate = FSR::Cmd::Originate.new(nil, :target => "user/bougyman", :endpoint => "4000")
9
30
  originate.raw.should == "originate {ignore_early_media=true,originate_timeout=30,origination_caller_id_name=FSR,origination_caller_id_number=8675309}user/bougyman 4000"
10
31
  end
11
32
 
33
+ # Different options choices
34
+ it "Honors timeout in :timeout option" do
35
+ originate = FSR::Cmd::Originate.new(nil, :target => "user/bougyman", :timeout => 10, :endpoint => "4000")
36
+ originate.raw.should == "originate {ignore_early_media=true,originate_timeout=10,origination_caller_id_name=FSR,origination_caller_id_number=8675309}user/bougyman 4000"
37
+ end
38
+
39
+ it "Honors timeout in :target_options[timeout] option" do
40
+ originate = FSR::Cmd::Originate.new(nil, :target => "user/bougyman", :target_options => {:timeout => 10}, :endpoint => "4000")
41
+ originate.raw.should == "originate {ignore_early_media=true,originate_timeout=10,origination_caller_id_name=FSR,origination_caller_id_number=8675309}user/bougyman 4000"
42
+ end
43
+
12
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freeswitcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jayson Vaughn
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2009-05-11 00:00:00 -05:00
15
+ date: 2009-05-18 00:00:00 -05:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: "0"
27
27
  version:
28
- description: "========================================================= FreeSWITCHeR Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry) Distributed under the terms of the MIT License. ========================================================== ABOUT ----- A ruby library for interacting with the \"FreeSWITCH\" (http://www.freeswitch.org) opensource telephony platform REQUIREMENTS ------------ - ruby (>= 1.8) - eventmachine (If you wish to use Outbound and Inbound listener) USAGE ----- An Outbound Event Listener Example that reads and returns DTMF input: -------------------------------------------------------------------- Simply just create a subclass of FSR::Listner::Outbound and all new calls/sessions will invoke the \"session_initiated\" callback method. * NOTE: FSR uses blocks within the 'session_inititated' method to ensure that the next \"freeswich command\" is not executed until the previous \"Freeswitch command\" has finished. This is kicked off by \"answer do\" require 'fsr' require 'fsr/listener/outbound' class OutboundDemo < FSR::Listener::Outbound def session_initiated exten = @session.headers[:caller_caller_id_number] FSR::Log.info \"*** Answering incoming call from #{exten}\" answer do FSR::Log.info \"***Reading DTMF from #{exten}\" read(\"/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav\", 4, 10, \"input\", 7000) do FSR::Log.info \"*** Updating session for #{exten}\" update_session do FSR::Log.info \"***Success, grabbed #{@session.headers[:variable_input].strip} from #{exten}\" hangup #Hangup the call end end end end end FSR.start_oes! OutboundDemo, :port => 8084, :host => \"127.0.0.1\" An Inbound Event Socket Listener example using FreeSWITCHeR's hook system: -------------------------------------------------------------------------- require 'pp' require 'fsr' require \"fsr/listener/inbound\" # EXAMPLE 1 # This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info \"*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!\" } # EXAMPLE 2 # Define a method to handle CHANNEL_HANGUP events. def custom_channel_hangup_handler(event) FSR::Log.info \"*** [#{event.content[:unique_id]}] Channel hangup. The event:\" pp event end # This adds a hook for EXAMPLE 2 FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) } # Start FSR Inbound Listener FSR.start_ies!(FSL::Inbound, :host => \"localhost\", :port => 8021) An Inbound Event Socket Listener example using the on_event callback method instead of hooks: --------------------------------------------------------------------------------------------- require 'pp' require 'fsr' require \"fsr/listener/inbound\" class IesDemo < FSR::Listener::Inbound def on_event(event) pp event.headers pp event.content[:event_name] end end FSR.start_ies!(IesDemo, :host => \"localhost\", :port => 8021) An example of using FSR::CommandSocket to originate a new call in irb: ---------------------------------------------------------------------- irb(main):001:0> require 'fsr' => true irb(main):002:0> FSR.load_all_commands => [:sofia, :originate] irb(main):003:0> sock = FSR::CommandSocket.new => #<FSR::CommandSocket:0xb7a89104 @server=\"127.0.0.1\", @socket=#<TCPSocket:0xb7a8908c>, @port=\"8021\", @auth=\"ClueCon\"> irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new(\"user/bougyman\")).run => {\"Job-UUID\"=>\"732075a4-7dd5-4258-b124-6284a82a5ae7\", \"body\"=>\"\", \"Content-Type\"=>\"command/reply\", \"Reply-Text\"=>\"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7\"} SUPPORT ------- Home page at http://code.rubyists.com/projects/fs #rubyists on FreeNode"
28
+ description: "========================================================= FreeSWITCHeR Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry) Distributed under the terms of the MIT License. ========================================================== ABOUT ----- A ruby library for interacting with the \"FreeSWITCH\" (http://www.freeswitch.org) opensource telephony platform REQUIREMENTS ------------ * ruby (>= 1.8) * eventmachine (If you wish to use Outbound and Inbound listener) USAGE ----- An Outbound Event Listener Example that reads and returns DTMF input: -------------------------------------------------------------------- Simply just create a subclass of FSR::Listner::Outbound and all new calls/sessions will invoke the \"session_initiated\" callback method. <b>NOTE</b>: FSR uses blocks within the 'session_inititated' method to ensure that the next \"freeswich command\" is not executed until the previous \"Freeswitch command\" has finished. This is kicked off by \"answer do\" #!/usr/bin/ruby require 'fsr' require 'fsr/listener/outbound' class OutboundDemo < FSR::Listener::Outbound def session_initiated exten = @session.headers[:caller_caller_id_number] FSR::Log.info \"*** Answering incoming call from #{exten}\" answer do FSR::Log.info \"***Reading DTMF from #{exten}\" read(\"/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav\", 4, 10, \"input\", 7000) do |read_var| FSR::Log.info \"***Success, grabbed #{read_var.strip} from #{exten}\" hangup #Hangup the call end end end end FSR.start_oes! OutboundDemo, :port => 8084, :host => \"127.0.0.1\" An Inbound Event Socket Listener example using FreeSWITCHeR's hook system: -------------------------------------------------------------------------- #!/usr/bin/ruby require 'pp' require 'fsr' require \"fsr/listener/inbound\" # EXAMPLE 1 # This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info \"*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!\" } # EXAMPLE 2 # Define a method to handle CHANNEL_HANGUP events. def custom_channel_hangup_handler(event) FSR::Log.info \"*** [#{event.content[:unique_id]}] Channel hangup. The event:\" pp event end # This adds a hook for EXAMPLE 2 FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) } # Start FSR Inbound Listener FSR.start_ies!(FSL::Inbound, :host => \"localhost\", :port => 8021) An Inbound Event Socket Listener example using the on_event callback method instead of hooks: --------------------------------------------------------------------------------------------- #!/usr/bin/ruby require 'pp' require 'fsr' require \"fsr/listener/inbound\" class IesDemo < FSR::Listener::Inbound def on_event(event) pp event.headers pp event.content[:event_name] end end FSR.start_ies!(IesDemo, :host => \"localhost\", :port => 8021) An example of using FSR::CommandSocket to originate a new call in irb: ---------------------------------------------------------------------- irb(main):001:0> require 'fsr' => true irb(main):002:0> FSR.load_all_commands => [:sofia, :originate] irb(main):003:0> sock = FSR::CommandSocket.new => #<FSR::CommandSocket:0xb7a89104 @server=\"127.0.0.1\", @socket=#<TCPSocket:0xb7a8908c>, @port=\"8021\", @auth=\"ClueCon\"> irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new(\"user/bougyman\")).run => {\"Job-UUID\"=>\"732075a4-7dd5-4258-b124-6284a82a5ae7\", \"body\"=>\"\", \"Content-Type\"=>\"command/reply\", \"Reply-Text\"=>\"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7\"} SUPPORT ------- Home page at http://code.rubyists.com/projects/fs #rubyists on FreeNode"
29
29
  email: FreeSWITCHeR@rubyists.com
30
30
  executables: []
31
31
 
@@ -89,7 +89,6 @@ files:
89
89
  - lib/fsr/listener/inbound.rb
90
90
  - lib/fsr/listener/inbound/event.rb
91
91
  - lib/fsr/listener/outbound.rb
92
- - lib/fsr/listener/outbound.rb.orig
93
92
  - lib/fsr/model/call.rb
94
93
  - lib/fsr/version.rb
95
94
  - tasks/authors.rake
@@ -107,26 +106,6 @@ files:
107
106
  - tasks/spec.rake
108
107
  - tasks/yard.rake
109
108
  - spec/helper.rb
110
- - spec/fsr/app.rb
111
- - spec/fsr/app/bridge.rb
112
- - spec/fsr/app/conference.rb
113
- - spec/fsr/app/fifo.rb
114
- - spec/fsr/app/hangup.rb
115
- - spec/fsr/app/limit.rb
116
- - spec/fsr/app/log.rb
117
- - spec/fsr/app/play_and_get_digits.rb
118
- - spec/fsr/app/playback.rb
119
- - spec/fsr/app/set.rb
120
- - spec/fsr/app/transfer.rb
121
- - spec/fsr/cmd.rb
122
- - spec/fsr/cmd/calls.rb
123
- - spec/fsr/cmd/originate.rb
124
- - spec/fsr/cmd/sofia.rb
125
- - spec/fsr/cmd/sofia/profile.rb
126
- - spec/fsr/listener.rb
127
- - spec/fsr/listener/inbound.rb
128
- - spec/fsr/listener/outbound.rb
129
- - spec/fsr/loading.rb
130
109
  has_rdoc: false
131
110
  homepage: http://code.rubyists.com/projects/fs
132
111
  post_install_message: |
@@ -142,8 +121,8 @@ post_install_message: |
142
121
 
143
122
  REQUIREMENTS
144
123
  ------------
145
- - ruby (>= 1.8)
146
- - eventmachine (If you wish to use Outbound and Inbound listener)
124
+ * ruby (>= 1.8)
125
+ * eventmachine (If you wish to use Outbound and Inbound listener)
147
126
 
148
127
  USAGE
149
128
  -----
@@ -154,97 +133,94 @@ post_install_message: |
154
133
  Simply just create a subclass of FSR::Listner::Outbound and all
155
134
  new calls/sessions will invoke the "session_initiated" callback method.
156
135
 
157
- * NOTE: FSR uses blocks within the 'session_inititated' method to ensure
158
- that the next "freeswich command" is not executed until the previous
159
- "Freeswitch command" has finished. This is kicked off by "answer do"
160
-
161
- require 'fsr'
162
- require 'fsr/listener/outbound'
163
-
164
- class OutboundDemo < FSR::Listener::Outbound
165
-
166
- def session_initiated
167
- exten = @session.headers[:caller_caller_id_number]
168
- FSR::Log.info "*** Answering incoming call from #{exten}"
169
-
170
- answer do
171
- FSR::Log.info "***Reading DTMF from #{exten}"
172
- read("/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav", 4, 10, "input", 7000) do
173
- FSR::Log.info "*** Updating session for #{exten}"
174
- update_session do
175
- FSR::Log.info "***Success, grabbed #{@session.headers[:variable_input].strip} from #{exten}"
176
- hangup #Hangup the call
177
- end
178
- end
179
- end
136
+ <b>NOTE</b>: FSR uses blocks within the 'session_inititated' method to ensure that the next "freeswich command" is not executed until the previous "Freeswitch command" has finished. This is kicked off by "answer do"
137
+
138
+ #!/usr/bin/ruby
139
+ require 'fsr'
140
+ require 'fsr/listener/outbound'
180
141
 
142
+ class OutboundDemo < FSR::Listener::Outbound
143
+
144
+ def session_initiated
145
+ exten = @session.headers[:caller_caller_id_number]
146
+ FSR::Log.info "*** Answering incoming call from #{exten}"
147
+
148
+ answer do
149
+ FSR::Log.info "***Reading DTMF from #{exten}"
150
+ read("/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav", 4, 10, "input", 7000) do |read_var|
151
+ FSR::Log.info "***Success, grabbed #{read_var.strip} from #{exten}"
152
+ hangup #Hangup the call
153
+ end
181
154
  end
182
155
 
183
156
  end
184
157
 
185
- FSR.start_oes! OutboundDemo, :port => 8084, :host => "127.0.0.1"
158
+ end
186
159
 
160
+ FSR.start_oes! OutboundDemo, :port => 8084, :host => "127.0.0.1"
187
161
 
188
162
  An Inbound Event Socket Listener example using FreeSWITCHeR's hook system:
189
163
  --------------------------------------------------------------------------
190
164
 
191
- require 'pp'
192
- require 'fsr'
193
- require "fsr/listener/inbound"
165
+ #!/usr/bin/ruby
166
+ require 'pp'
167
+ require 'fsr'
168
+ require "fsr/listener/inbound"
194
169
 
195
- # EXAMPLE 1
196
- # This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example
197
- FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info "*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!" }
170
+ # EXAMPLE 1
171
+ # This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example
172
+ FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info "*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!" }
198
173
 
199
- # EXAMPLE 2
200
- # Define a method to handle CHANNEL_HANGUP events.
201
- def custom_channel_hangup_handler(event)
202
- FSR::Log.info "*** [#{event.content[:unique_id]}] Channel hangup. The event:"
203
- pp event
204
- end
174
+ # EXAMPLE 2
175
+ # Define a method to handle CHANNEL_HANGUP events.
176
+ def custom_channel_hangup_handler(event)
177
+ FSR::Log.info "*** [#{event.content[:unique_id]}] Channel hangup. The event:"
178
+ pp event
179
+ end
205
180
 
206
- # This adds a hook for EXAMPLE 2
207
- FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) }
181
+ # This adds a hook for EXAMPLE 2
182
+ FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) }
208
183
 
209
184
 
210
- # Start FSR Inbound Listener
211
- FSR.start_ies!(FSL::Inbound, :host => "localhost", :port => 8021)
185
+ # Start FSR Inbound Listener
186
+ FSR.start_ies!(FSL::Inbound, :host => "localhost", :port => 8021)
212
187
 
213
188
 
214
189
  An Inbound Event Socket Listener example using the on_event callback method instead of hooks:
215
190
  ---------------------------------------------------------------------------------------------
216
191
 
217
- require 'pp'
218
- require 'fsr'
219
- require "fsr/listener/inbound"
192
+ #!/usr/bin/ruby
193
+ require 'pp'
194
+ require 'fsr'
195
+ require "fsr/listener/inbound"
220
196
 
221
197
 
222
- class IesDemo < FSR::Listener::Inbound
223
-
224
- def on_event(event)
225
- pp event.headers
226
- pp event.content[:event_name]
227
- end
198
+ class IesDemo < FSR::Listener::Inbound
228
199
 
200
+ def on_event(event)
201
+ pp event.headers
202
+ pp event.content[:event_name]
229
203
  end
230
204
 
231
- FSR.start_ies!(IesDemo, :host => "localhost", :port => 8021)
205
+ end
206
+
207
+ FSR.start_ies!(IesDemo, :host => "localhost", :port => 8021)
232
208
 
233
209
 
234
210
  An example of using FSR::CommandSocket to originate a new call in irb:
235
211
  ----------------------------------------------------------------------
236
212
 
237
- irb(main):001:0> require 'fsr'
238
- => true
213
+ irb(main):001:0> require 'fsr'
214
+ => true
239
215
 
240
- irb(main):002:0> FSR.load_all_commands
241
- => [:sofia, :originate]
216
+ irb(main):002:0> FSR.load_all_commands
217
+ => [:sofia, :originate]
242
218
 
243
- irb(main):003:0> sock = FSR::CommandSocket.new
244
- => #<FSR::CommandSocket:0xb7a89104 @server="127.0.0.1", @socket=#<TCPSocket:0xb7a8908c>, @port="8021", @auth="ClueCon">
219
+ irb(main):003:0> sock = FSR::CommandSocket.new
220
+ => #<FSR::CommandSocket:0xb7a89104 @server="127.0.0.1", @socket=#<TCPSocket:0xb7a8908c>, @port="8021", @auth="ClueCon">
245
221
 
246
- irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new("user/bougyman")).run
247
- => {"Job-UUID"=>"732075a4-7dd5-4258-b124-6284a82a5ae7", "body"=>"", "Content-Type"=>"command/reply", "Reply-Text"=>"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7"}
222
+ irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new("user/bougyman")).run
223
+ => {"Job-UUID"=>"732075a4-7dd5-4258-b124-6284a82a5ae7", "body"=>"", "Content-Type"=>"command/reply", "Reply-Text"=>"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7"}
248
224
 
249
225
 
250
226
 
@@ -278,9 +254,12 @@ specification_version: 2
278
254
  summary: A library for interacting with the "FreeSWITCH":http://freeswitch.org telephony platform
279
255
  test_files:
280
256
  - spec/fsr/app.rb
257
+ - spec/fsr/app/answer.rb
281
258
  - spec/fsr/app/bridge.rb
282
259
  - spec/fsr/app/conference.rb
283
260
  - spec/fsr/app/fifo.rb
261
+ - spec/fsr/app/fs_break.rb
262
+ - spec/fsr/app/fs_sleep.rb
284
263
  - spec/fsr/app/hangup.rb
285
264
  - spec/fsr/app/limit.rb
286
265
  - spec/fsr/app/log.rb
@@ -1,131 +0,0 @@
1
- require "yaml"
2
- require "fsr/listener"
3
- module FSR
4
- load_all_applications
5
- module Listener
6
- module Outbound
7
- include FSR::Listener
8
-
9
- # Include FSR::App to get all the applications defined as methods
10
- include FSR::App
11
-
12
- # Redefine the FSR::App methods to wrap sendmsg around them
13
- SENDMSG_METHOD_DEFINITION = "def %s(*args, &block); sendmsg super; end"
14
- APPLICATIONS.each { |app, obj| module_eval(SENDMSG_METHOD_DEFINITION % app.to_s) }
15
-
16
- def post_init
17
- @session = nil # holds the session object
18
- send_data("connect\n\n")
19
- FSR::Log.debug "Accepting connections."
20
- end
21
-
22
- # Received data dispatches the data received by the EM socket,
23
- # Either as a Session, a continuation of a Session, or as a Session's last CommandReply
24
- def receive_data(data)
25
- FSR::Log.debug("received #{data}")
26
- if @session.nil? # if @session is nil, create a new Session object
27
- @session = Session.new(data)
28
- session_initiated(@session) if @session.initiated?
29
- else
30
- # If it's not nil, we add the data to this session, Session knows whether
31
- # or not to create a CommandReply, complete a CommandReply, or simply add to
32
- # its own @data array and @headers/@body structures
33
- if @session.initiated?
34
- @session << data
35
- reply_received(@session.replies.last) if @session.replies.last.complete?
36
- else
37
- @session << data
38
- session_initiated(@session) if @session.initiated?
39
- end
40
- end
41
- @session
42
- end
43
-
44
- def session_initiated(session)
45
- session
46
- end
47
-
48
- def reply_received(command_reply)
49
- command_reply
50
- end
51
-
52
- alias :receive_response :reply_received
53
- # sendmsg sends data to the EM app socket via #send_data, or
54
- # returns the string it would send if #send_data is not defined.
55
- # It expects an object which responds to either #sendmsg or #to_s,
56
- # which should return a EM Outbound Event Socket formatted instruction
57
- def sendmsg(message)
58
- text = message.respond_to?(:sendmsg) ? message.sendmsg : message.to_s
59
- FSR::Log.debug "sending #{text}"
60
- message = "sendmsg\n%s\n" % text
61
- self.respond_to?(:send_data) ? send_data(message) : message
62
- end
63
-
64
-
65
- class SocketResponse
66
- attr_accessor :headers, :body, :data
67
- def initialize(data = "")
68
- @data = [data]
69
- @headers = {}
70
- if data.match(/\n$/)
71
- headers, @body = data.split("\n\n")
72
- headers.each_line do |line|
73
- key, value = line.split(":")
74
- @headers[key] = value.to_s.strip
75
- end
76
- end
77
- @body ||= ""
78
- FSR::Log.debug("New #{self.class.name} created: #{self}")
79
- end
80
-
81
- def <<(data)
82
- if data.match(/\n$/)
83
- @data.last.match(/\n$/) ? @data << data : @data.last << data
84
- extra_headers, more_body = @data.last.split("\n\n")
85
- extra_headers.each_line do |line|
86
- key, value = line.split(":")
87
- @headers[key] = value.to_s.strip
88
- end
89
- @body << more_body unless more_body.nil?
90
- else
91
- @data.last.match(/\n$/) ? @data << data : @data.last << data
92
- end
93
- self
94
- end
95
- end
96
-
97
- class Session < SocketResponse
98
- attr_accessor :replies
99
- def initialize(data = "")
100
- super
101
- @replies = []
102
- end
103
-
104
- def <<(data)
105
- if initiated?
106
- if @replies.empty? or @replies.last.complete?
107
- @replies << CommandReply.new(data)
108
- else
109
- @replies.last << data
110
- end
111
- else
112
- super
113
- end
114
- end
115
-
116
- def initiated?
117
- @headers.keys.include?("Control")
118
- end
119
-
120
- end
121
-
122
- class CommandReply < SocketResponse
123
- # Set this to true for now, fill it in when we know what completed a reply
124
- def complete?
125
- true
126
- end
127
- end
128
- end
129
-
130
- end
131
- end