quaff 0.5.1 → 0.5.2

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.
Files changed (3) hide show
  1. data/lib/call.rb +41 -21
  2. data/lib/sip_parser.rb +169 -0
  3. metadata +18 -2
data/lib/call.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # -*- coding: us-ascii -*-
2
+ require 'securerandom'
2
3
  require_relative './utils.rb'
3
4
  require_relative './sources.rb'
4
5
  require_relative './auth.rb'
@@ -32,18 +33,11 @@ class Call
32
33
  destination=nil,
33
34
  target_uri=nil)
34
35
  @cxn = cxn
35
- @cseq_number = 1
36
- change_cid cid
37
- @uri = uri
36
+ setdest(destination, recv_from_this: true) if destination
38
37
  @retrans = nil
39
38
  @t1, @t2 = 0.5, 32
40
- @last_From = "<#{uri}>"
41
- update_branch
42
- @last_To = "<#{target_uri}>"
43
- setdest(destination, recv_from_this: true) if destination
44
- set_callee target_uri if target_uri
45
- @routeset = []
46
39
  @instance_id = instance_id
40
+ set_default_headers cid, uri, target_uri
47
41
  end
48
42
 
49
43
  def change_cid cid
@@ -87,11 +81,24 @@ class Call
87
81
  rescue
88
82
  raise "#{ @uri } timed out waiting for #{ method }"
89
83
  end
84
+
90
85
  unless msg.type == :request \
91
86
  and Regexp.new(method) =~ msg.method
92
87
  raise((msg.to_s || "Message is nil!"))
93
88
  end
89
+
90
+ unless @has_To_tag
91
+ @has_To_tag = true
92
+ tospec = ToSpec.new
93
+ tospec.parse(msg.header("To"))
94
+ tospec.params['tag'] = generate_random_tag
95
+ @last_To = tospec.to_s
96
+ @last_From = msg.header("From")
97
+ end
98
+
94
99
  if dialog_creating
100
+ @in_dialog = true
101
+
95
102
  set_callee msg.first_header("Contact")
96
103
  unless msg.all_headers("Record-Route").nil?
97
104
  @routeset = msg.all_headers("Record-Route")
@@ -110,12 +117,20 @@ class Call
110
117
  and Regexp.new(code) =~ msg.status_code
111
118
  raise "Expected #{ code}, got #{msg.status_code || msg}"
112
119
  end
120
+
113
121
  if dialog_creating
122
+ @in_dialog = true
114
123
  set_callee msg.first_header("Contact")
115
124
  unless msg.all_headers("Record-Route").nil?
116
125
  @routeset = msg.all_headers("Record-Route").reverse
117
126
  end
118
127
  end
128
+
129
+ if @in_dialog
130
+ @has_To_tag = true
131
+ @last_To = msg.header("To")
132
+ end
133
+
119
134
  msg
120
135
  end
121
136
 
@@ -138,21 +153,11 @@ class Call
138
153
  @cxn.mark_call_dead @cid
139
154
  end
140
155
 
141
- def clear_tag str
142
- str
143
- end
144
-
145
156
  def assoc_with_msg(msg)
146
157
  @last_Via = msg.all_headers("Via")
147
158
  @last_CSeq = CSeq.new(msg.header("CSeq"))
148
159
  end
149
160
 
150
- def clone_details other_message
151
- @headers['To'] = [clear_tag(other_message.header("To"))]
152
- @headers['From'] = [clear_tag(other_message.header("From"))]
153
- @headers['Route'] = [other_message.header("Route")]
154
- end
155
-
156
161
  def get_next_hop header
157
162
  /<sip:(.+@)?(.+):(\d+);(.*)>/ =~ header
158
163
  sock = TCPSocket.new $2, $3
@@ -164,8 +169,6 @@ class Call
164
169
  msg = @cxn.get_new_message @cid
165
170
  @retrans = nil
166
171
  @src = msg.source
167
- @last_To = msg.header("To")
168
- @last_From = msg.header("From")
169
172
  set_callee msg.header("From")
170
173
  @last_Via = msg.headers["Via"]
171
174
  @last_CSeq = CSeq.new(msg.header("CSeq"))
@@ -233,5 +236,22 @@ class Call
233
236
  end
234
237
  end
235
238
 
239
+ def set_default_headers cid, uri, target_uri
240
+ @cseq_number = 1
241
+ change_cid cid
242
+ @uri = uri
243
+ @last_From = "<#{uri}>;tag=" + generate_random_tag
244
+ @in_dialog = false
245
+ @has_To_tag = false
246
+ update_branch
247
+ @last_To = "<#{target_uri}>"
248
+ set_callee target_uri if target_uri
249
+ @routeset = []
250
+ end
251
+
252
+ def generate_random_tag
253
+ SecureRandom::base64
254
+ end
255
+
236
256
  end
237
257
  end
data/lib/sip_parser.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- coding: us-ascii -*-
2
2
  require 'digest/md5'
3
+ require 'abnf'
3
4
  require_relative './message.rb'
4
5
 
5
6
  module Quaff
@@ -98,4 +99,172 @@ module Quaff
98
99
 
99
100
  end
100
101
 
