websocket-server 1.0.1-java → 1.1.2-java

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.
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -23,6 +23,7 @@ module WebSocket
23
23
  # server pipeline.
24
24
  class IdleHandler < WebSocket::IdleStateUserEventHandler
25
25
  def initialize
26
+ # Include additional subclass initialization here.
26
27
  super()
27
28
  end
28
29
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -63,36 +63,24 @@ module WebSocket
63
63
  # rubocop: disable Metrics/AbcSize
64
64
  # rubocop: disable Metrics/MethodLength
65
65
  def run(params = {})
66
- options.merge!(params)
66
+ @options.merge!(params)
67
67
  channel = bootstrap.bind(port).sync().channel()
68
68
  channel_group.add(channel)
69
69
  ::WebSocket::ShutdownHook.new(self)
70
70
  log.info "Listening on #{channel.local_address}"
71
71
  channel.closeFuture().sync()
72
72
  rescue java.net.BindException => e
73
- raise "Bind error: #{e.message}: #{options[:host]}:#{port}"
73
+ raise "Bind error: #{e.message}: #{@options[:host]}:#{port}"
74
74
  rescue java.net.SocketException => e
75
- raise "Socket error: #{e.message}: #{options[:host]}:#{port}"
75
+ raise "Socket error: #{e.message}: #{@options[:host]}:#{port}"
76
76
  ensure
77
77
  stop
78
78
  end
79
79
  # rubocop: enable Metrics/AbcSize
80
80
  # rubocop: enable Metrics/MethodLength
81
81
 
82
- IntegerPattern = /^\d+$/.freeze
83
-
84
- def valid_port?(val)
85
- IntegerPattern.match?(val.to_s) && val.positive? && val < 65_536
86
- end
87
-
88
- def given_port
89
- value = (options[:ssl] ? options[:ssl_port] : options[:port]).to_i
90
- raise 'Given port parameter is invalid' unless valid_port?(value)
91
- value
92
- end
93
-
94
82
  def port
95
- @port ||= given_port
83
+ @port ||= (@options[:ssl] ? @options[:ssl_port] : @options[:port]).to_i
96
84
  end
97
85
 
98
86
  def shutdown
@@ -109,8 +97,8 @@ module WebSocket
109
97
  channel_initializer.handlers << handler
110
98
  end
111
99
 
112
- def add_listener(listener)
113
- channel_initializer.add_listener(listener)
100
+ def add_listener(*listener)
101
+ channel_initializer.add_listener(*listener)
114
102
  end
115
103
 
116
104
  # def all_exist?(*files)
@@ -6,36 +6,14 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
- require 'java'
14
-
15
13
  # The WebSocket module
16
14
  module WebSocket
17
15
  # The Listenable module
18
16
  module Listenable
19
- def listeners
20
- @listeners ||= java.util.concurrent.CopyOnWriteArrayList.new
21
- end
22
-
23
- def add_listener(listener)
24
- listeners << listener
25
- end
26
-
27
- def remove_listener(listener)
28
- listeners.delete(listener)
29
- end
30
-
31
- def notify(message, *args)
32
- return if listeners.empty?
33
- log.trace "Notifying listeners (#{listeners}) of message: #{message}"
34
- listeners.each do |listener|
35
- listener.send(message.to_sym, *args) if listener.respond_to?(message.to_sym)
36
- end
37
- end
17
+ include ::Server::Listenable
38
18
  end
39
- # module Listenable
40
19
  end
41
- # module WebSocket
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -26,13 +26,13 @@ module WebSocket
26
26
 
27
27
  # The ResponseHelpers helpers
28
28
  module ResponseHelpers
29
- NonSpacesBeforeEOLPattern = %r{([^\s]+)$}.freeze
29
+ NON_SPACES_BEFORE_EOL_PATTERN = %r{([^\s]+)$}
30
30
 
31
31
  def index_listing(path)
32
32
  results = `ls -la #{path}`.strip.split("\n")
33
33
  results.shift
34
34
  index = results.collect do |s|
