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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7670d3a4e743e533e42467d4047741a0ea833cc4e7ea4d1855a1ed9b76138560
4
- data.tar.gz: d1d6b8efb9502a45b44d56267d8a76fc036d46e4169c15cf93fcc605202ded8c
3
+ metadata.gz: 1a82a08a0eb5e690dcea50d8df9c9173fc9ee89dcb533e856b70c4a6622a5c11
4
+ data.tar.gz: 561c75644b76a40ed767a5c4e03d7d35dfb606c1819d39f08449b0c4283620ff
5
5
  SHA512:
6
- metadata.gz: a7cf7669311ab73b6a1905cda6d8112052b32ddbd7da3ccfb6bcf36e36e3f1d66b8fabf11da1b0abe0dc29a61c96f10506c1a8c750f95a45a18f494e711ec24f
7
- data.tar.gz: 16e0b9f2221cd9a83de57266561ea8797f40ac7d6d717e6b67fef1e078f045a5b2a5605c25c5670bc6fdde6c5db48610b85786f0a5c1a79d2a7df20c366ef6d6
6
+ metadata.gz: '083153e26d8f09e3cf8c9667bb02970d5861bba51d6390b9d02b8a5a5950c8c5e47afb172822b44e2e2e14810f90112314b87d3a5fbef201bbec1c8f2d4b46d1'
7
+ data.tar.gz: 446b92140447fdf3a45abae203308a1ac716f9ca6e6e15bd79053059c44a60fb2345a5421e7c391e855ba4739682258b5e01207ce52775e2eb6561a40a23db09
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2018 Nels Nelson
3
+ Copyright (c) 2016-2024 Nels Nelson
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -14,12 +14,13 @@ Follow these instructions to get a websocket server echo program running in your
14
14
 
15
15
  ### Container
16
16
 
17
- You may run the websocket server in a container.
17
+ You may run the websocket server in a container. Using [colima] for a container runtime is recommended.
18
18
 
19
19
  ```sh
20
20
  colima start
21
- docker-compose up &
21
+ docker-compose up --detach
22
22
  open http://localhost:4000/client.html
23
+ docker-compose down
23
24
  ```
24
25
 
25
26
 
@@ -35,34 +36,33 @@ docker run --detach --publish 4000:4000 --name websocket-server-jruby websocket-
35
36
 
36
37
  Run directly with the required dependencies installed.
37
38
 
38
- ### Install asdf
39
39
 
40
- The [asdf] CLI tool used to manage multiple runtime versions.
40
+ ## Install mise-en-place
41
+
42
+ The [mise] CLI tool used to manage multiple runtime versions.
43
+
44
+ See: https://mise.jdx.dev/getting-started.html
41
45
 
42
46
  ```sh
43
- git clone https://github.com/asdf-vm/asdf.git "${HOME}/.asdf" --branch v0.8.1
44
- pushd "${HOME}/.asdf"; git fetch origin; popd
45
- source "${HOME}/.asdf/asdf.sh"; source "${HOME}/.asdf/completions/asdf.bash"
47
+ curl https://mise.jdx.dev/install.sh | sh
48
+ ~/.local/bin/mise --version
49
+ mise 2024.x.x
46
50
  ```
47
51
 
48
- ### Install required runtime software
49
-
50
- Download and install the latest version of the [Java JDK].
52
+ Enable mise activation in future zsh sessions.
51
53
 
52
54
  ```sh
53
- asdf plugin add java
54
- asdf install java openjdk-17.0.2
55
+ echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
55
56
  ```
56
57
 
57
58
 
58
- Download and install the latest version of [JRuby].
59
+ ## Install required runtime software
60
+
61
+ Use mise to install the runtime software defined as requirements
62
+ in the .tool-versions file.
59
63
 
60
64
  ```sh
61
- asdf plugin add ruby
62
- pushd "${HOME}/.asdf/plugins/ruby/ruby-build"; git fetch origin; git pull origin master; popd
63
- # ~/.asdf/plugins/ruby/bin/list-all
64
- asdf list all ruby
65
- asdf install
65
+ mise install
66
66
  ```
67
67
 
68
68
 
@@ -106,12 +106,11 @@ bundle exec rake publish
106
106
  Here is a bird's-eye view of the project layout.
107
107
 
