websocket-server 1.1.5-java → 1.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
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