Class: OverSIP::WebSocket::WsSipApp

Inherits:
Object
  • Object
show all
Includes:
Logger, SIP::MessageProcessor
Defined in:
lib/oversip/websocket/ws_sip_app.rb

Constant Summary collapse

LOG_ID =
"WsSipApp"

Constants included from SIP::MessageProcessor

SIP::MessageProcessor::MSG_TYPE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logger

close, fg_system_msg2str, init_logger_mq, load_methods, syslog_system_msg2str, syslog_user_msg2str

Constructor Details

#initialize(connection, ws_framing) ⇒ WsSipApp

Returns a new instance of WsSipApp.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/oversip/websocket/ws_sip_app.rb', line 20

def initialize connection, ws_framing
  @connection = connection
  @ws_framing = ws_framing
  @ws_message = ::IO::Buffer.new

  # Mantain WebSocket keepalive.
  @ws_framing.do_keep_alive @@ws_keepalive_interval  if @@ws_keepalive_interval

  # WebSocket is message boundary so we just need a SIP parser instance.
  @@parser ||= ::OverSIP::SIP::MessageParser.new
  @parser = @@parser
end

Class Method Details

.class_initObject



8
9
10
11
# File 'lib/oversip/websocket/ws_sip_app.rb', line 8

def self.class_init
  @@max_message_size = ::OverSIP.configuration[:websocket][:max_ws_message_size]
  @@ws_keepalive_interval = ::OverSIP.configuration[:websocket][:ws_keepalive_interval]
end

Instance Method Details

#log_idObject



15
16
17
# File 'lib/oversip/websocket/ws_sip_app.rb', line 15

def log_id
  LOG_ID
end

#message_done(type) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/oversip/websocket/ws_sip_app.rb', line 44

def message_done type
  log_system_debug "received WS message: type=#{type}, length=#{@ws_message.size}"  if $oversip_debug

  # Better to encode it as BINARY (to later extract the body).
  process_sip_message @ws_message.to_str.force_encoding ::Encoding::BINARY

  @ws_message.clear
  true
end

#process_sip_message(ws_message) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/oversip/websocket/ws_sip_app.rb', line 55

def process_sip_message ws_message
  # Just a single SIP message allowed per WS message.
  @parser.reset

  unless parser_nbytes = @parser.execute(ws_message, 0)
    if wrong_message = @parser.parsed
      log_system_warn "SIP parsing error for #{MSG_TYPE[wrong_message.class]}: \"#{@parser.error}\""
    else
      log_system_warn "SIP parsing error: \"#{@parser.error}\""
    end
    @connection.close 4000, "SIP message parsing error"
    return
  end

  unless @parser.finished?
    log_system_warn "SIP parsing error: message not completed"

    @connection.close 4001, "SIP message incomplete"
    return
  end

  # At this point we've got a SIP::Request, SIP::Response or :outbound_keepalive symbol.
  @msg = @parser.parsed

  # Received data is a SIP Outbound keealive (double CRLF). Reply with single CRLF.
  if @msg == :outbound_keepalive
    log_system_debug "Outbound keepalive received, replying single CRLF"  if $oversip_debug
    @ws_framing.send_text_frame(CRLF)
    return
  end

  @parser.post_parsing

  @msg.connection = @connection
  @msg.transport = @connection.class.transport
  @msg.source_ip = @connection.remote_ip
  @msg.source_port = @connection.remote_port
  @msg.source_ip_type = @connection.remote_ip_type

  return  unless valid_message? @parser
  # TODO: Make it configurable:
  #add_via_received_rport  if @msg.request?
  return  unless check_via_branch

  # Get the body.
  if parser_nbytes != ws_message.bytesize
    @msg.body = ws_message[parser_nbytes..-1].force_encoding(::Encoding::UTF_8)

    if @msg.content_length and @msg.content_length != @msg.body.bytesize
      log_system_warn "SIP message body size (#{@msg.body.bytesize}) does not match Content-Length (#{@msg.content_length.inspect}), ignoring message"
      @connection.close 4002, "SIP message body size does not match Content-Length"
      return
    end
  end

  if @msg.request?
    process_request
  else
    process_response
  end

end

#receive_payload_data(payload_data) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/oversip/websocket/ws_sip_app.rb', line 34

def receive_payload_data payload_data
  # payload_data is always Encoding::BINARY so also @ws_message.to_str.
  @ws_message << payload_data

  # Check max message size.
  return false  if @ws_message.size > @@max_message_size
  true
end