108
108
  ```sh
109
- # date && tree
110
- Wed Apr 6 23:05:28 CDT 2022
109
+ # date && tree -A -I "logs|vendor|tmp|Gemfile.lock"
110
+ Sun Jul 31 15:17:32 CDT 2022
111
111
  .
112
112
  ├── Dockerfile
113
113
  ├── Gemfile
114
- ├── Gemfile.lock
115
114
  ├── LICENSE
116
115
  ├── README.md
117
116
  ├── Rakefile
@@ -119,10 +118,9 @@ Wed Apr 6 23:05:28 CDT 2022
119
118
  ├── exe
120
119
  │ └── websocket
121
120
  ├── lib
122
- │ ├── log.rb
121
+ │ ├── logging.rb
123
122
  │ ├── server
124
- │ │ ├── mime_types.rb
125
- │ │ └── server.rb
123
+ │ │ └── mime_types.rb
126
124
  │ ├── websocket
127
125
  │ │ ├── arguments_parser.rb
128
126
  │ │ ├── channel_initializer.rb
@@ -135,22 +133,20 @@ Wed Apr 6 23:05:28 CDT 2022
135
133
  │ │ ├── http_static_file_server_handler_instance_methods.rb
136
134
  │ │ ├── idle_handler.rb
137
135
  │ │ ├── idle_state_user_event_handler.rb
136
+ │ │ ├── instance_methods.rb
138
137
  │ │ ├── listenable.rb
139
138
  │ │ ├── message_handler.rb
140
- │ │ ├── modular_handler.rb
141
139
  │ │ ├── response_helpers.rb
142
140
  │ │ ├── server.rb
143
- │ │ ├── server_instance_methods.rb
144
141
  │ │ ├── shutdown_hook.rb
145
142
  │ │ ├── ssl_cipher_inspector.rb
146
143
  │ │ ├── ssl_context_initialization.rb
147
144
  │ │ ├── telnet_proxy.rb
148
145
  │ │ ├── validation_helpers.rb
149
146
  │ │ └── version.rb
147
+ │ ├── websocket-server.rb
150
148
  │ ├── websocket_client.rb
151
149
  │ └── websocket_server.rb
152
- ├── logs
153
- │ └── server.log
154
150
  ├── spec
155
151
  │ ├── spec_helper.rb
156
152
  │ ├── test_spec.rb
@@ -172,14 +168,17 @@ Wed Apr 6 23:05:28 CDT 2022
172
168
  │ │ ├── console.js
173
169
  │ │ └── websocket.js
174
170
  │ └── jquery.min.js
171
+ ├── websocket-server-1.0.1-java.gem
175
172
  ├── websocket-server-jruby.gemspec
176
- └── websocket.rb
173
+ ├── websocket.rb
174
+ └── websocket_server.png
177
175
 
178
- 13 directories, 52 files
176
+ 12 directories, 51 files
179
177
  ```
180
178
 
181
179
  [license]: https://gitlab.com/nelsnelson/websocket-server-jruby/blob/master/LICENSE
182
- [asdf]: https://asdf-vm.com/
180
+ [mise]: https://mise.jdx.dev/
181
+ [colima]: https://github.com/abiosoft/colima
183
182
  [Netty project]: https://github.com/netty/netty
184
183
  [Java JDK]: https://www.java.com/en/download/
185
184
  [JRuby]: https://jruby.org/download
data/exe/websocket CHANGED
@@ -8,7 +8,7 @@
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
 
@@ -1,6 +1,9 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: false
3
3
 
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
4
7
  # =begin
5
8
 
6
9
  # Copyright Nels Nelson 2016-2019 but freely usable (see license)
@@ -8,11 +11,10 @@
8
11
  # =end
9
12
 
10
13
  require 'java'
14
+ require 'fileutils'
11
15
  require 'logger'
12
16
 
13
- require 'log4j-2'
14
-
15
- require 'fileutils'
17
+ require 'apache-log4j-2'
16
18
 
17
19
  # The Logging module
18
20
  module Logging
@@ -22,16 +24,22 @@ module Logging
22
24
  lib_dir_path = File.expand_path(__dir__)
23
25
  project_dir_path = File.expand_path(File.dirname(lib_dir_path))
24
26
  logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
