sipatra 0.0.3 → 0.1.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.
- data/lib/sipatra/base.rb +89 -30
- data/lib/sipatra/helpers.rb +129 -104
- data/lib/sipatra/log4j-1.2.16.jar +0 -0
- data/lib/sipatra/sipatra-0.1.0-SNAPSHOT.jar +0 -0
- data/lib/sipatra/slf4j-api-1.6.1.jar +0 -0
- data/lib/sipatra/slf4j-log4j12-1.6.1.jar +0 -0
- data/spec/base_spec.rb +530 -0
- data/spec/classic_style_spec.rb +19 -0
- data/spec/helper.rb +46 -0
- data/spec/helpers_spec.rb +352 -0
- data/spec/sipatra_spec.rb +26 -0
- data/test/integration/sipapp/WEB-INF/sip.xml +14 -0
- data/test/integration/sipapp/WEB-INF/sipatra/application.rb +26 -0
- data/test/integration/sipatra.xml +9 -0
- data/test/integration/sipp/uac.xml +122 -0
- metadata +77 -63
- data/lib/sipatra/sipatra-0.0.3-SNAPSHOT.jar +0 -0
- data/lib/sipatra/slf4j-api-1.4.0.jar +0 -0
- data/lib/sipatra/slf4j-log4j12-1.4.0.jar +0 -0
data/lib/sipatra/base.rb
CHANGED
@@ -7,26 +7,21 @@ module Sipatra
|
|
7
7
|
|
8
8
|
class Base
|
9
9
|
include HelperMethods
|
10
|
-
attr_accessor :sip_factory, :context, :session, :
|
11
|
-
|
10
|
+
attr_accessor :sip_factory, :context, :session, :message, :params, :log
|
11
|
+
alias :request :message
|
12
|
+
alias :response :message
|
13
|
+
|
12
14
|
def initialize()
|
13
|
-
@params = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
15
|
+
@params = Hash.new { |hash,key| hash[key.to_s] if Symbol === key }
|
14
16
|
end
|
15
17
|
|
16
18
|
# called from Java to set SIP servlet bindings
|
17
19
|
def set_bindings(*args)
|
18
|
-
@context, @sip_factory, @session, @
|
20
|
+
@context, @sip_factory, @session, @message, @log = args
|
19
21
|
session.extend Sipatra::SessionExtension
|
20
|
-
|
22
|
+
message.extend Sipatra::MessageExtension
|
21
23
|
end
|
22
|
-
|
23
|
-
def session=(session)
|
24
|
-
@session = session
|
25
|
-
class << @session
|
26
|
-
include SessionExtension
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
24
|
+
|
30
25
|
# called to process a SIP request
|
31
26
|
def do_request
|
32
27
|
call! self.class.req_handlers
|
@@ -36,7 +31,17 @@ module Sipatra
|
|
36
31
|
def do_response
|
37
32
|
call! self.class.resp_handlers
|
38
33
|
end
|
39
|
-
|
34
|
+
|
35
|
+
# Access settings defined with Base.set.
|
36
|
+
def self.settings
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# Access settings defined with Base.set.
|
41
|
+
def settings
|
42
|
+
self.class.settings
|
43
|
+
end
|
44
|
+
|
40
45
|
# Exit the current block, halts any further processing
|
41
46
|
# of the message.
|
42
47
|
# TODO: handle a response (as param)
|
@@ -50,16 +55,28 @@ module Sipatra
|
|
50
55
|
end
|
51
56
|
|
52
57
|
def request?
|
53
|
-
!
|
58
|
+
!message.respond_to?(:getRequest)
|
54
59
|
end
|
55
60
|
|
56
61
|
def response?
|
57
|
-
|
62
|
+
message.respond_to?(:getRequest)
|
58
63
|
end
|
59
64
|
|
60
65
|
private
|
61
66
|
|
62
|
-
def
|
67
|
+
def session=(session)
|
68
|
+
@session = session
|
69
|
+
class << @session
|
70
|
+
include SessionExtension
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Retrieve the OUTBOUND_INTERFACES value from cipango.
|
75
|
+
def get_addresses
|
76
|
+
context.getAttribute('javax.servlet.sip.outboundInterfaces')
|
77
|
+
end
|
78
|
+
|
79
|
+
def message_type
|
63
80
|
response? ? :response : :request
|
64
81
|
end
|
65
82
|
|
@@ -75,7 +92,7 @@ module Sipatra
|
|
75
92
|
#clear (for multi usage)
|
76
93
|
@params.clear
|
77
94
|
if request?
|
78
|
-
match = arg.match
|
95
|
+
match = arg.match message.requestURI.to_s
|
79
96
|
if match
|
80
97
|
eval_options(opts)
|
81
98
|
if keys.any?
|
@@ -89,7 +106,7 @@ module Sipatra
|
|
89
106
|
return true
|
90
107
|
end
|
91
108
|
else
|
92
|
-
if ((arg == 0) or (arg ==
|
109
|
+
if ((arg == 0) or (arg == message.status))
|
93
110
|
eval_options(opts)
|
94
111
|
return true
|
95
112
|
end
|
@@ -117,7 +134,7 @@ module Sipatra
|
|
117
134
|
def call!(handlers)
|
118
135
|
filter! :before
|
119
136
|
catch(:halt) do
|
120
|
-
process_handler(handlers,
|
137
|
+
process_handler(handlers, message.method)
|
121
138
|
process_handler(handlers, "_")
|
122
139
|
end
|
123
140
|
ensure
|
@@ -131,7 +148,36 @@ module Sipatra
|
|
131
148
|
def configure(*envs, &block)
|
132
149
|
yield self if envs.empty? || envs.include?(environment.to_sym)
|
133
150
|
end
|
134
|
-
|
151
|
+
|
152
|
+
# Sets an option to the given value. If the value is a proc,
|
153
|
+
# the proc will be called every time the option is accessed.
|
154
|
+
def set(option, value=self, &block)
|
155
|
+
raise ArgumentError if block && value != self
|
156
|
+
value = block if block
|
157
|
+
if value.kind_of?(Proc)
|
158
|
+
metadef(option, &value)
|
159
|
+
metadef("#{option}?") { !!__send__(option) }
|
160
|
+
metadef("#{option}=") { |val| metadef(option, &Proc.new{val}) }
|
161
|
+
elsif value == self && option.respond_to?(:each)
|
162
|
+
option.each { |k,v| set(k, v) }
|
163
|
+
elsif respond_to?("#{option}=")
|
164
|
+
__send__ "#{option}=", value
|
165
|
+
else
|
166
|
+
set option, Proc.new{value}
|
167
|
+
end
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
# Same as calling `set :option, true` for each of the given options.
|
172
|
+
def enable(*opts)
|
173
|
+
opts.each { |key| set(key, true) }
|
174
|
+
end
|
175
|
+
|
176
|
+
# Same as calling `set :option, false` for each of the given options.
|
177
|
+
def disable(*opts)
|
178
|
+
opts.each { |key| set(key, false) }
|
179
|
+
end
|
180
|
+
|
135
181
|
# Methods defined in the block and/or in the module
|
136
182
|
# arguments available to handlers.
|
137
183
|
def helpers(*modules, &block)
|
@@ -182,12 +228,12 @@ module Sipatra
|
|
182
228
|
end
|
183
229
|
end
|
184
230
|
|
185
|
-
def before(
|
186
|
-
add_filter(:before,
|
231
|
+
def before(message_type = nil, &block)
|
232
|
+
add_filter(:before, message_type, &block)
|
187
233
|
end
|
188
234
|
|
189
|
-
def after(
|
190
|
-
add_filter(:after,
|
235
|
+
def after(message_type = nil, &block)
|
236
|
+
add_filter(:after, message_type, &block)
|
191
237
|
end
|
192
238
|
|
193
239
|
def reset!
|
@@ -210,10 +256,14 @@ module Sipatra
|
|
210
256
|
filters[:after]
|
211
257
|
end
|
212
258
|
|
259
|
+
def invoke_hook(name, *args)
|
260
|
+
extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
|
261
|
+
end
|
262
|
+
|
213
263
|
private
|
214
264
|
|
215
|
-
def add_filter(type,
|
216
|
-
if
|
265
|
+
def add_filter(type, msg_type = nil, &block)
|
266
|
+
if msg_type
|
217
267
|
add_filter(type) do
|
218
268
|
next unless msg_type == message_type
|
219
269
|
instance_eval(&block)
|
@@ -222,7 +272,15 @@ module Sipatra
|
|
222
272
|
filters[type] << block
|
223
273
|
end
|
224
274
|
end
|
225
|
-
|
275
|
+
|
276
|
+
def metadef(message, &block)
|
277
|
+
(class << self; self; end).
|
278
|
+
send :define_method, message, &block
|
279
|
+
if !['?', '='].include?(message.to_s[-1, 1])
|
280
|
+
invoke_hook(:option_set, self, message)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
226
284
|
# compiles a URI pattern
|
227
285
|
def compile_uri_pattern(uri)
|
228
286
|
keys = []
|
@@ -241,6 +299,7 @@ module Sipatra
|
|
241
299
|
end
|
242
300
|
|
243
301
|
def handler(method_name, verb, pattern, keys, options={}, &block)
|
302
|
+
raise ArgumentError, "A block should be given to a handler definition method" if block.nil?
|
244
303
|
define_method method_name, &block
|
245
304
|
unbound_method = instance_method(method_name)
|
246
305
|
block =
|
@@ -287,7 +346,7 @@ module Sipatra
|
|
287
346
|
delegate :ack, :bye, :cancel, :info, :invite, :message,
|
288
347
|
:notify, :options, :prack, :publish, :refer,
|
289
348
|
:register, :subscribe, :update,
|
290
|
-
:helpers, :configure,
|
349
|
+
:helpers, :configure, :settings, :set, :enable, :disable,
|
291
350
|
:before, :after, :request, :response
|
292
351
|
end
|
293
352
|
|
@@ -298,4 +357,4 @@ module Sipatra
|
|
298
357
|
def self.register_extension(*extensions, &block)
|
299
358
|
Application.register_extension(*extensions, &block)
|
300
359
|
end
|
301
|
-
end
|
360
|
+
end
|
data/lib/sipatra/helpers.rb
CHANGED
@@ -1,146 +1,146 @@
|
|
1
1
|
module Sipatra
|
2
2
|
STATUS_CODES_MAP = {
|
3
|
-
:accepted
|
4
|
-
:address_incomplete
|
5
|
-
:alternative_service
|
6
|
-
:ambiguous
|
7
|
-
:bad_event
|
8
|
-
:bad_extension
|
9
|
-
:bad_gateway
|
10
|
-
:bad_identity_info
|
11
|
-
:bad_request
|
12
|
-
:busy_everywhere
|
13
|
-
:busy_here
|
14
|
-
:call_being_forwarded
|
15
|
-
:call_leg_done
|
16
|
-
:call_queued
|
17
|
-
:conditional_request_failed
|
18
|
-
:decline
|
19
|
-
:does_not_exit_anywhere
|
20
|
-
:extension_required
|
21
|
-
:forbidden
|
22
|
-
:gone
|
23
|
-
:interval_too_brief
|
24
|
-
:invalid_identity_header
|
25
|
-
:loop_detected
|
26
|
-
:message_too_large
|
27
|
-
:method_not_allowed
|
28
|
-
:moved_permanently
|
29
|
-
:moved_temporarily
|
30
|
-
:multiple_choices
|
31
|
-
:not_acceptable
|
32
|
-
:not_acceptable_anywhere
|
33
|
-
:not_acceptable_here
|
34
|
-
:not_found
|
35
|
-
:not_implemented
|
36
|
-
:ok
|
37
|
-
:payment_required
|
38
|
-
:precondition_failure
|
39
|
-
:provide_referer_identity
|
3
|
+
:accepted => 202,
|
4
|
+
:address_incomplete => 484,
|
5
|
+
:alternative_service => 380,
|
6
|
+
:ambiguous => 485,
|
7
|
+
:bad_event => 489,
|
8
|
+
:bad_extension => 420,
|
9
|
+
:bad_gateway => 502,
|
10
|
+
:bad_identity_info => 436,
|
11
|
+
:bad_request => 400,
|
12
|
+
:busy_everywhere => 600,
|
13
|
+
:busy_here => 486,
|
14
|
+
:call_being_forwarded => 181,
|
15
|
+
:call_leg_done => 481,
|
16
|
+
:call_queued => 182,
|
17
|
+
:conditional_request_failed => 412,
|
18
|
+
:decline => 603,
|
19
|
+
:does_not_exit_anywhere => 604,
|
20
|
+
:extension_required => 421,
|
21
|
+
:forbidden => 403,
|
22
|
+
:gone => 410,
|
23
|
+
:interval_too_brief => 423,
|
24
|
+
:invalid_identity_header => 438,
|
25
|
+
:loop_detected => 482,
|
26
|
+
:message_too_large => 513,
|
27
|
+
:method_not_allowed => 405,
|
28
|
+
:moved_permanently => 301,
|
29
|
+
:moved_temporarily => 302,
|
30
|
+
:multiple_choices => 300,
|
31
|
+
:not_acceptable => 406,
|
32
|
+
:not_acceptable_anywhere => 606,
|
33
|
+
:not_acceptable_here => 488,
|
34
|
+
:not_found => 404,
|
35
|
+
:not_implemented => 501,
|
36
|
+
:ok => 200,
|
37
|
+
:payment_required => 402,
|
38
|
+
:precondition_failure => 580,
|
39
|
+
:provide_referer_identity => 429,
|
40
40
|
:proxy_authentication_required => 407,
|
41
|
-
:request_entity_too_large
|
42
|
-
:request_pending
|
43
|
-
:request_terminated
|
44
|
-
:request_timeout
|
45
|
-
:request_uri_too_long
|
46
|
-
:ringing
|
47
|
-
:security_agreement_required
|
48
|
-
:server_internal_error
|
49
|
-
:server_timeout
|
50
|
-
:service_unavailable
|
51
|
-
:session_interval_too_small
|
52
|
-
:session_progress
|
53
|
-
:temporarily_unavailable
|
54
|
-
:too_many_hops
|
55
|
-
:trying
|
56
|
-
:unauthorized
|
57
|
-
:undecipherable
|
58
|
-
:unsupported_certificate
|
59
|
-
:unsupported_media_type
|
60
|
-
:unsupported_uri_scheme
|
61
|
-
:use_identity_header
|
62
|
-
:use_proxy
|
63
|
-
:version_not_supported
|
41
|
+
:request_entity_too_large => 413,
|
42
|
+
:request_pending => 491,
|
43
|
+
:request_terminated => 487,
|
44
|
+
:request_timeout => 408,
|
45
|
+
:request_uri_too_long => 414,
|
46
|
+
:ringing => 180,
|
47
|
+
:security_agreement_required => 494,
|
48
|
+
:server_internal_error => 500,
|
49
|
+
:server_timeout => 504,
|
50
|
+
:service_unavailable => 503,
|
51
|
+
:session_interval_too_small => 422,
|
52
|
+
:session_progress => 183,
|
53
|
+
:temporarily_unavailable => 480,
|
54
|
+
:too_many_hops => 483,
|
55
|
+
:trying => 100,
|
56
|
+
:unauthorized => 401,
|
57
|
+
:undecipherable => 493,
|
58
|
+
:unsupported_certificate => 437,
|
59
|
+
:unsupported_media_type => 415,
|
60
|
+
:unsupported_uri_scheme => 416,
|
61
|
+
:use_identity_header => 428,
|
62
|
+
:use_proxy => 305,
|
63
|
+
:version_not_supported => 505,
|
64
64
|
}
|
65
|
-
|
65
|
+
|
66
66
|
class HeadersWrapper
|
67
67
|
def initialize(app, plural = false, address = false)
|
68
68
|
@app = app
|
69
69
|
method_definitions = <<-RUBY
|
70
70
|
def [](name)
|
71
|
-
@app.
|
71
|
+
@app.message.get#{address ? "Address" : ""}Header#{plural ? "s" : ""}(name.to_s)#{plural ? ".to_a" : ""}
|
72
72
|
end
|
73
73
|
RUBY
|
74
74
|
if plural
|
75
75
|
method_definitions += <<-RUBY
|
76
76
|
def []=(name, values)
|
77
77
|
name = name.to_s
|
78
|
-
@app.
|
78
|
+
@app.message.removeHeader(name)
|
79
79
|
if !values.nil?
|
80
|
-
values.each do |value|
|
81
|
-
@app.
|
80
|
+
values.each do |value|
|
81
|
+
@app.message.add#{address ? "Address" : ""}Header(name, value#{address ? ", true" : ".to_s"})
|
82
82
|
end
|
83
83
|
end
|
84
|
-
end
|
84
|
+
end
|
85
85
|
RUBY
|
86
86
|
else
|
87
87
|
method_definitions += <<-RUBY
|
88
88
|
def []=(name, value)
|
89
89
|
if !value.nil?
|
90
|
-
@app.
|
90
|
+
@app.message.set#{address ? "Address" : ""}Header(name.to_s, value)
|
91
91
|
else
|
92
|
-
@app.
|
92
|
+
@app.message.removeHeader(name.to_s)
|
93
93
|
end
|
94
|
-
end
|
94
|
+
end
|
95
95
|
RUBY
|
96
96
|
end
|
97
97
|
class << self; self; end.class_eval method_definitions
|
98
|
-
end
|
98
|
+
end
|
99
99
|
end
|
100
|
-
|
101
|
-
module HelperMethods
|
100
|
+
|
101
|
+
module HelperMethods
|
102
102
|
def proxy(*args)
|
103
103
|
uri = args.shift
|
104
104
|
uri, options = nil, uri if uri.kind_of? Hash
|
105
105
|
options ||= args.shift || {}
|
106
106
|
if uri.nil?
|
107
|
-
uri =
|
107
|
+
uri = message.requestURI
|
108
108
|
else
|
109
109
|
uri = sip_factory.createURI(uri)
|
110
110
|
end
|
111
|
-
proxy =
|
111
|
+
proxy = message.proxy
|
112
112
|
proxy.setRecordRoute(options[:record_route]) if options.has_key? :record_route
|
113
113
|
proxy.proxyTo(uri)
|
114
|
-
end
|
115
|
-
|
114
|
+
end
|
115
|
+
|
116
116
|
def header
|
117
117
|
@header_wrapper ||= HeadersWrapper::new(self)
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
def headers
|
121
121
|
@headers_wrapper ||= HeadersWrapper::new(self, true)
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def address_header
|
125
125
|
@address_header_wrapper ||= HeadersWrapper::new(self, false, true)
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
def address_headers
|
129
129
|
@address_headers_wrapper ||= HeadersWrapper::new(self, true, true)
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
def add_header(name, value)
|
133
|
-
|
133
|
+
message.addHeader(name.to_s, value)
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
def add_address_header(name, value, first = true)
|
137
|
-
|
137
|
+
message.addAddressHeader(name.to_s, value, first)
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
def header?(name)
|
141
|
-
!
|
141
|
+
!message.getHeader(name.to_s).nil?
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
def modify_header(header_name, pattern = nil, new_value = nil)
|
145
145
|
#FIXME: "JAVA" Code
|
146
146
|
if pattern
|
@@ -154,46 +154,71 @@ module Sipatra
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
157
|
-
|
157
|
+
|
158
158
|
def remove_header(name)
|
159
|
-
|
159
|
+
message.removeHeader(name.to_s)
|
160
|
+
end
|
161
|
+
|
162
|
+
class ResponseEnvironment
|
163
|
+
instance_methods.each do |m|
|
164
|
+
undef_method m unless m.to_s =~ /^__|respond_to?|instance_eval/
|
165
|
+
end
|
166
|
+
|
167
|
+
attr_reader :response, :app
|
168
|
+
alias :message :response
|
169
|
+
|
170
|
+
def initialize(app, response)
|
171
|
+
@app, @response = app, response
|
172
|
+
end
|
173
|
+
|
174
|
+
# TODO: complete with some direct access to app ?
|
160
175
|
end
|
161
|
-
|
162
|
-
def send_response(status, *args)
|
176
|
+
|
177
|
+
def send_response(status, *args, &block)
|
163
178
|
create_args = [convert_status_code(status)]
|
164
179
|
create_args << args.shift unless args.empty? || args.first.kind_of?(Hash)
|
165
|
-
response =
|
180
|
+
response = message.createResponse(*create_args)
|
166
181
|
unless args.empty?
|
167
182
|
raise ArgumentError, "last argument should be a Hash" unless args.first.kind_of? Hash
|
168
183
|
args.first.each_pair do |name, value|
|
169
184
|
response.addHeader(name.to_s, value.to_s)
|
170
185
|
end
|
171
186
|
end
|
172
|
-
|
173
|
-
|
187
|
+
unless block.nil?
|
188
|
+
ResponseEnvironment::new(self, response).instance_eval(&block)
|
174
189
|
end
|
175
190
|
response.send
|
176
191
|
end
|
177
|
-
|
192
|
+
|
178
193
|
def create_address(addr, options = {})
|
179
194
|
addr = addr.to_s # TODO: Handle URI instances
|
180
195
|
address = sip_factory.createAddress(addr)
|
181
196
|
address.setExpires(options[:expires]) if options.has_key? :expires
|
182
197
|
address.setDisplayName(options[:display_name]) if options.has_key? :display_name
|
183
|
-
|
184
|
-
address
|
198
|
+
|
199
|
+
address
|
185
200
|
end
|
186
|
-
|
201
|
+
|
202
|
+
def create_uri(value, params = {})
|
203
|
+
uri = sip_factory.createURI(value)
|
204
|
+
if uri.respond_to? :setLrParam
|
205
|
+
uri.setLrParam(params.has_key?(:lr) ? params.delete(:lr) : true)
|
206
|
+
end
|
207
|
+
params.each { |name, value| uri.setParameter(name.to_s, value.to_s) }
|
208
|
+
uri
|
209
|
+
end
|
210
|
+
|
187
211
|
def push_route(route)
|
188
|
-
|
189
|
-
end
|
190
|
-
|
212
|
+
message.pushRoute(sip_factory.createAddress(route))
|
213
|
+
end
|
214
|
+
|
191
215
|
private
|
192
|
-
|
216
|
+
|
193
217
|
def convert_status_code(symbol_or_int)
|
194
218
|
case symbol_or_int
|
195
|
-
when Integer
|
196
|
-
|
219
|
+
when Integer
|
220
|
+
return symbol_or_int
|
221
|
+
when Symbol
|
197
222
|
code = STATUS_CODES_MAP[symbol_or_int]
|
198
223
|
raise ArgumentError, "Unknown status code symbol: '#{symbol_or_int}'" unless code
|
199
224
|
code
|
@@ -202,4 +227,4 @@ module Sipatra
|
|
202
227
|
end
|
203
228
|
end
|
204
229
|
end
|
205
|
-
end
|
230
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|