oversip 1.2.1 → 1.3.0.dev1

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 (61) hide show
  1. data/README.md +28 -4
  2. data/bin/oversip +1 -1
  3. data/etc/proxies.conf +10 -0
  4. data/etc/server.rb +13 -9
  5. data/ext/utils/haproxy_protocol.c +0 -3
  6. data/ext/utils/outbound_utils.c +1 -1
  7. data/ext/utils/utils_ruby.c +0 -1
  8. data/ext/websocket_http_parser/ws_http_parser.c +940 -1903
  9. data/ext/websocket_http_parser/ws_http_parser.h +1 -0
  10. data/lib/oversip/config_validators.rb +2 -2
  11. data/lib/oversip/launcher.rb +275 -240
  12. data/lib/oversip/master_process.rb +7 -2
  13. data/lib/oversip/proxies_config.rb +8 -1
  14. data/lib/oversip/sip/client.rb +304 -0
  15. data/lib/oversip/sip/client_transaction.rb +31 -36
  16. data/lib/oversip/sip/core.rb +7 -4
  17. data/lib/oversip/sip/launcher.rb +30 -30
  18. data/lib/oversip/sip/listeners/connection.rb +4 -0
  19. data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +1 -0
  20. data/lib/oversip/sip/listeners/ipv4_tls_server.rb +1 -0
  21. data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +1 -0
  22. data/lib/oversip/sip/listeners/ipv4_udp_server.rb +1 -0
  23. data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +1 -0
  24. data/lib/oversip/sip/listeners/ipv6_tls_server.rb +1 -0
  25. data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +1 -0
  26. data/lib/oversip/sip/listeners/ipv6_udp_server.rb +1 -0
  27. data/lib/oversip/sip/listeners/tcp_client.rb +26 -0
  28. data/lib/oversip/sip/listeners/tcp_connection.rb +7 -1
  29. data/lib/oversip/sip/listeners/tcp_server.rb +1 -1
  30. data/lib/oversip/sip/listeners/tls_client.rb +28 -24
  31. data/lib/oversip/sip/listeners/tls_server.rb +25 -8
  32. data/lib/oversip/sip/listeners/tls_tunnel_connection.rb +1 -24
  33. data/lib/oversip/sip/message.rb +2 -2
  34. data/lib/oversip/sip/message_processor.rb +23 -13
  35. data/lib/oversip/sip/{grammar/name_addr.rb → name_addr.rb} +11 -0
  36. data/lib/oversip/sip/proxy.rb +53 -227
  37. data/lib/oversip/sip/request.rb +15 -11
  38. data/lib/oversip/sip/response.rb +3 -3
  39. data/lib/oversip/sip/rfc3263.rb +2 -3
  40. data/lib/oversip/sip/tags.rb +1 -1
  41. data/lib/oversip/sip/transport_manager.rb +6 -5
  42. data/lib/oversip/sip/uac.rb +93 -0
  43. data/lib/oversip/sip/uac_request.rb +82 -0
  44. data/lib/oversip/sip/{grammar/uri.rb → uri.rb} +22 -0
  45. data/lib/oversip/version.rb +3 -3
  46. data/lib/oversip/websocket/launcher.rb +25 -25
  47. data/lib/oversip/websocket/listeners/connection.rb +4 -0
  48. data/lib/oversip/websocket/listeners/ipv4_ws_server.rb +1 -0
  49. data/lib/oversip/websocket/listeners/ipv4_wss_server.rb +1 -0
  50. data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +1 -0
  51. data/lib/oversip/websocket/listeners/ipv6_ws_server.rb +1 -0
  52. data/lib/oversip/websocket/listeners/ipv6_wss_server.rb +1 -0
  53. data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +1 -0
  54. data/lib/oversip/websocket/listeners/ws_server.rb +55 -26
  55. data/lib/oversip/websocket/listeners/wss_server.rb +26 -9
  56. data/lib/oversip/websocket/listeners/wss_tunnel_server.rb +14 -11
  57. data/lib/oversip/websocket/ws_framing.rb +6 -2
  58. data/lib/oversip.rb +3 -1
  59. data/test/test_http_parser.rb +3 -3
  60. data/test/test_uri.rb +18 -12
  61. metadata +91 -77