25
- server_log_file = File.expand_path(File.join(logs_dir_path, 'server.log'))
27
+ FileUtils.mkdir_p(logs_dir_path)
28
+ log_file_path = File.expand_path(File.join(logs_dir_path, 'server.log'))
29
+ FileUtils.touch(log_file_path)
26
30
  {
27
- level: :info,
31
+ level: Logger::INFO,
28
32
  name: 'websocket',
29
33
  lib_dir_path: lib_dir_path,
30
34
  project_dir_path: project_dir_path,
31
35
  logs_dir_path: logs_dir_path,
32
- server_log_file: server_log_file,
33
- rolling_log_file_name_template: 'server-%d{yyyy-MM-dd}.log.gz',
34
- logger_pattern_template: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
36
+ log_file_path: log_file_path,
37
+ rolling_log_file_name_template: File.expand_path(
38
+ File.join(logs_dir_path, 'server-%d{yyyy-MM-dd}.log.gz')),
39
+ logging_pattern_template: {
40
+ java: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
41
+ ruby: "%<timestamp>s %-5<severity>s [%<progname>s] %<msg>s\n"
42
+ },
35
43
  schedule: '0 0 0 * * ?',
36
44
  size: '100M'
37
45
  }
@@ -41,69 +49,52 @@ module Logging
41
49
  # rubocop: enable Metrics/MethodLength
42
50
  end
43
51
 
44
- # The LogInitialization module
45
- module LogInitialization
46
- def init
47
- init_log_file
48
- init_log4j if defined? Java
49
- end
50
- module_function :init
51
-
52
- def init_log_file
53
- FileUtils.mkdir_p(Logging.config[:logs_dir_path])
54
- return if File.file?(Logging.config[:server_log_file])
55
-
56
- File.write(Logging.config[:server_log_file], '')
52
+ # The Logging module
53
+ module Logging
54
+ if defined?(Java)
55
+ java_import Java::org.apache.logging.log4j.core.appender::ConsoleAppender
56
+ java_import Java::org.apache.logging.log4j.core.config::Configurator
57
+ java_import Java::org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
57
58
  end
58
- module_function :init_log_file
59
59
 
60
60
  # rubocop: disable Metrics/AbcSize
61
61
  # rubocop: disable Metrics/MethodLength
62
62
  def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
63
- server_log_file = Logging.config[:server_log_file]
64
- logs_dir_path = Logging.config[:logs_dir_path]
65
- rolling_log_file_name_template = Logging.config[:rolling_log_file_name_template]
66
- rolling_log_file_path = File.join(logs_dir_path, rolling_log_file_name_template)
67
-
68
63
  java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
69
- factory = org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
70
- config = factory.newConfigurationBuilder()
64
+ config = ConfigurationBuilderFactory.newConfigurationBuilder()
71
65
 
72
- if log_level.is_a?(Symbol)
73
- log_level = org.apache.logging.log4j.Level.to_level(
74
- log_level.to_s.upcase
75
- )
76
- end
66
+ log_level = org.apache.logging.log4j::Level.to_level(log_level.to_s.upcase) if log_level.is_a? Symbol
77
67
  config.setStatusLevel(log_level)
78
- config.setConfigurationName(Logging.config['name'])
68
+ config.setConfigurationName('websocket')
79
69
 
80
- # Create a console appender
81
- target = org.apache.logging.log4j.core.appender::ConsoleAppender::Target::SYSTEM_OUT
70
+ # create a console appender
71
+ target = ConsoleAppender::Target::SYSTEM_OUT
72
+ pattern = Logging.config[:logging_pattern_template][:java]
82
73
  layout = config.newLayout('PatternLayout')
83
- layout = layout.addAttribute('pattern', Logging.config[:logger_pattern_template])
74
+ layout = layout.addAttribute('pattern', pattern)
84
75
  appender = config.newAppender('stdout', 'CONSOLE')
85
76
  appender = appender.addAttribute('target', target)
86
77
  appender = appender.add(layout)
87
78
  config.add(appender)
88
79
 
89
- # Create a root logger
80
+ # create a root logger
90
81
  root_logger = config.newRootLogger(log_level)
91
82
  root_logger = root_logger.add(config.newAppenderRef('stdout'))
92
83
 
93
- # Create a rolling file appender
84
+ # create a rolling file appender
94
85
  cron = config.newComponent('CronTriggeringPolicy')
