websocket-server 1.1.5-java → 1.2.0-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: 58298e46b315a6b0a3b263a24b5ce82644a75e26b828d5bbee46b9206c4bb944
4
- data.tar.gz: 8ab9652cb207c8c3f180ffb85792782b4665a9842d71299e5bf368fedef5737d
3
+ metadata.gz: 64315a4d554857c31f1dd058666d4ff50813ec6a0afe829ad89434ab997ad55a
4
+ data.tar.gz: 6732df15258e1c3fcb5b2552160ad1125e383ab42bc7fa29763e992bf93c920a
5
5
  SHA512:
6
- metadata.gz: 94ad7799ec5713d5e4f0671158d488856f91e99cbd7e8d8dd9d9a06e622c273d28e95bfe3d377efe571ba779149bd62ec1dd8402ace97f66c11921b894b11312
7
- data.tar.gz: ebefc7c8ec573d5266d72c76e54e7bcd240efe8289f3aefc74c679a29f83e61b27edc7a8a59ecaf96491948b84c2686ae4e9db0496fb30aad30c64226e101a18
6
+ metadata.gz: a284c684a87c395f2587f0756f0ea6d312233208597e79de7c2e681e0f609ebd8ff552f017f199a0fe4f198860eef0bf2b7876e8d3a43829f9a2f1838635de73
7
+ data.tar.gz: 34fe8725f760895177dd962954564c9b246005a09ecca02e5be8e3c836edaa71d8bcb9d8aa3af55920579b32cd8c660dfe07214729f3036332a735b4500196f6
@@ -30,7 +30,7 @@ module WebSocket
30
30
  # configuration for the channel pipeline that will handle requests of
31
31
  # the server.
32
32
  class ChannelInitializer < ::Server::ChannelInitializer
33
- HttpObjectAggregatorBufferBytesSize = 65_536
33
+ HTTP_OBJECT_AGGREGATOR_BUFFER_BYTES_SIZE = 65_536
34
34
 
35
35
  def initialize(channel_group, options = {})
36
36
  super(channel_group, options)
@@ -40,15 +40,15 @@ module WebSocket
40
40
  # rubocop: disable Metrics/MethodLength
41
41
  def initChannel(channel)
42
42
  pipeline = channel.pipeline
43
- pipeline.addLast(ssl_handler(channel)) if @options[:ssl]
43
+ pipeline.addLast(ssl_handler(channel)) if ssl?
44
44
  pipeline.addLast(HttpServerCodec.new)
45
- pipeline.addLast(HttpObjectAggregator.new(HttpObjectAggregatorBufferBytesSize))
45
+ pipeline.addLast(HttpObjectAggregator.new(HTTP_OBJECT_AGGREGATOR_BUFFER_BYTES_SIZE))
46
46
  pipeline.addLast(ChunkedWriteHandler.new)
47
- pipeline.addLast(IdleStateHandler.new(@options[:idle_reading], @options[:idle_writing], 0))
47
+ pipeline.addLast(IdleStateHandler.new(idle_reading, idle_writing, 0))
48
48
  pipeline.addLast(WebSocket::IdleHandler.new)
49
49
  pipeline.addLast(WebSocketServerCompressionHandler.new)
50
- pipeline.addLast(WebSocketServerProtocolHandler.new(@options[:web_socket_path], nil, true))
51
- pipeline.addLast(SslCipherInspector.new) if !ssl_context.nil? && @options[:inspect_ssl]
50
+ pipeline.addLast(WebSocketServerProtocolHandler.new(web_socket_path, nil, true))
51
+ pipeline.addLast(SslCipherInspector.new) if !ssl_context.nil? && inspect_ssl?
52
52
  pipeline.addLast(HttpStaticFileServerHandler.new(@options))
53
53
  add_user_handlers(pipeline)
54
54
  pipeline.addLast(default_handler)