@@ -0,0 +1,82 @@
1
+ module OverSIP::SIP
2
+
3
+ class UacRequest
4
+
5
+ DEFAULT_MAX_FORWARDS = "20"
6
+ DEFAULT_FROM = "\"OverSIP #{::OverSIP::VERSION}\" <sip:uac@oversip.net>"
7
+
8
+ attr_reader :sip_method, :ruri, :from, :from_tag, :to, :body, :call_id, :cseq
9
+ attr_reader :antiloop_id
10
+ attr_reader :routes # Always nil (needed for OverSIP::SIP::Tags.create_antiloop_id().
11
+ attr_accessor :tvars # Transaction variables (a hash).
12
+
13
+
14
+ def initialize data, extra_headers=[], body=nil
15
+ unless (@sip_method = data[:sip_method])
16
+ raise ::OverSIP::RuntimeError, "no data[:sip_method] given"
17
+ end
18
+ unless (@ruri = data[:ruri])
19
+ raise ::OverSIP::RuntimeError, "no data[:ruri] given"
20
+ end
21
+
22
+ @from = data[:from] || DEFAULT_FROM
23
+ @from_tag = data[:from_tag] || ::SecureRandom.hex(4)
24
+ @to = data[:to] || @ruri
25
+ @call_id = data[:call_id] || ::SecureRandom.hex(8)
26
+ @cseq = data[:cseq] || rand(1000)
27
+ @max_forwards = data[:max_forwards] || DEFAULT_MAX_FORWARDS
28
+
29
+ @headers = {}
30
+ @extra_headers = extra_headers
31
+
32
+ @body = body
33
+
34
+ @antiloop_id = ::OverSIP::SIP::Tags.create_antiloop_id(self)
35
+ end
36
+
37
+
38
+ def insert_header name, value
39
+ @headers[name] = value.to_s
40
+ end
41
+
42
+
43
+ def delete_header_top name
44
+ @headers.delete name
45
+ end
46
+
47
+
48
+ def to_s
49
+ # Let @ruri to be an String, an OverSIP::SIP::Uri or an OverSIP::SIP::NameAddr instance.
50
+ ruri = case @ruri
51
+ when ::String
52
+ @ruri
53
+ when ::OverSIP::SIP::Uri, ::OverSIP::SIP::NameAddr
54
+ @ruri.uri
55
+ end
56
+
57
+ msg = "#{@sip_method.to_s} #{ruri} SIP/2.0\r\n"
58
+
59
+ @headers.each do |name, value|
60
+ msg << name << ": #{value}\r\n"
61
+ end
62
+
63
+ msg << "From: #{@from.to_s};tag=#{@from_tag}\r\n"
64
+ msg << "To: #{@to.to_s}\r\n"
65
+ msg << "Call-ID: #{@call_id}\r\n"
66
+ msg << "CSeq: #{@cseq.to_s} #{@sip_method.to_s}\r\n"
67
+ msg << "Content-Length: #{@body ? @body.bytesize : "0"}\r\n"
68
+ msg << "Max-Forwards: #{@max_forwards.to_s}\r\n"
69
+ msg << HDR_USER_AGENT << CRLF
70
+
71
+ @extra_headers.each do |header|
72
+ msg << header << CRLF
73
+ end
74
+
75
+ msg << CRLF
76
+ msg << @body if @body
77
+ msg
78
+ end
79
+
80
+ end # class Request
81
+
82
+ end
@@ -3,6 +3,24 @@ module OverSIP::SIP
3
3
  class Uri
4
4
  attr_reader :scheme, :user, :host, :host_type, :port, :params, :transport_param, :phone_context_param, :ovid_param, :headers