95
- cron = cron.addAttribute('schedule', Logging.config[:schedule])
86
+ cron = cron.addAttribute('schedule', '0 0 0 * * ?')
96
87
 
97
88
  size = config.newComponent('SizeBasedTriggeringPolicy')
98
- size = size.addAttribute('size', Logging.config[:size])
89
+ size = size.addAttribute('size', '100M')
99
90
 
100
91
  policies = config.newComponent('Policies')
101
92
  policies = policies.addComponent(cron)
102
93
  policies = policies.addComponent(size)
103
94
 
104
95
  appender = config.newAppender('rolling_file', 'RollingFile')
105
- appender = appender.addAttribute('fileName', server_log_file)
106
- appender = appender.addAttribute('filePattern', rolling_log_file_path)
96
+ appender = appender.addAttribute('fileName', Logging.config[:log_file_path])
97
+ appender = appender.addAttribute('filePattern', Logging.config[:rolling_log_file_name_template])
107
98
  appender = appender.add(layout)
108
99
  appender = appender.addComponent(policies)
109
100
  config.add(appender)
@@ -113,28 +104,20 @@ module LogInitialization
113
104
  config.add(root_logger)
114
105
 
115
106
  logging_configuration = config.build()
116
- ctx = org.apache.logging.log4j.core.config::Configurator.initialize(logging_configuration)
107
+ ctx = Configurator.initialize(logging_configuration)
117
108
  ctx.updateLoggers()
118
109
  end
110
+ module_function :init_log4j
119
111
  # rubocop: enable Metrics/AbcSize
120
112
  # rubocop: enable Metrics/MethodLength
121
113
  # def init_log4j
122
- module_function :init_log4j
123
- end
124
- # module LogInitialization
125
-
126
- ::LogInitialization.init
127
114
 
128
- # The Apache log4j Logger class
129
- # rubocop: disable Style/ClassAndModuleChildren
130
- class org.apache.logging.log4j.core::Logger
131
- alias log4j_error error
132
- def error(error_or_message, error = nil)
133
- return extract_backtrace(error_or_message) if error.nil?
134
- log4j_error(generate_message(error_or_message, error))
135
- extract_backtrace(error)
136
- end
115
+ init_log4j if defined?(Java)
116
+ end
117
+ # module Logging
137
118
 
119
+ # Namespace for methods to help with implicit backtrace printing
120
+ module LoggerHelpers
138
121
  def generate_message(error_or_message, error)
139
122
  error_message = "#{error_or_message}: #{error.class.name}"
140
123
  error_message << ": #{error.message}" if error.respond_to?(:message)
@@ -142,40 +125,67 @@ class org.apache.logging.log4j.core::Logger
142
125
  end
143
126
 
144
127
  def extract_backtrace(error, default_result = nil)
145
- log4j_error(error)
146
128
  if error.respond_to?(:backtrace)
147
- error.backtrace.each { |trace| log4j_error(trace) unless trace.nil? }
129
+ error.backtrace.each { |trace| original_error(trace) unless trace.nil? }
148
130
  elsif error.respond_to?(:getStackTrace)
149
- error.getStackTrace().each { |trace| log4j_error(trace) unless trace.nil? }
131
+ error.getStackTrace().each { |trace| original_error(trace) unless trace.nil? }
150
132
  else
151
133
  default_result
152
134
  end
153
135
  end
154
136
  end
155
- # rubocop: enable Style/ClassAndModuleChildren
137
+
138
+ # Monkey-patch the built-in Ruby Logger class to support
139
+ # implicit backtrace printing
140
+ # TODO: Figure out if this is actually useful.
141
+ class Logger
142
+ include LoggerHelpers
143
+
144
+ alias original_error error
145
+ def error(error_or_message, error = nil)
146
+ return extract_backtrace(error_or_message) if error.nil?
147
+ original_error(generate_message(error_or_message, error))
148
+ extract_backtrace(original_error(error))
149
+ end
150
+ end
156
151
 
157
152
  # The Logging module
158
153
  module Logging
159
- def init_logger(level = :all, logger_name = nil)
154
+ if defined?(Java)
155
+ java_import Java::org.apache.logging.log4j.Level
156
+ java_import Java::org.apache.logging.log4j.LogManager
157
+ end
158
+
159
+ FORWARD_SLASH_PATTERN = %r{/}
160
+
161
+ def init_logger(level = :info, logger_name = nil)
160
162
  return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