@@ -67,6 +67,43 @@ module WebSocket
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ private
72
+
73
+ def web_socket_path
74
+ @web_socket_path ||= begin
75
+ value = @options[:web_socket_path]
76
+ value.nil? || value.empty? ? DEFAULT_WEB_SOCKET_PATH : value
77
+ end
78
+ end
79
+
80
+ def idle_reading
81
+ @idle_reading ||= begin
82
+ value = @options[:idle_reading]
83
+ value.nil? ? DEFAULT_IDLE_READING_SECONDS : value
84
+ end
85
+ end
86
+
87
+ def idle_writing
88
+ @idle_writing ||= begin
89
+ value = @options[:idle_writing]
90
+ value.nil? ? DEFAULT_IDLE_WRITING_SECONDS : value
91
+ end
92
+ end
93
+
94
+ def ssl?
95
+ @ssl ||= begin
96
+ value = @options[:ssl]
97
+ value.nil? ? DEFAULT_SSL_ENABLED : value
98
+ end
99
+ end
100
+
101
+ def inspect_ssl?
102
+ @inspect_ssl = begin
103
+ value = @options[:inspect_ssl]
104
+ value.nil? ? DEFAULT_SSL_INSPECTION_ENABLED : value
105
+ end
106
+ end
70
107
  end
71
108
  # class ServerInitializer
72
109
  end
@@ -14,47 +14,70 @@ require 'logger'
14
14
 
15
15
  # The WebSocket module
16
16
  module WebSocket