35
- s.gsub(NonSpacesBeforeEOLPattern) do |resource_name|
35
+ s.gsub(NON_SPACES_BEFORE_EOL_PATTERN) do |resource_name|
36
36
  %(<a href="#{resource_name}">#{resource_name}</a>)
37
37
  end
38
38
  end.join '<br />'
@@ -6,12 +6,10 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
- require 'java'
14
- require 'netty'
15
13
  require 'tcp-server'
16
14
 
17
15
  require_relative 'instance_methods'
@@ -6,12 +6,11 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
13
  require 'java'
14
- require 'netty'
15
14
 
16
15
  # The WebSocket module
17
16
  module WebSocket
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -22,6 +22,7 @@ module WebSocket
22
22
  # cipher configuration and pipeline handling of SSL handshakes.
23
23
  class SslCipherInspector < SimpleChannelInboundHandler
24
24
  def initialize
25
+ # Include additional subclass initialization here.
25
26
  super()
26
27
  end
27
28
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -6,41 +6,37 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
- require 'java'
14
- require 'netty'
15
-
16
13
  require_relative 'encoding'
17
14
 
18
15
  # The WebSocket module
19
16
  module WebSocket
20
17
  # The ValidationHelpers module
21
18
  module ValidationHelpers
22
- FileSeparatorDotPattern = %r{#{File::SEPARATOR}\.}.freeze
23
- DotFileSeparatorPattern = %r{\.#{File::SEPARATOR}}.freeze
19
+ FILE_SEPARATOR_DOT_PATTERN = %r{#{File::SEPARATOR}\.}
20
+ DOT_FILE_SEPARATOR_PATTERN = %r{\.#{File::SEPARATOR}}
21
+ QUERY_STRING_PATTERN = %r{\?.*}
22
+ FORWARD_SLASH_PATTERN = %r{/}
24
23
 
25
24
  # Simplistic dumb security check.
26
25
  # Something more serious is required in a production environment.
27
26
  def insecure_uri?(uri)
28
- FileSeparatorDotPattern.match?(uri) ||
29
- DotFileSeparatorPattern.match?(uri) ||
27
+ FILE_SEPARATOR_DOT_PATTERN.match?(uri) ||
28
+ DOT_FILE_SEPARATOR_PATTERN.match?(uri) ||
30
29
  uri.start_with?('.') ||
31
30
  uri.end_with?('.') ||
32
31
  options[:insecure_uri_pattern].match?(uri)
33
32
  end
34
33
 
35
- QueryStringPattern = %r{\?.*}.freeze
36
- ForwardSlashPattern = %r{/}.freeze
37
-
38
34
  def sanitize_uri(uri)
39
35
  # Decode the path.
40
- uri = CGI.unescape(uri.gsub(QueryStringPattern, ''), WebSocket::Encoding.name)
36
+ uri = CGI.unescape(uri.gsub(QUERY_STRING_PATTERN, ''), WebSocket::Encoding.name)
41
37
  return nil if uri.empty? || !uri.start_with?('/')
42
38
  # Convert file separators.
43
- uri = uri.gsub(ForwardSlashPattern, File::SEPARATOR)
39
+ uri = uri.gsub(FORWARD_SLASH_PATTERN, File::SEPARATOR)
44
40
  return nil if insecure_uri?(uri)
45
41
  # Convert to absolute path.
46
42
  File.join(options[:web_root], uri)
@@ -6,11 +6,11 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
13
  # The WebSocket module
14
14
  module WebSocket
15
- VERSION = '1.0.1'.freeze
15
+ VERSION = '1.1.2'.freeze
16
16
  end
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -8,16 +8,16 @@
8
8
 
9
9
  # =begin
10
10
  #
11
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
11
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
12
12
  #
13
13
  # =end
14
14
 
15
+ require 'java'
15
16
  require 'optparse'
16
17
 
17
- require 'java'
18
18
  require 'netty'
19
19
 
20
- require 'log'
20
+ require_relative 'logging'
21
21
 
22
22
  # Simple websocket client ported from the example from Netty-io.
23
23
 
@@ -260,23 +260,32 @@ module WebSocket
260
260
  @listeners ||= java.util.concurrent.CopyOnWriteArrayList.new
261
261
  end
262
262
 
263
- def add_listener(listener)
264
- listeners << listener
263
+ def add_listener(*listener)
264
+ listeners.addAll(listener)
265
+ ensure
266
+ log.trace "Listeners: #{listeners}"
267
+ end
268
+
269
+ def remove_listener(*listener)
270
+ listeners.removeAll(listener)
265
271
  end
266
272
 
267
- def remove_listener(listener)
268
- listeners.delete(listener)
273
+ def replace_listeners(*listener)
274
+ listeners.clear
275
+ add_listener(*listener)
269
276
  end
270
277
 
271
- def notify(message, *args)
272
- return if listeners.empty?
273
- log.trace "Notifying listeners (#{listeners}) of message: #{message}"
278
+ def notify(event, *args)
274
279
  listeners.each do |listener|
275
- listener.send(message.to_sym, *args) if listener.respond_to?(message.to_sym)
280
+ next unless listener.respond_to?(event.to_sym)
281
+ log.trace "Notifying listener #{listener} of event: #{event}"
282
+ listener.send(event.to_sym, *args)
276
283
  end
277
284
  end
278
285
  end
286
+ # module Listenable
279
287
  end
288
+ # module WebSocket
280
289
 
281
290
  # The WebSocket module
282
291
  module WebSocket
@@ -326,7 +335,6 @@ module WebSocket
326
335
  end
327
336
 
328
337
  def exceptionCaught(ctx, cause)
329
- log.info "##{__method__} wtf1"
330
338
  cause.printStackTrace()
331
339
  @handshake_future.setFailure(cause) unless @handshake_future.isDone()
332
340
  ctx.close()
@@ -424,10 +432,8 @@ module WebSocket
424
432
  session
425
433
  end
426
434
 
427
- IdentiferTemplate = '#<%<class>s:0x%<id>s>'.freeze
428
-
429
435
  def to_s
430
- format(IdentiferTemplate, class: self.class.name, id: object_id.to_s(16))
436
+ format('#<%<class>s:0x%<id>s>', class: self.class.name, id: object_id.to_s(16))
431
437
  end
432
438
  alias inspect to_s
433
439
  end
@@ -436,31 +442,69 @@ end
436
442
 
437
443
  # The WebSocket module
438
444
  module WebSocket
439
- # rubocop: disable Metrics/AbcSize
440
- # rubocop: disable Metrics/MethodLength
441
- def parse_arguments(options = ::WebSocket.client_config.dup)
442
- parser = OptionParser.new
443
- parser.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options]"
444
- parser.separator ''
445
- parser.separator 'Options:'
446
- parser.on_head('-u', '--uri=<uri>', 'Fully qualified connection string') do |v|
447
- options[:uri] = java.net.URI.new(v)
448
- end
449
- parser.on_tail('-v', '--verbose', 'Increase verbosity') { options[:log_level] -= 1 }
450
- parser.on_tail('-?', '--help', 'Show this message') do
451
- puts parser
452
- exit
453
- end
454
- parser.on_tail('--version', 'Show version') do
455
- puts "#{$PROGRAM_NAME} version #{::WebSocket.version}"
456
- exit
457
- end
458
- parser.parse!
459
- options
445
+ # The ArgumentsParser class
446
+ class ArgumentsParser
447
+ attr_reader :parser, :options
448
+
449
+ def initialize(parser = OptionParser.new, options = ::WebSocket.client_config.dup)
450
+ @parser = parser
451
+ @options = options
452
+ @flags = %i[banner uri log_level help version]
453
+ @flags.each { |method_name| method(method_name)&.call if respond_to?(method_name) }
454
+ end
455
+
456
+ def banner
457
+ @parser.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options]"
458
+ @parser.separator ''
459
+ @parser.separator 'Options:'
460
+ end
461
+
462
+ def uri
463
+ @parser.on_head('-u', '--uri=<uri>', 'Fully qualified connection string') do |v|
464
+ @options[:uri] = java.net.URI.new(v)
465
+ end
466
+ end
467
+
468
+ def log_level
469
+ @parser.on_tail('-v', '--verbose', 'Increase verbosity') do
470
+ @options[:log_level] ||= 0
471
+ @options[:log_level] -= 1
472
+ end
473
+ end
474
+
475
+ def help
476
+ @parser.on_tail('-?', '--help', 'Show this message') do
477
+ puts @parser
478
+ exit
479
+ end
480
+ end
481
+
482
+ def version
483
+ @parser.on_tail('--version', 'Show version') do
484
+ puts "#{File.basename($PROGRAM_NAME)} version #{::WebSocket::VERSION}"
485
+ exit
486
+ end
487
+ end
460
488
  end
461
- # rubocop: enable Metrics/AbcSize
462
- # rubocop: enable Metrics/MethodLength
489
+ # class ArgumentsParser
490
+
491
+ def parse_arguments(arguments_parser = ArgumentsParser.new)
492
+ arguments_parser.parser.parse!(ARGV)
493
+ arguments_parser.parse_positional_arguments!
494
+ arguments_parser.options
495
+ rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
496
+ OptionParser::MissingArgument, OptionParser::NeedlessArgument => e
497
+ puts e.message
498
+ puts parser
499
+ exit
500
+ rescue OptionParser::AmbiguousOption => e
501
+ abort e.message
502
+ end
503
+ end
504
+ # module WebSocket
463
505
 
506
+ # The WebSocket module
507
+ module WebSocket
464
508
  def main(args = parse_arguments)
465
509
  Logging.log_level = args[:log_level]
466
510
  ::WebSocket::Client.new(args)
@@ -475,4 +519,4 @@ module WebSocket
475
519
  end
476
520
  # module WebSocket
477
521
 
478
- Object.new.extend(::WebSocket).main if $PROGRAM_NAME == __FILE__
522
+ Object.new.extend(WebSocket).main if $PROGRAM_NAME == __FILE__
@@ -8,42 +8,47 @@
8
8
 
9
9
  # =begin
10
10
  #
11
- # Copyright Nels Nelson 2016-2022 but freely usable (see license)
11
+ # Copyright Nels Nelson 2016-2024 but freely usable (see license)
12
12
  #
13
13
  # =end
14
14
 
15
- require_relative 'log'
15
+ require 'java'
16
+
17
+ require_relative 'logging'
16
18
  require_relative 'websocket/arguments_parser'
17
19
  require_relative 'websocket/server'
18
20
  require_relative 'websocket/telnet_proxy'
19
21
 
20
22
  # The WebSocket module
21
23
  module WebSocket
22
- EchoServerMessageTemplate = "%<message>s\n".freeze
23
- InterruptTemplate = "\r%<class>s".freeze
24
-
25
24
  def echo_server(options)
26
- WebSocket::Server.new(options: options) do |_ctx, msg|
27
- format(EchoServerMessageTemplate, message: msg.upcase)
25
+ ::WebSocket::Server.new(options) do |_ctx, msg|
26
+ format("%<message>s\n", message: msg.upcase)
28
27
  end.run
29
28
  end
30
29
 
31
30
  def telnet_proxy(options)
32
- handler = WebSocket::TelnetProxy.new(options[:telnet_proxy_host], options[:telnet_proxy_port])
33
- WebSocket::Server.new(handler: handler, options: options).run
31
+ handler = ::WebSocket::TelnetProxy.new(options[:telnet_proxy_host], options[:telnet_proxy_port])
32
+ ::WebSocket::Server.new(options, handler).run
34
33
  end
35
34
 
35
+ # rubocop: disable Metrics/AbcSize
36
+ # rubocop: disable Metrics/MethodLength
36
37
  def main(args = parse_arguments)
37
38
  Logging.log_level = args[:log_level]
38
39
  return telnet_proxy(args) unless args[:telnet_proxy_host].nil?
39
40
  echo_server(args)
40
41
  rescue Interrupt => e
41
- warn format(InterruptTemplate, class: e.class)
42
+ warn format("\r%<class>s", class: e.class)
42
43
  exit
43
44
  rescue StandardError => e
44
- WebSocket::Server.log.fatal(e.message)
45
+ puts Logging.log_level
46
+ ::WebSocket::Server.log.fatal(e.message)
47
+ e.backtrace.each { |t| WebSocket::Server.log.debug t }
45
48
  abort
46
49
  end
50
+ # rubocop: enable Metrics/AbcSize
51
+ # rubocop: enable Metrics/MethodLength
47
52
  end
48
53
  # module WebSocket
49
54
 
metadata CHANGED
@@ -1,71 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: websocket-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.2
5
5
  platform: java
6
6
  authors:
7
7
  - Nels Nelson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2024-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 1.0.5
18
+ version: 1.1.3
19
19
  name: tcp-server
20
- prerelease: false
21
20
  type: :runtime
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 1.0.5
27
- - !ruby/object:Gem::Dependency
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 12.3.0
33
- name: rake
34
- prerelease: false
35
- type: :development
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 12.3.0
41
- - !ruby/object:Gem::Dependency
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 3.11.0
47
- name: rspec
48
- prerelease: false
49
- type: :development
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 3.11.0
55
- - !ruby/object:Gem::Dependency
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: 1.25.0
61
- name: rubocop
62
21
  prerelease: false
63
- type: :development
64
22
  version_requirements: !ruby/object:Gem::Requirement
65
23
  requirements:
66
24
  - - "~>"
67
25
  - !ruby/object:Gem::Version
68
- version: 1.25.0
26
+ version: 1.1.3
27
+ force_ruby_platform: false
69
28
  description: Websocket Server for JRuby is a websocket server with a file server to
70
29
  support a demo javascript client application which interfaces with a demo echo server
71
30
  application.
@@ -75,11 +34,11 @@ executables:
75
34
  extensions: []
76
35
  extra_rdoc_files: []
77
36
  files:
78
- - LICENSE
37
+ - LICENSE.txt
79
38
  - README.md
80
39
  - Rakefile
81
40
  - exe/websocket
82
- - lib/log.rb
41
+ - lib/logging.rb
83
42
  - lib/server/mime_types.rb
84
43
  - lib/websocket-server.rb
85
44
  - lib/websocket/arguments_parser.rb
@@ -138,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
97
  - !ruby/object:Gem::Version
139
98
  version: '0'
140
99
  requirements: []
141
- rubygems_version: 3.2.29
100
+ rubygems_version: 3.3.26
142
101
  signing_key:
143
102
  specification_version: 4
144
103
  summary: Websocket Server for JRuby packaged as a gem.