5
5
 
6
+ def initialize scheme=:sip, user=nil, host=nil, port=nil
7
+ @scheme = scheme.to_sym
8
+ @user = user
9
+ @host = host
10
+ @host_type = ::OverSIP::Utils.ip_type(host) || :domain if host
11
+ @port = port
12
+
13
+ @uri_modified = true
14
+ end
15
+
16
+ def sip?
17
+ @scheme == :sip or @scheme == :sips
18
+ end
19
+
20
+ def tel?
21
+ @scheme == :tel
22
+ end
23
+
6
24
  def scheme= value
7
25
  return nil if unknown_scheme?
8
26
  @scheme = value
@@ -45,6 +63,10 @@ module OverSIP::SIP
45
63
  @params ||= {}
46
64
  end
47
65
 
66
+ def get_param k
67
+ params[k.to_s.downcase]
68
+ end
69
+
48
70
  def set_param k, v
49
71
  return nil if unknown_scheme?
50
72
  @params ||= {}
@@ -4,9 +4,9 @@ module OverSIP
4
4
 
5
5
  module Version
6
6
  MAJOR = 1
7
- MINOR = 2
8
- TINY = 1
9
- DEVEL = nil # Set to nil for stable releases.
7
+ MINOR = 3
8
+ TINY = 0
9
+ DEVEL = "dev1" # Set to nil for stable releases.
10
10
  end
11
11
 
12
12
  PROGRAM_NAME = "OverSIP"
@@ -2,7 +2,7 @@ module OverSIP::WebSocket
2
2
 
3
3
  module Launcher
4
4
 
5
- extend OverSIP::Logger
5
+ extend ::OverSIP::Logger
6
6
 