102
+ class ABNFSipParser
103
+ include ABNF
104
+
105
+ # Rules
106
+
107
+ def alphanum
108
+ Alternate.new(Alpha.new, Digit.new)
109
+ end
110
+
111
+ def reserved
112
+ AlternateChars.new(";/?:@&=+$,")
113
+ end
114
+
115
+ def mark
116
+ AlternateChars.new("-_.!~*'()")
117
+ end
118
+
119
+ def unreserved
120
+ Alternate.new(alphanum, mark)
121
+ end
122
+
123
+ def escaped
124
+ Concat.new(Char.new(?%), HexDigit.new, HexDigit.new)
125
+ end
126
+
127
+ def user_unreserved
128
+ AlternateChars.new "&=+$,;?/"
129
+ end
130
+
131
+ def user
132
+ Repetition.new([:at_least, 1], Alternate.new(unreserved, escaped, user_unreserved))
133
+ end
134
+
135
+ def userinfo
136
+ Concat.new(user, Char.new(?@))
137
+ end
138
+
139
+ def hostname
140
+ Repetition.new([:at_least, 1], Alternate.new(alphanum, Char.new(?.)))
141
+ end
142
+
143
+ def port
144
+ Repetition.new([:at_least, 1], Digit.new)
145
+ end
146
+
147
+ def hostport
148
+ Concat.new(hostname, OptionalConcat.new(Char.new(?:), port))
149
+ end
150
+
151
+ def paramchar
152
+ paramunreserved = AlternateChars.new("[]/:&+%")
153
+ Alternate.new(paramunreserved, unreserved, escaped)
154
+ end
155
+
156
+ def pname
157
+ Repetition.new([:at_least, 1], paramchar)
158
+ end
159
+
160
+ def pvalue
161
+ Repetition.new([:at_least, 1], paramchar)
162
+ end
163
+
164
+
165
+ def param
166
+ Concat.new(pname, OptionalConcat.new(Char.new(?=), pvalue))
167
+ end
168
+
169
+ def uri_parameters
170
+ Repetition.new(:any,
171
+ Concat.new(Char.new(?;), param))
172
+ end
173
+
174
+ def sip_uri
175
+ Concat.new(Literal.new("sip:"),
176
+ Optional.new(userinfo),
177
+ hostport,
178
+ uri_parameters)
179
+ end
180
+
181
+ def addr_spec
182
+ sip_uri
183
+ end
184
+
185
+ def wsp
186
+ Alternate.new(Char.new(" "), Char.new("\t"))
187
+ end
188
+
189
+ def lws
190
+ Concat.new(OptionalConcat.new(Repetition.new([:at_least, 1], wsp), Literal.new("\r\n")), Repetition.new([:at_least, 1], wsp))
191
+ end
192
+
193
+ def sws
194
+ Optional.new(lws)
195
+ end
196
+
197
+ def raquot
198
+ Concat.new(Char.new(">"), sws)
199
+ end
200
+
201
+ def laquot
202
+ Concat.new(sws, Char.new("<"))
203
+ end
204
+
205
+ def display_name
206
+ Repetition.new(:any, Alternate.new(alphanum, wsp, Char.new(?")))
207
+ end
208
+
209
+ def name_addr
210
+ Concat.new(display_name, laquot, addr_spec, raquot)
211
+ end
212
+
213
+ def from_param
214
+ param
215
+ end
216
+
217
+ def from_spec
218
+ Concat.new(Alternate.new(addr_spec, name_addr), Repetition.new(:any, Concat.new(Char.new(?;), from_param)))
219
+ end
220
+
221
+ def to_param
222
+ param
223
+ end
224
+
225
+ def to_spec
226
+ Concat.new(Alternate.new(addr_spec, name_addr), Repetition.new(:any, Concat.new(Char.new(?;), from_param)))
227
+ end
228
+ end
229
+
230
+ class ToSpec < ABNFSipParser
231
+ attr_accessor :params, :uri, :displayname, :is_nameaddr
232
+ def initialize
233
+ super
234
+ @params = {}
235
+ @uri = nil
236
+ @displayname = nil
237
+ @is_nameaddr = false
238
+ end
239
+
240
+ def to_param
241
+ super.set_block {|p| k, v = p.split("="); @params[k] = if v.nil? then true else v end}
242
+ end
243
+
244
+ def display_name
245
+ super.set_block {|p| @display_name = p; @is_nameaddr = true}
246
+ end
247
+
248
+ def addr_spec
249
+ super.set_block {|p| @uri = p}
250
+ end
251
+
252
+ def parse(str)
253
+ if to_spec.match(Stream.new(str))
254
+ true
255
+ else
256
+ false
257
+ end
258
+ end
259
+
260
+ def to_s
261
+ paramstr = @params.collect {|k, v| if (v == true) then ";#{k}" else ";#{k}=#{v}" end}.join("")
262
+ if @is_nameaddr
263
+ puts "#{@displayname} <#{@uri}>#{paramstr}"
264
+ else
265
+ puts "#{@uri}#{paramstr}"
266
+ end
267
+ end
268
+ end
269
+
101
270
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quaff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-12 00:00:00.000000000 Z
12
+ date: 2014-03-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.1.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: abnf-parsing
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.0
46
62
  description: A Ruby library for writing SIP test scenarios
47
63
  email: rkd@rkd.me.uk
48
64
  executables: []