freeswitcher 0.1.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +4 -3
- data/CHANGELOG +123 -0
- data/MANIFEST +3 -9
- data/README +57 -60
- data/Rakefile +4 -4
- data/examples/outbound_event_socket.rb +2 -5
- data/freeswitcher.gemspec +62 -65
- data/lib/fsr/app.rb +1 -3
- data/lib/fsr/app/answer.rb +2 -0
- data/lib/fsr/app/play_and_get_digits.rb +11 -1
- data/lib/fsr/app/read.rb +12 -2
- data/lib/fsr/app/uuid_getvar.rb +13 -2
- data/lib/fsr/app/uuid_setvar.rb +11 -1
- data/lib/fsr/cmd.rb +22 -4
- data/lib/fsr/cmd/originate.rb +23 -6
- data/lib/fsr/command_socket.rb +1 -1
- data/lib/fsr/listener/inbound.rb +19 -10
- data/lib/fsr/listener/outbound.rb +75 -18
- data/lib/fsr/version.rb +1 -1
- data/spec/fsr/app/answer.rb +12 -0
- data/spec/fsr/app/fs_break.rb +12 -0
- data/spec/fsr/app/fs_sleep.rb +12 -0
- data/spec/fsr/cmd/originate.rb +32 -0
- metadata +63 -84
- data/lib/fsr/listener/outbound.rb.orig +0 -131
@@ -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
|
data/spec/fsr/cmd/originate.rb
CHANGED
@@ -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.
|
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-
|
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 ------------
|
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
|
-
|
146
|
-
|
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
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
165
|
+
#!/usr/bin/ruby
|
166
|
+
require 'pp'
|
167
|
+
require 'fsr'
|
168
|
+
require "fsr/listener/inbound"
|
194
169
|
|
195
|
-
|
196
|
-
|
197
|
-
|
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
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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
|
-
|
207
|
-
|
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
|
-
|
211
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
192
|
+
#!/usr/bin/ruby
|
193
|
+
require 'pp'
|
194
|
+
require 'fsr'
|
195
|
+
require "fsr/listener/inbound"
|
220
196
|
|
221
197
|
|
222
|
-
|
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
|
-
|
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
|
-
|
238
|
-
|
213
|
+
irb(main):001:0> require 'fsr'
|
214
|
+
=> true
|
239
215
|
|
240
|
-
|
241
|
-
|
216
|
+
irb(main):002:0> FSR.load_all_commands
|
217
|
+
=> [:sofia, :originate]
|
242
218
|
|
243
|
-
|
244
|
-
|
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
|
-
|
247
|
-
|
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
|