7
7
  IP_TYPE = {
8
8
  :ipv4 => "IPv4",
@@ -29,18 +29,18 @@ module OverSIP::WebSocket
29
29
  klass = case transport
30
30
  when :ws
31
31
  case ip_type
32
- when :ipv4 ; OverSIP::WebSocket::IPv4WsServer
33
- when :ipv6 ; OverSIP::WebSocket::IPv6WsServer
32
+ when :ipv4 ; ::OverSIP::WebSocket::IPv4WsServer
33
+ when :ipv6 ; ::OverSIP::WebSocket::IPv6WsServer
34
34
  end
35
35
  when :wss
36
36
  case ip_type
37
- when :ipv4 ; OverSIP::WebSocket::IPv4WssServer
38
- when :ipv6 ; OverSIP::WebSocket::IPv6WssServer
37
+ when :ipv4 ; ::OverSIP::WebSocket::IPv4WssServer
38
+ when :ipv6 ; ::OverSIP::WebSocket::IPv6WssServer
39
39
  end
40
40
  when :wss_tunnel
41
41
  case ip_type
42
- when :ipv4 ; OverSIP::WebSocket::IPv4WssTunnelServer
43
- when :ipv6 ; OverSIP::WebSocket::IPv6WssTunnelServer
42
+ when :ipv4 ; ::OverSIP::WebSocket::IPv4WssTunnelServer
43
+ when :ipv6 ; ::OverSIP::WebSocket::IPv6WssTunnelServer
44
44
  end
45
45
  end
46
46
 
@@ -49,33 +49,33 @@ module OverSIP::WebSocket
49
49
 
50
50
  case
51
51
 
52
- when klass == OverSIP::WebSocket::IPv4WsServer
52
+ when klass == ::OverSIP::WebSocket::IPv4WsServer
53
53
  klass.via_core = "SIP/2.0/WS #{uri_ip}:#{port}"
54
54
  klass.record_route = "<sip:#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
55
55
  klass.outbound_record_route_fragment = "@#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
56
56
  klass.outbound_path_fragment = "@#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
57
57
 
58
58
  if enabled
59
- EM.start_server(ip, port, klass) do |conn|
59
+ ::EM.start_server(ip, port, klass) do |conn|
60
60
  conn.post_connection
61
- conn.set_comm_inactivity_timeout 3600 # TODO
61
+ conn.set_comm_inactivity_timeout 300
62
62
  end
63
63
  end
64
64
 
65
- when klass == OverSIP::WebSocket::IPv6WsServer
65
+ when klass == ::OverSIP::WebSocket::IPv6WsServer
66
66
  klass.via_core = "SIP/2.0/WS #{uri_ip}:#{port}"
67
67
  klass.record_route = "<sip:#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
68
68
  klass.outbound_record_route_fragment = "@#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
69
69
  klass.outbound_path_fragment = "@#{uri_ip}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
70
70
 
71
71
  if enabled
72
- EM.start_server(ip, port, klass) do |conn|
72
+ ::EM.start_server(ip, port, klass) do |conn|
73
73
  conn.post_connection
74
- conn.set_comm_inactivity_timeout 3600 # TODO
74
+ conn.set_comm_inactivity_timeout 300
75
75
  end
76
76
  end
77
77
 
78
- when klass == OverSIP::WebSocket::IPv4WssServer
78
+ when klass == ::OverSIP::WebSocket::IPv4WssServer
79
79
  klass.via_core = "SIP/2.0/WSS #{uri_ip}:#{port}"
80
80
  rr_host = ::OverSIP.configuration[:sip][:record_route_hostname_tls_ipv4] || uri_ip
81
81
  klass.record_route = "<sip:#{rr_host}:#{port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
@@ -83,13 +83,13 @@ module OverSIP::WebSocket
83
83
  klass.outbound_path_fragment = "@#{rr_host}:#{port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
84
84
 
85
85
  if enabled
86
- EM.start_server(ip, port, klass) do |conn|
86
+ ::EM.start_server(ip, port, klass) do |conn|
87
87
  conn.post_connection
88
- conn.set_comm_inactivity_timeout 3600 # TODO
88
+ conn.set_comm_inactivity_timeout 300
89
89
  end
90
90
  end
91
91
 
92
- when klass == OverSIP::WebSocket::IPv6WssServer
92
+ when klass == ::OverSIP::WebSocket::IPv6WssServer
93
93
  klass.via_core = "SIP/2.0/WSS #{uri_ip}:#{port}"
94
94
  rr_host = ::OverSIP.configuration[:sip][:record_route_hostname_tls_ipv6] || uri_ip
95
95
  klass.record_route = "<sips:#{rr_host}:#{port};transport=ws;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
@@ -97,13 +97,13 @@ module OverSIP::WebSocket
97
97
  klass.outbound_path_fragment = "@#{rr_host}:#{port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
98
98
 
99
99
  if enabled
100
- EM.start_server(ip, port, klass) do |conn|
100
+ ::EM.start_server(ip, port, klass) do |conn|
101
101
  conn.post_connection
102
- conn.set_comm_inactivity_timeout 3600 # TODO
102
+ conn.set_comm_inactivity_timeout 300
103
103
  end
104
104
  end
105
105
 
106
- when klass == OverSIP::WebSocket::IPv4WssTunnelServer
106
+ when klass == ::OverSIP::WebSocket::IPv4WssTunnelServer
107
107
  klass.via_core = "SIP/2.0/WSS #{uri_virtual_ip}:#{virtual_port}"
108
108
  rr_host = ::OverSIP.configuration[:sip][:record_route_hostname_tls_ipv4] || uri_virtual_ip
109
109
  klass.record_route = "<sip:#{rr_host}:#{virtual_port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
@@ -111,13 +111,13 @@ module OverSIP::WebSocket
111
111
  klass.outbound_path_fragment = "@#{rr_host}:#{virtual_port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
112
112
 
113
113
  if enabled
114
- EM.start_server(ip, port, klass) do |conn|
114
+ ::EM.start_server(ip, port, klass) do |conn|
115
115
  conn.post_connection
116
- conn.set_comm_inactivity_timeout 3600 # TODO
116
+ conn.set_comm_inactivity_timeout 300
117
117
  end
118
118
  end
119
119
 
120
- when klass == OverSIP::WebSocket::IPv6WssTunnelServer
120
+ when klass == ::OverSIP::WebSocket::IPv6WssTunnelServer
121
121
  klass.via_core = "SIP/2.0/WSS #{uri_virtual_ip}:#{virtual_port}"
122
122
  rr_host = ::OverSIP.configuration[:sip][:record_route_hostname_tls_ipv6] || uri_virtual_ip
123
123
  klass.record_route = "<sip:#{rr_host}:#{virtual_port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid}>"
@@ -125,9 +125,9 @@ module OverSIP::WebSocket
125
125
  klass.outbound_path_fragment = "@#{rr_host}:#{virtual_port};transport=wss;lr;ovid=#{OverSIP::SIP::Tags.value_for_route_ovid};ob>"
126
126
 
127
127
  if enabled
128
- EM.start_server(ip, port, klass) do |conn|
128
+ ::EM.start_server(ip, port, klass) do |conn|
129
129
  conn.post_connection
130
- conn.set_comm_inactivity_timeout 3600 # TODO
130
+ conn.set_comm_inactivity_timeout 300
131
131
  end
132
132
  end
133
133
 
@@ -17,6 +17,10 @@ module OverSIP::WebSocket
17
17
  def reliable_transport_listener?
18
18
  @is_reliable_transport_listener
19
19
  end
20
+
21
+ def outbound_listener?
22
+ @is_outbound_listener
23
+ end
20
24
  end
21
25
 
22
26
 
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WS IPv4 server"
15
16
  def log_id
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WSS IPv4 server"
15
16
  def log_id
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WSS-Tunnel IPv4 server"
15
16
  def log_id
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WS IPv6 server"
15
16
  def log_id
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WSS IPv6 server"
15
16
  def log_id
@@ -10,6 +10,7 @@ module OverSIP::WebSocket
10
10
  @invite_client_transactions = {}
11
11
  @non_invite_client_transactions = {}
12
12
  @is_reliable_transport_listener = true
13
+ @is_outbound_listener = true
13
14
 
14
15
  LOG_ID = "SIP WSS-Tunnel IPv6 server"
15
16
  def log_id
@@ -85,12 +85,15 @@ module OverSIP::WebSocket
85
85
  end unless $!
86
86
 
87
87
  if @ws_established
88
- begin
89
- ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
90
- rescue ::Exception => e
91
- log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
92
- log_system_error e
93
- end
88
+ # Run OverSIP::WebSocketEvents.on_disconnection
89
+ ::Fiber.new do
90
+ begin
91
+ ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
92
+ rescue ::Exception => e
93
+ log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
94
+ log_system_error e
95
+ end
96
+ end.resume
94
97
  end unless $!
95
98
  end
96
99
 
@@ -98,6 +101,14 @@ module OverSIP::WebSocket
98
101
  def receive_data data
99
102
  @state == :ignore and return
100
103
  @buffer << data
104
+ @state == :waiting_for_on_client_tls_handshake and return
105
+ @state == :waiting_for_on_connection and return
106
+
107
+ process_received_data
108
+ end
109
+
110
+ def process_received_data
111
+ @state == :ignore and return
101
112
 
102
113
  while (case @state
103
114
  when :init
@@ -113,8 +124,9 @@ module OverSIP::WebSocket
113
124
  when :check_http_request
114
125
  check_http_request
115
126
 
116
- when :ws_connection_callback
117
- ws_connection_callback
127
+ when :on_connection_callback
128
+ do_on_connection_callback
129
+ false
118
130
 
119
131
  when :accept_ws_handshake
120
132
  accept_ws_handshake
@@ -164,6 +176,16 @@ module OverSIP::WebSocket
164
176
 
165
177
 
166
178
  def check_http_request
179
+ # Check OverSIP status.
180
+ unless ::OverSIP.status == :running
181
+ case ::OverSIP.status
182
+ when :loading
183
+ http_reject 500, "Server Still Loading", [ "Retry-After: 5" ]
184
+ when :terminating
185
+ http_reject 500, "Server is Being Stopped"
186
+ end
187
+ return false
188
+ end
167
189
 
168
190
  # HTTP method must be GET.
169
191
  if @http_request.http_method != :GET
@@ -215,29 +237,36 @@ module OverSIP::WebSocket
215
237
  end
216
238
  end
217
239
 
218
- @state = :ws_connection_callback
240
+ @state = :on_connection_callback
219
241
  true
220
242
  end
221
243
 
222
244
 
223
- def ws_connection_callback
224
- begin
225
- ::OverSIP::WebSocketEvents.on_connection self, @http_request
226
- rescue ::Exception => e
227
- log_system_error "error calling OverSIP::WebSocketEvents.on_connection() => 500:"
228
- log_system_error e
229
- http_reject 500
230
- return false
231
- end
245
+ def do_on_connection_callback
246
+ # Set the state to :waiting_for_on_connection so data received before
247
+ # user callback validation is just stored.
248
+ @state = :waiting_for_on_connection
232
249
 
233
- # The user provided callback could have reject the WS connection, so
234
- # check it not to reply a 101 after the reply sent by the user.
235
- if @state == :ws_connection_callback
236
- @state = :accept_ws_handshake
237
- true
238
- else
239
- false
240
- end
250
+ # Run OverSIP::WebSocketEvents.on_connection.
251
+ ::Fiber.new do
252
+ begin
253
+ log_system_debug "running OverSIP::WebSocketEvents.on_connection()..." if $oversip_debug
254
+ ::OverSIP::WebSocketEvents.on_connection self, @http_request
255
+ # If the user of the peer has not closed the connection then continue.
256
+ unless @local_closed or error?
257
+ @state = :accept_ws_handshake
258
+ # Call process_received_data() to process possible data received in the meanwhile.
259
+ process_received_data
260
+ else
261
+ log_system_debug "connection closed during OverSIP::WebSocketEvents.on_connection(), aborting" if $oversip_debug
262
+ end
263
+
264
+ rescue ::Exception => e
265
+ log_system_error "error calling OverSIP::WebSocketEvents.on_connection() => 500:"
266
+ log_system_error e
267
+ http_reject 500
268
+ end
269
+ end.resume
241
270
  end
242
271
 
243
272
 
@@ -43,7 +43,7 @@ module OverSIP::WebSocket
43
43
 
44
44
 
45
45
  def ssl_handshake_completed
46
- log_system_info "TLS connection established from " << remote_desc
46
+ log_system_debug ("TLS connection established from " << remote_desc) if $oversip_debug
47
47
 
48
48
  # @connected in WssServer means "TLS connection" rather than
49
49
  # just "TCP connection".
@@ -51,20 +51,37 @@ module OverSIP::WebSocket
51
51
  @timer_tls_handshake.cancel if @timer_tls_handshake
52
52
 
53
53
  if ::OverSIP::WebSocket.callback_on_client_tls_handshake
54
- begin
55
- ::OverSIP::WebSocketEvents.on_client_tls_handshake self, @client_pems
56
- rescue ::Exception => e
57
- log_system_error "error calling OverSIP::WebSocketEvents.on_client_tls_handshake():"
58
- log_system_error e
59
- close_connection
60
- end
54
+ # Set the state to :waiting_for_on_client_tls_handshake so data received after TLS handshake but before
55
+ # user callback validation is just stored.
56
+ @state = :waiting_for_on_client_tls_handshake
57
+
58
+ # Run OverSIP::WebSocketEvents.on_client_tls_handshake.
59
+ ::Fiber.new do
60
+ begin
61
+ log_system_debug "running OverSIP::SipWebSocketEvents.on_client_tls_handshake()..." if $oversip_debug
62
+ ::OverSIP::WebSocketEvents.on_client_tls_handshake self, @client_pems
63
+ # If the user of the peer has not closed the connection then continue.
64
+ unless @local_closed or error?
65
+ @state = :init
66
+ # Call process_received_data() to process possible data received in the meanwhile.
67
+ process_received_data
68
+ else
69
+ log_system_debug "connection closed during OverSIP::SipWebSocketEvents.on_client_tls_handshake(), aborting" if $oversip_debug
70
+ end
71
+
72
+ rescue ::Exception => e
73
+ log_system_error "error calling OverSIP::WebSocketEvents.on_client_tls_handshake():"
74
+ log_system_error e
75
+ close_connection
76
+ end
77
+ end.resume
61
78
  end
62
79
  end
63
80
 
64
81
 
65
82
  def unbind cause=nil
66
- super
67
83
  @timer_tls_handshake.cancel if @timer_tls_handshake
84
+ super
68
85
  end
69
86
 
70
87
  end
@@ -40,19 +40,21 @@ module OverSIP::WebSocket
40
40
  end unless $!
41
41
 
42
42
  if @ws_established
43
- begin
44
- ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
45
- rescue ::Exception => e
46
- log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
47
- log_system_error e
48
- end
43
+ # Run OverSIP::WebSocketEvents.on_disconnection
44
+ ::Fiber.new do
45
+ begin
46
+ ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
47
+ rescue ::Exception => e
48
+ log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
49
+ log_system_error e
50
+ end
51
+ end.resume
49
52
  end unless $!
50
53
  end
51
54
 
52
55
 
53
- def receive_data data
56
+ def process_received_data
54
57
  @state == :ignore and return
55
- @buffer << data
56
58
 
57
59
  while (case @state
58
60
  when :init
@@ -78,13 +80,14 @@ module OverSIP::WebSocket
78
80
  when :check_http_request
79
81
  check_http_request
80
82
 
81
- when :ws_connection_callback
82
- ws_connection_callback
83
+ when :on_connection_callback
84
+ do_on_connection_callback
85
+ false
83
86
 
84
87
  when :accept_ws_handshake
85
88
  accept_ws_handshake
86
89
 
87
- when :websocket_frames
90
+ when :websocket
88
91
  @ws_established = true
89
92
  return false if @buffer.size.zero?
90
93
  @ws_framing.receive_data
@@ -44,8 +44,12 @@ module OverSIP::WebSocket
44
44
 
45
45
  def do_keep_alive interval
46
46
  @keep_alive_timer = ::EM::PeriodicTimer.new(interval) do
47
- log_system_debug "sending keep-alive ping frame" if $oversip_debug
48
- @connection.send_data KEEPALIVE_PING_FRAME
47
+ unless @connection.error? # Ensure it.
48
+ log_system_debug "sending keep-alive ping frame" if $oversip_debug
49
+ @connection.send_data KEEPALIVE_PING_FRAME
50
+ else
51
+ @keep_alive_timer.cancel
52
+ end
49
53
  end
50
54
  end
51
55
 
data/lib/oversip.rb CHANGED
@@ -46,7 +46,9 @@ module OverSIP
46
46
  :configuration,
47
47
  :proxies,
48
48
  :tls_public_cert, :tls_private_cert,
49
- :stud_pids
49
+ :stud_pids,
50
+ :is_ready, # true, false
51
+ :status # :loading, :running, :terminating
50
52
 
51
53
  def master?
52
54
  @master_pid == $$
@@ -34,7 +34,7 @@ class TestHttpParser < OverSIPTest
34
34
 
35
35
  def test_parse_http_get
36
36
  parser, request = parse <<-END
37
- GET http://server.example.coM./chat?qwe=QWE&asd=#fragment HTTP/1.1\r
37
+ GET /chat?qwe=QWE&asd=#fragment HTTP/1.1\r
38
38
  Host: server.example.Com.\r
39
39
  Upgrade: WebSocket\r
40
40
  Connection: keep-Alive , Upgrade\r
@@ -51,11 +51,11 @@ END
51
51
  assert_equal request.http_method, :GET
52
52
  assert_equal request.http_version, "HTTP/1.1"
53
53
 
54
- assert_equal "/chat?qwe=QWE&asd=", request.uri
54
+ assert_equal "/chat?qwe=QWE&asd=#fragment", request.uri
55
55
  assert_equal "/chat", request.uri_path
56
56
  assert_equal "qwe=QWE&asd=", request.uri_query
57
57
  assert_equal "fragment", request.uri_fragment
58
- assert_equal request.uri_scheme, :http
58
+ assert_equal request.uri_scheme, nil
59
59
  assert_equal "server.example.com", request.host
60
60
  assert_nil request.port
61
61
 
data/test/test_uri.rb CHANGED
@@ -9,17 +9,17 @@ class TestUri < OverSIPTest
9
9
  full_uri = "sips:i%C3%B1aki@aliax.net:5060;transport=tcp;foo=123;baz?X-Header-1=qwe&X-Header-2=asd"
10
10
  aor = "sip:i%C3%B1aki@aliax.net"
11
11
 
12
- uri = ::OverSIP::SIP::Uri.new
13
- uri.instance_variable_set :@scheme, :sips
14
- uri.user = "iñaki"
15
- uri.host = "aliax.net"
16
- uri.host_type = :domain
17
- uri.port = 5060
12
+ uri = ::OverSIP::SIP::Uri.new :sips, "iñaki", "aliax.net", 5060
18
13
  uri.transport_param = :tcp
19
- uri.instance_variable_set :@params, {"transport"=>"tcp", "foo"=>"123", "baz"=>nil}
14
+ uri.set_param "FOO", "123"
15
+ uri.set_param "baz", nil
20
16
  uri.headers = "?X-Header-1=qwe&X-Header-2=asd"
21
17
 
18
+ assert_true uri.sip?
19
+ assert_false uri.tel?
20
+ assert_false uri.unknown_scheme?
22
21
  assert_equal "iñaki", uri.user
22
+ assert_equal "123", uri.get_param("Foo")
23
23
  assert_equal aor, uri.aor
24
24
  assert_equal full_uri, uri.to_s
25
25
  end
@@ -28,12 +28,15 @@ class TestUri < OverSIPTest
28
28
  full_uri = "tel:944991212;foo=bar;phone-context=+34"
29
29
  aor = "tel:944991212"
30
30
 
31
- uri = ::OverSIP::SIP::Uri.new
32
- uri.instance_variable_set :@scheme, :tel
33
- uri.user = "944991212"
34
- uri.instance_variable_set :@params, {"foo"=>"bar"}
31
+ uri = ::OverSIP::SIP::Uri.new :tel, "944991212"
32
+ uri.set_param "FOO", "bar"
35
33
  uri.phone_context_param = "+34"
36
34
 
35
+ assert_false uri.sip?
36
+ assert_true uri.tel?
37
+ assert_false uri.unknown_scheme?
38
+ assert_equal "944991212", uri.number
39
+ assert_equal "bar", uri.get_param("Foo")
37
40
  assert_equal aor, uri.aor
38
41
  assert_equal full_uri, uri.to_s
39
42
  end
@@ -42,9 +45,12 @@ class TestUri < OverSIPTest
42
45
  full_uri = "http://oversip.net/authors/"
43
46
  aor = nil
44
47
 
45
- uri = ::OverSIP::SIP::Uri.new
48
+ uri = ::OverSIP::SIP::Uri.allocate
46
49
  uri.instance_variable_set :@uri, full_uri
47
50
 
51
+ assert_false uri.sip?
52
+ assert_false uri.tel?
53
+ assert_true uri.unknown_scheme?
48
54
  assert_nil uri.aor
49
55
  assert_equal full_uri, uri.to_s
50
56
  end