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 CHANGED
@@ -7,26 +7,21 @@ module Sipatra
7
7
 
8
8
  class Base
9
9
  include HelperMethods
10
- attr_accessor :sip_factory, :context, :session, :msg, :params
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, @msg = args
20
+ @context, @sip_factory, @session, @message, @log = args
19
21
  session.extend Sipatra::SessionExtension
20
- msg.extend Sipatra::MessageExtension
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
- !msg.respond_to?(:getRequest)
58
+ !message.respond_to?(:getRequest)
54
59
  end
55
60
 
56
61
  def response?
57
- msg.respond_to?(:getRequest)
62
+ message.respond_to?(:getRequest)
58
63
  end
59
64
 
60
65
  private
61
66
 
62
- def msg_type
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 msg.requestURI.to_s
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 == msg.status))
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, msg.method)
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(msg_type = nil, &block)
186
- add_filter(:before, msg_type, &block)
231
+ def before(message_type = nil, &block)
232
+ add_filter(:before, message_type, &block)
187
233
  end
188
234
 
189
- def after(msg_type = nil, &block)
190
- add_filter(:after, msg_type, &block)
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, message_type = nil, &block)
216
- if message_type
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
@@ -1,146 +1,146 @@
1
1
  module Sipatra
2
2
  STATUS_CODES_MAP = {
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,
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 => 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,
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.msg.get#{address ? "Address" : ""}Header#{plural ? "s" : ""}(name.to_s)#{plural ? ".to_a" : ""}
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.msg.removeHeader(name)
78
+ @app.message.removeHeader(name)
79
79
  if !values.nil?
80
- values.each do |value|
81
- @app.msg.add#{address ? "Address" : ""}Header(name, value#{address ? ", true" : ".to_s"})
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.msg.set#{address ? "Address" : ""}Header(name.to_s, value)
90
+ @app.message.set#{address ? "Address" : ""}Header(name.to_s, value)
91
91
  else
92
- @app.msg.removeHeader(name.to_s)
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 = msg.requestURI
107
+ uri = message.requestURI
108
108
  else
109
109
  uri = sip_factory.createURI(uri)
110
110
  end
111
- proxy = msg.getProxy()
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
- msg.addHeader(name.to_s, value)
133
+ message.addHeader(name.to_s, value)
134
134
  end
135
-
135
+
136
136
  def add_address_header(name, value, first = true)
137
- msg.addAddressHeader(name.to_s, value, first)
137
+ message.addAddressHeader(name.to_s, value, first)
138
138
  end
139
-
139
+
140
140
  def header?(name)
141
- !msg.getHeader(name.to_s).nil?
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
- msg.removeHeader(name.to_s)
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 = msg.createResponse(*create_args)
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
- if block_given?
173
- yield response
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
- msg.pushRoute(sip_factory.createAddress(route))
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: return symbol_or_int
196
- when Symbol:
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