17
+ WEBSOCKET_SUBMODULE_DIR_PATH = File.expand_path(__dir__)
18
+ LIB_DIR_PATH = File.expand_path(File.dirname(WEBSOCKET_SUBMODULE_DIR_PATH))
19
+ PROJECT_DIR_PATH = File.expand_path(File.dirname(LIB_DIR_PATH))
20
+ DEFAULT_LOG_LEVEL = Logger::INFO
21
+ DEFAULT_HOSTNAME = '0.0.0.0'.freeze
22
+ DEFAULT_PORT = 4000
23
+ DEFAULT_SSL_PORT = 443
24
+ DEFAULT_TELNET_PROXY_HOST = nil
25
+ DEFAULT_TELNET_PROXY_PORT = 21
26
+ DEFAULT_KEEP_ALIVE = true
27
+ DEFAULT_MAX_QUEUED_INCOMING_CONNECTIONS = 100
28
+ DEFAULT_IDLE_READING_SECONDS = 5 * 60 # seconds
29
+ DEFAULT_IDLE_WRITING_SECONDS = 30 # seconds
30
+ DEFAULT_SSL_ENABLED = false
31
+ DEFAULT_SSL_CERTIFICATE_FILE_PATH = File.join(PROJECT_DIR_PATH, 'fullchain.pem')
32
+ # openssl pkcs8 -topk8 -nocrypt -in websocket.key -out websocket_pcks8
33
+ #
34
+ # The privkey.key file here should be generated using the following
35
+ # openssl command:
36
+ #
37
+ # openssl pkcs8 -topk8 -inform PEM -outform DER -in privkey.pem -nocrypt > privkey.key
38
+ #
39
+ DEFAULT_SSL_PRIVATE_KEY_FILE_PATH = File.join(PROJECT_DIR_PATH, 'privkey.key')
40
+ DEFAULT_SSL_INSPECTION_ENABLED = false
41
+ DEFAULT_WEB_SOCKET_PATH = '/websocket'.freeze
42
+ DEFAULT_WEB_DIR = 'web'.freeze
43
+ DEFAULT_WEB_ROOT = File.join(PROJECT_DIR_PATH, DEFAULT_WEB_DIR)
44
+ DEFAULT_INDEX_PAGE = 'index.html'.freeze
45
+ DEFAULT_PING_MESSAGE = "ping\n".freeze
46
+ # EEE, dd MMM yyyy HH:mm:ss zzz
47
+ DEFAULT_HTTP_DATE_FORMAT = '%a, %d %b %Y %H:%M:%S %Z'.freeze
48
+ DEFAULT_HTTP_DATE_GMT_TIMEZONE = 'GMT'.freeze
49
+ DEFAULT_CACHE_SECONDS = 60 # seconds
50
+ DEFAULT_INSECURE_URI_PATTERN = %r{.*[<>&"].*}
51
+ DEFAULT_LOG_REQUESTS = false
52
+
17
53
  # rubocop: disable Metrics/MethodLength
18
54
  def server_config
19
- @server_config ||= begin
20
- server_submodule_dir_path = File.expand_path(__dir__)
21
- lib_dir_path = File.expand_path(File.dirname(server_submodule_dir_path))
22
- project_dir_path = File.expand_path(File.dirname(lib_dir_path))
23
- {
24
- log_level: Logger::INFO,
25
- host: '0.0.0.0',
26
- port: 4000,
27
- ssl_port: 443,
28
- telnet_proxy_host: nil,
29
- telnet_proxy_port: 21,
30
- ssl: false,
31
- ssl_certificate_file_path: File.join(project_dir_path, 'fullchain.pem'),
32
- # openssl pkcs8 -topk8 -nocrypt -in websocket.key -out websocket_pcks8
33
- #
34
- # The privkey.key file here should be generated using the following
35
- # openssl command:
36
- #
37
- # openssl pkcs8 -topk8 -inform PEM -outform DER -in privkey.pem -nocrypt > privkey.key
38
- #
39
- ssl_private_key_file_path: File.join(project_dir_path, 'privkey.key'),
40
- use_jdk_ssl_provider: false,
41
- inspect_ssl: false,
42
- idle_reading: 5 * 60, # seconds
43
- idle_writing: 30, # seconds
44
- keep_alive: true,
45
- max_queued_incoming_connections: 100,
46
- index_page: 'index.html',
47
- web_root: File.join(project_dir_path, 'web'),
48
- web_socket_path: '/websocket',
49
- ping_message: "ping\n",
50
- http_date_format: '%a, %d %b %Y %H:%M:%S %Z', # EEE, dd MMM yyyy HH:mm:ss zzz
51
- http_date_gmt_timezone: 'GMT',
52
- http_cache_seconds: 60,
53
- insecure_uri_pattern: /.*[<>&"].*/,
54
- allowed_file_name: /[A-Za-z0-9][-_A-Za-z0-9\\.]*/,
55
- log_requests: false
56
- }.freeze
57
- end
55
+ @server_config ||= {
56
+ log_level: DEFAULT_LOG_LEVEL,
57
+ host: DEFAULT_HOSTNAME,
58
+ port: DEFAULT_PORT,
59
+ ssl_port: DEFAULT_SSL_PORT,
60
+ telnet_proxy_host: DEFAULT_TELNET_PROXY_HOST,
61
+ telnet_proxy_port: DEFAULT_TELNET_PROXY_PORT,
62
+ ssl: DEFAULT_SSL_ENABLED,
63
+ ssl_certificate_file_path: DEFAULT_SSL_CERTIFICATE_FILE_PATH,
64
+ ssl_private_key_file_path: DEFAULT_SSL_PRIVATE_KEY_FILE_PATH,
65
+ use_jdk_ssl_provider: false,
66
+ inspect_ssl: DEFAULT_SSL_INSPECTION_ENABLED,
67
+ idle_reading: DEFAULT_IDLE_READING_SECONDS,
68
+ idle_writing: DEFAULT_IDLE_WRITING_SECONDS,
69
+ keep_alive: DEFAULT_KEEP_ALIVE,
70
+ max_queued_incoming_connections: DEFAULT_MAX_QUEUED_INCOMING_CONNECTIONS,
71
+ index_page: DEFAULT_INDEX_PAGE,
72
+ web_root: DEFAULT_WEB_ROOT,
73
+ web_socket_path: DEFAULT_WEB_SOCKET_PATH,
74
+ ping_message: DEFAULT_PING_MESSAGE,
75
+ http_date_format: DEFAULT_HTTP_DATE_FORMAT,
76
+ http_date_gmt_timezone: DEFAULT_HTTP_DATE_GMT_TIMEZONE,
77
+ http_cache_seconds: DEFAULT_CACHE_SECONDS,
78
+ insecure_uri_pattern: DEFAULT_INSECURE_URI_PATTERN,
79
+ log_requests: DEFAULT_LOG_REQUESTS
80
+ }
58
81
  end
59
82
  module_function :server_config
60
83
  # rubocop: enable Metrics/MethodLength
@@ -28,7 +28,7 @@ module WebSocket
28
28
  class FrameHandler < SimpleChannelInboundHandler
29
29
  include ChannelHandler
30
30
  include ChannelFutureListener
31
- UnsupportedFrameTypeErrorTemplate =
31
+ UNSUPPORTED_FRAME_TYPE_ERROR_TEMPLATE =
32
32
  '%<handler>s encountered unsupported frame type: %<frame>s'.freeze
33
33
 
34
34
  def initialize
@@ -50,7 +50,9 @@ module WebSocket
50
50
 
51
51
  def unsupported_frame(frame, handler)
52
52
  raise java.lang.UnsupportedOperationException, format(
53
- UnsupportedFrameTypeErrorTemplate, handler: handler.class, frame: frame.class
53
+ UNSUPPORTED_FRAME_TYPE_ERROR_TEMPLATE,
54
+ handler: handler.class,
55
+ frame: frame.class
54
56
  )
55
57
  end
56
58
 
@@ -21,6 +21,8 @@ module WebSocket
21
21
 
22
22
  # The HeaderHelpers module
23
23
  module HeaderHelpers
24
+ PRIVATE_MAX_AGE_TEMPLATE = 'private, max-age=%<max_age>s'.freeze
25
+
24
26
  def keep_alive_header(response)
25
27
  response.headers().set(HttpHeaderNames::CONNECTION, HttpHeaderValues::KEEP_ALIVE)
26
28
  end
@@ -41,15 +43,13 @@ module WebSocket
41
43
  response.headers().set(HttpHeaderNames::LAST_MODIFIED, last_modified)
42
44
  end
43
45
 
44
- PrivateMaxAgeTempalte = 'private, max-age=%<max_age>s'.freeze
45
-
46
46
  # rubocop: disable Metrics/AbcSize
47
47
  def date_and_cache_headers(response, path, timestamp = Time.now)
48
48
  maximum_age = options[:http_cache_seconds]
49
49
  date_format = options[:http_date_format]
50
50
  date_header(response, timestamp.strftime(date_format))
51
51
  expires_header(response, Time.at(timestamp.to_i + maximum_age).strftime(date_format))
52
- cache_control_header(response, format(PrivateMaxAgeTempalte, max_age: maximum_age.to_s))
52
+ cache_control_header(response, format(PRIVATE_MAX_AGE_TEMPLATE, max_age: maximum_age.to_s))
53
53
  last_modified_header(response, File.mtime(path).strftime(date_format))
54
54
  end
55
55
  # rubocop: enable Metrics/AbcSize
@@ -36,6 +36,7 @@ module WebSocket
36
36
 
37
37
  # The HttpStaticFileServerHandlerInstanceMethods module
38
38
  module HttpStaticFileServerHandlerInstanceMethods
39
+ WEB_SOCKET_PATH_PATTERN_TEMPLATE = '^%<path>s$'.freeze
39
40
  FORWARD_SLASH_BEFORE_EOL_PATTERN = %r{/$}
40
41
  URI_FORWARD_SLASH_TEMPLATE = '%<uri>s/'.freeze
41
42
 
@@ -44,7 +45,7 @@ module WebSocket
44
45
  # rubocop: disable Metrics/MethodLength
45
46
  # rubocop: disable Metrics/PerceivedComplexity
46
47
  def messageReceived(ctx, request)
47
- return if %r{^#{options[:web_socket_path]}$}.match?(request.uri)
48
+ return if web_socket_path_pattern.match?(request.uri)
48
49
 
49
50
  unless request.decoderResult().isSuccess()
50
51
  send_error(ctx, HttpResponseStatus::BAD_REQUEST)
@@ -153,6 +154,22 @@ module WebSocket
153
154
  return unless ctx.channel().isActive()
154
155
  send_error(ctx, HttpResponseStatus::INTERNAL_SERVER_ERROR)
155
156
  end
157
+
158
+ private
159
+
160
+ def web_socket_path_pattern
161
+ @web_socket_path_pattern ||= begin
162
+ pattern = format(WEB_SOCKET_PATH_PATTERN_TEMPLATE, path: web_socket_path)
163
+ Regexp.new(pattern)
164
+ end
165
+ end
166
+
167
+ def web_socket_path
168
+ @web_socket_path ||= begin
169
+ value = options[:web_socket_path]
170
+ value.nil? || value.empty? ? DEFAULT_WEB_SOCKET_PATH : value
171
+ end
172
+ end
156
173
  end
157
174
  # module HttpStaticFileServerHandlerInstanceMethods
158
175
  end
@@ -23,15 +23,6 @@ module WebSocket
23
23
 
24
24
  # The InstanceMethods module
25
25
  module InstanceMethods
26
- def bootstrap
27
- @bootstrap = ServerBootstrap.new
28
- @bootstrap.group(boss_group, worker_group)
29
- @bootstrap.channel(channel_type)
30
- @bootstrap.option(ChannelOption::SO_BACKLOG, max_queued_incoming_connections)
31
- @bootstrap.handler(logging_handler) if @options[:log_requests]
32
- @bootstrap.childHandler(channel_initializer)
33
- end
34
-
35
26
  def channel_initializer
36
27
  @channel_initializer ||= ::WebSocket::ChannelInitializer.new(channel_group, @options)
37
28
  end
@@ -58,6 +49,13 @@ module WebSocket
58
49
  def port
59
50
  @port ||= (@options[:ssl] ? @options[:ssl_port] : @options[:port]).to_i
60
51
  end
52
+
53
+ def log_requests?
54
+ @log_requests ||= begin
55
+ value = @options[:log_requests]
56
+ value.nil? ? DEFAULT_LOG_REQUESTS : value
57
+ end
58
+ end
61
59
  end
62
60
  # module ServerInstanceMethods
63
61
  end
@@ -28,7 +28,7 @@ module WebSocket
28
28
  DOT_FILE_SEPARATOR_PATTERN.match?(uri) ||
29
29
  uri.start_with?('.') ||
30
30
  uri.end_with?('.') ||
31
- options[:insecure_uri_pattern].match?(uri)
31
+ insecure_uri_pattern.match?(uri)
32
32
  end
33
33
 
34
34
  def sanitize_uri(uri)
@@ -39,7 +39,23 @@ module WebSocket
39
39
  uri = uri.gsub(FORWARD_SLASH_PATTERN, File::SEPARATOR)
40
40
  return nil if insecure_uri?(uri)
41
41
  # Convert to absolute path.
42
- File.join(options[:web_root], uri)
42
+ File.join(web_root, uri)
43
+ end
44
+
45
+ private
46
+
47
+ def web_root
48
+ @web_root ||= begin
49
+ value = options[:web_root]
50
+ value || DEFAULT_WEB_ROOT
51
+ end
52
+ end
53
+
54
+ def insecure_uri_pattern
55
+ @insecure_uri_pattern ||= begin
56
+ value = options[:insecure_uri_pattern]
57
+ value || DEFAULT_INSECURE_URI_PATTERN
58
+ end
43
59
  end
44
60
  end
45
61
  # module ValidationHelpers
@@ -12,5 +12,5 @@
12
12
 
13
13
  # The WebSocket module
14
14
  module WebSocket
15
- VERSION = '1.1.5'.freeze
15
+ VERSION = '1.2.0'.freeze
16
16
  end
@@ -262,8 +262,6 @@ module WebSocket
262
262
 
263
263
  def add_listener(*listener)
264
264
  listeners.addAll(listener)
265
- ensure
266
- log.trace "Listeners: #{listeners}"
267
265
  end
268
266
 
269
267
  def remove_listener(*listener)
@@ -33,7 +33,6 @@ module WebSocket
33
33
  end
34
34
 
35
35
  # rubocop: disable Metrics/AbcSize
36
- # rubocop: disable Metrics/MethodLength
37
36
  def main(args = parse_arguments)
38
37
  Logging.log_level = args[:log_level]
39
38
  return telnet_proxy(args) unless args[:telnet_proxy_host].nil?
@@ -42,13 +41,11 @@ module WebSocket
42
41
  warn format("\r%<class>s", class: e.class)
43
42
  exit
44
43
  rescue StandardError => e
45
- puts Logging.log_level
46
44
  ::WebSocket::Server.log.fatal(e.message)
47
45
  e.backtrace.each { |t| WebSocket::Server.log.debug t }
48
46
  abort
49
47
  end
50
48
  # rubocop: enable Metrics/AbcSize
51
- # rubocop: enable Metrics/MethodLength
52
49
  end
53
50
  # module WebSocket
54
51
 
@@ -0,0 +1,71 @@
1
+
2
+ span.underline {
3
+ text-decoration: underline;
4
+ }
5
+ span.blink {
6
+ text-decoration: blink;
7
+ }
8
+ span.flash {
9
+ text-decoration: flash;
10
+ }
11
+ span.inverse {
12
+ text-decoration: inverse;
13
+ }
14
+ span.hidden {
15
+ display: none;
16
+ }
17
+ span.line-through {
18
+ text-decoration: line-through;
19
+ }
20
+ span.monospace {
21
+ font-family: 'Droid Sans Mono', sans-serif;
22
+ }
23
+
24
+ span.black-foreground {
25
+ color: black;
26
+ }
27
+ span.red-foreground {
28
+ color: red;
29
+ }
30
+ span.green-foreground {
31
+ color: green;
32
+ }
33
+ span.yellow-foreground {
34
+ color: yellow;
35
+ }
36
+ span.dodgerblue-foreground {
37
+ color: dodgerblue;
38
+ }
39
+ span.magenta-foreground {
40
+ color: magenta;
41
+ }
42
+ span.cyan-foreground {
43
+ color: cyan;
44
+ }
45
+ span.white-foreground {
46
+ color: white;
47
+ }
48
+ span.black-background {
49
+ background-color: black;
50
+ }
51
+ span.red-background {
52
+ background-color: red;
53
+ }
54
+ span.green-background {
55
+ background-color: green;
56
+ }
57
+ span.yellow-background {
58
+ background-color: yellow;
59
+ }
60
+ span.dodgerblue-background {
61
+ background-color: dodgerblue;
62
+ }
63
+ span.magenta-background {
64
+ background-color: magenta;
65
+ }
66
+ span.cyan-background {
67
+ background-color: cyan;
68
+ }
69
+ span.white-background {
70
+ background-color: white;
71
+ }
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: websocket-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.0
5
5
  platform: java
6
6
  authors:
7
7
  - Nels Nelson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-12 00:00:00.000000000 Z
11
+ date: 2024-04-16 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.1.4
18
+ version: 1.2.1
19
19
  name: tcp-server
20
20
  type: :runtime
21
21
  prerelease: false
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.1.4
26
+ version: 1.2.1
27
27
  force_ruby_platform: false
28
28
  description: Websocket Server for JRuby is a websocket server with a file server to
29
29
  support a demo javascript client application which interfaces with a demo echo server
@@ -66,6 +66,7 @@ files:
66
66
  - lib/websocket_client.rb
67
67
  - lib/websocket_server.rb
68
68
  - web/client.html
69
+ - web/css/client/ansispan.css
69
70
  - web/css/client/console.css
70
71
  - web/css/client/parchment.css
71
72
  - web/favicon.ico