161
- init_ruby_logger(level)
163
+ init_ruby_logger(level, logger_name, caller[2])
162
164
  end
163
165
 
164
- def init_ruby_logger(level)
165
- logger_instance = Logger.new
166
- logger_instance.level = Logging::Level.to_level(level.to_s.upcase)
167
- logger_instance
166
+ def ruby_log_formatter(severity_level, datetime, program_name, message)
167
+ format(
168
+ Logging.config[:logging_pattern_template][:ruby],
169
+ timestamp: datetime.strftime(Logging.config[:logging_timestamp_format]),
170
+ progname: program_name, severity: severity_level, msg: message)
168
171
  end
169
172
 
170
- # rubocop: disable Metrics/AbcSize
171
- def init_java_logger(level, logger_name = nil, source_location = nil)
173
+ def init_ruby_logger(level = nil, logger_name = nil, source_location = nil)
172
174
  logger_name = get_formatted_logger_name(logger_name)
173
- logger_name = source_location.split(/\//).last if logger_name.empty?
174
- logger_instance = org.apache.logging.log4j.LogManager.getLogger(logger_name)
175
- logger_instance.level = org.apache.logging.log4j.Level.to_level(level.to_s.upcase)
176
- logger_instance
175
+ logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
176
+ log = Logger.new($stdout, progname: logger_name)
177
+ log.level = level.to_s unless level.nil?
178
+ log.formatter = method(:ruby_log_formatter)
179
+ log
180
+ end
181
+
182
+ def init_java_logger(level = nil, logger_name = nil, source_location = nil)
183
+ logger_name = get_formatted_logger_name(logger_name)
184
+ logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
185
+ log = LogManager.getLogger(logger_name)
186
+ log.level = Level.to_level(level.to_s.upcase) unless level.nil?
187
+ log
177
188
  end
178
- # rubocop: enable Metrics/AbcSize
179
189
 
180
190
  def get_formatted_logger_name(logger_name = nil)
181
191
  return logger_name.to_s[/\w+$/] unless logger_name.nil?
@@ -202,14 +212,13 @@ module Logging
202
212
  when 1 then :info
203
213
  when 0 then :debug
204
214
  when -1 then :trace
205
- when -2..-Float::INFINITY then :all
215
+ when -Float::INFINITY..-2 then :all
206
216
  end
207
217
  end
208
218
  # rubocop: enable Metrics/CyclomaticComplexity
209
- module_function :symbolize_numeric_log_level
210
219
 
211
- def log_level=(log_level)
212
- Logging.config[:level] = symbolize_numeric_log_level(log_level)
220
+ def log_level=(level)
221
+ Logging.config[:level] = symbolize_numeric_log_level(level)
213
222
  end
214
223
  module_function :log_level=
215
224
 
@@ -218,7 +227,7 @@ module Logging
218
227
  end
219
228
  module_function :log_level
220
229
 
221
- def log(level = Logging.log_level, log_name = nil)
230
+ def log(level = Logging.log_level, log_name = Logging.config[:app_name])
222
231
  @log ||= init_logger(level, log_name)
223
232
  end
224
233
  alias logger log
@@ -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
 
@@ -16,20 +16,21 @@ require_relative 'config'
16
16
 
17
17
  # The WebSocket module
18
18
  module WebSocket
19
+ # rubocop: disable Metrics/ClassLength
19
20
  # The ArgumentsParser class
20
21
  class ArgumentsParser
21
- Flags = %i[
22
- banner port telnet_proxy_host telnet_proxy_port
23
- ssl ssl_certificate ssl_private_key use_jdk_ssl_provider
24
- inspect_ssl idle_reading idle_writing log_requests web_root
25
- verbose help version
26
- ].freeze
27
22
  attr_reader :parser, :options
28
23
 
29
24
  def initialize(option_parser = OptionParser.new)
30
25
  @parser = option_parser
31
26
  @options = ::WebSocket.server_config.dup
32
- Flags.each { |method_name| method(method_name).call }
27
+ @flags = %i[
28
+ banner port telnet_proxy_host telnet_proxy_port
29
+ ssl ssl_certificate ssl_private_key use_jdk_ssl_provider
30
+ inspect_ssl idle_reading idle_writing log_requests web_root
31
+ verbose help version
32
+ ]
33
+ @flags.each { |method_name| method(method_name)&.call if respond_to?(method_name) }
33
34
  end
34
35
 
35
36
  def banner
@@ -38,9 +39,17 @@ module WebSocket
38
39
  @parser.separator 'Options:'
39
40
  end
40
41
 
42
+ def validated_port(val, integer_pattern = /^\d+$/)
43
+ raise OptionParser::InvalidArgument, "Invalid port: #{v}" unless \
44
+ integer_pattern.match?(val.to_s) && val.positive? && val < 65_536
45
+
46
+ val
47
+ end
48
+
41
49
  def port
42
- @parser.on_head('-p', '--port=port', 'Listen on this port for incoming connections') do |v|
43
- @options[:port] = v.to_i
50
+ description = "Port on which to listen for connections; default: #{@options[:port]}"
51
+ @parser.on('-p', '--port=<port>', Integer, description) do |v|
52
+ @options[:port] = validated_port(v).to_i
44
53
  end
45
54
  end
46
55
 
@@ -112,6 +121,7 @@ module WebSocket
112
121
 
113
122
  def verbose
114
123
  @parser.on_tail('-v', '--verbose', 'Increase verbosity') do
124
+ @options[:log_level] ||= 0
115
125
  @options[:log_level] -= 1
116
126
  end
117
127
  end
@@ -125,17 +135,23 @@ module WebSocket
125
135
 
126
136
  def version
127
137
  @parser.on_tail('--version', 'Show version') do
128
- puts "#{File.basename($PROGRAM_NAME)} version #{WebSocket.version}"
138
+ puts "#{File.basename($PROGRAM_NAME)} version #{::WebSocket::VERSION}"
129
139
  exit
130
140
  end
131
141
  end
132
142
  end
143
+ # rubocop: enable Metrics/ClassLength
133
144
  # class ArgumentsParser
134
145
 
135
146
  def parse_arguments(arguments_parser = WebSocket::ArgumentsParser.new)
136
147
  arguments_parser.parser.parse!(ARGV)
137
148
  arguments_parser.options
138
- rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption => e
149
+ rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
150
+ OptionParser::MissingArgument, OptionParser::NeedlessArgument => e
151
+ puts e.message
152
+ puts parser
153
+ exit
154
+ rescue OptionParser::AmbiguousOption => e
139
155
  abort e.message
140
156
  end
141
157
  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
 
@@ -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,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,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,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
 
@@ -36,8 +36,8 @@ module WebSocket
36
36
 
37
37
  # The HttpStaticFileServerHandlerInstanceMethods module
38
38
  module HttpStaticFileServerHandlerInstanceMethods
39
- ForwardSlashBeforeEOLPattern = %r{/$}.freeze
40
- URIForwardSlashTemplate = '%<uri>s/'.freeze
39
+ FORWARD_SLASH_BEFORE_EOL_PATTERN = %r{/$}
40
+ URI_FORWARD_SLASH_TEMPLATE = '%<uri>s/'.freeze
41
41
 
42
42
  # rubocop: disable Metrics/AbcSize
43
43
  # rubocop: disable Metrics/CyclomaticComplexity
@@ -69,10 +69,10 @@ module WebSocket
69
69
  end
70
70
 
71
71
  if File.directory? path
72
- if ForwardSlashBeforeEOLPattern.match?(uri)
72
+ if FORWARD_SLASH_BEFORE_EOL_PATTERN.match?(uri)
73
73
  send_listing(ctx, path)
74
74
  else
75
- send_redirect(ctx, format(URIForwardSlashTemplate, uri: uri))
75
+ send_redirect(ctx, format(URI_FORWARD_SLASH_TEMPLATE, uri: uri))
76
76
  end
77
77
  return
78
78
  end
@@ -149,7 +149,6 @@ module WebSocket
149
149
  # rubocop: enable Metrics/PerceivedComplexity
150
150
 
151
151
  def exceptionCaught(ctx, cause)
152
- log.info "##{__method__} wtf2"
153
152
  cause.printStackTrace()
154
153
  return unless ctx.channel().isActive()
155
154
  send_error(ctx, HttpResponseStatus::INTERNAL_SERVER_ERROR)