websocket-server 1.1.4-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 +4 -4
- data/lib/websocket/channel_initializer.rb +43 -6
- data/lib/websocket/config.rb +62 -37
- data/lib/websocket/frame_handler.rb +4 -2
- data/lib/websocket/header_helpers.rb +3 -3
- data/lib/websocket/http_static_file_server_handler_instance_methods.rb +18 -1
- data/lib/websocket/instance_methods.rb +6 -59
- data/lib/websocket/ssl_context_initialization.rb +9 -0
- data/lib/websocket/validation_helpers.rb +18 -2
- data/lib/websocket/version.rb +1 -1
- data/lib/websocket_client.rb +0 -2
- data/lib/websocket_server.rb +0 -3
- data/web/css/client/ansispan.css +71 -0
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64315a4d554857c31f1dd058666d4ff50813ec6a0afe829ad89434ab997ad55a
|
|
4
|
+
data.tar.gz: 6732df15258e1c3fcb5b2552160ad1125e383ab42bc7fa29763e992bf93c920a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
|
43
|
+
pipeline.addLast(ssl_handler(channel)) if ssl?
|
|
44
44
|
pipeline.addLast(HttpServerCodec.new)
|
|
45
|
-
pipeline.addLast(HttpObjectAggregator.new(
|
|
45
|
+
pipeline.addLast(HttpObjectAggregator.new(HTTP_OBJECT_AGGREGATOR_BUFFER_BYTES_SIZE))
|
|
46
46
|
pipeline.addLast(ChunkedWriteHandler.new)
|
|
47
|
-
pipeline.addLast(IdleStateHandler.new(
|
|
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(
|
|
51
|
-
pipeline.addLast(SslCipherInspector.new) if !ssl_context.nil? &&
|
|
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
|
data/lib/websocket/config.rb
CHANGED
|
@@ -14,45 +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 ||=
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
web_root: File.join(project_dir_path, 'web'),
|
|
46
|
-
web_socket_path: '/websocket',
|
|
47
|
-
ping_message: "ping\n",
|
|
48
|
-
http_date_format: '%a, %d %b %Y %H:%M:%S %Z', # EEE, dd MMM yyyy HH:mm:ss zzz
|
|
49
|
-
http_date_gmt_timezone: 'GMT',
|
|
50
|
-
http_cache_seconds: 60,
|
|
51
|
-
insecure_uri_pattern: /.*[<>&"].*/,
|
|
52
|
-
allowed_file_name: /[A-Za-z0-9][-_A-Za-z0-9\\.]*/,
|
|
53
|
-
log_requests: false
|
|
54
|
-
}
|
|
55
|
-
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
|
+
}
|
|
56
81
|
end
|
|
57
82
|
module_function :server_config
|
|
58
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
@@ -19,47 +19,14 @@ require_relative 'shutdown_hook'
|
|
|
19
19
|
# The WebSocket module
|
|
20
20
|
module WebSocket
|
|
21
21
|
java_import Java::io.netty.bootstrap.ServerBootstrap
|
|
22
|
-
java_import Java::io.netty.channel.
|
|
23
|
-
java_import Java::io.netty.channel.nio.NioEventLoopGroup
|
|
24
|
-
java_import Java::io.netty.handler.logging.LoggingHandler
|
|
25
|
-
java_import Java::io.netty.handler.logging.LogLevel
|
|
26
|
-
java_import Java::io.netty.util.concurrent.GlobalEventExecutor
|
|
22
|
+
java_import Java::io.netty.channel.ChannelOption
|
|
27
23
|
|
|
28
24
|
# The InstanceMethods module
|
|
29
25
|
module InstanceMethods
|
|
30
|
-
def configure_handlers(&block)
|
|
31
|
-
add_listener(self)
|
|
32
|
-
channel_initializer << block if block_given?
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def bootstrap
|
|
36
|
-
@bootstrap = ServerBootstrap.new
|
|
37
|
-
@bootstrap.group(boss_group, worker_group)
|
|
38
|
-
@bootstrap.channel(Server::CHANNEL_TYPE)
|
|
39
|
-
@bootstrap.handler(logging_handler) if @options[:log_requests]
|
|
40
|
-
@bootstrap.childHandler(channel_initializer)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
26
|
def channel_initializer
|
|
44
27
|
@channel_initializer ||= ::WebSocket::ChannelInitializer.new(channel_group, @options)
|
|
45
28
|
end
|
|
46
29
|
|
|
47
|
-
def boss_group
|
|
48
|
-
@boss_group ||= NioEventLoopGroup.new(2)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def worker_group
|
|
52
|
-
@worker_group ||= NioEventLoopGroup.new
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def channel_group
|
|
56
|
-
@channel_group ||= DefaultChannelGroup.new('server_channels', GlobalEventExecutor::INSTANCE)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def logging_handler
|
|
60
|
-
LoggingHandler.new(LogLevel::INFO)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
30
|
# rubocop: disable Metrics/AbcSize
|
|
64
31
|
# rubocop: disable Metrics/MethodLength
|
|
65
32
|
def run(params = {})
|
|
@@ -83,32 +50,12 @@ module WebSocket
|
|
|
83
50
|
@port ||= (@options[:ssl] ? @options[:ssl_port] : @options[:port]).to_i
|
|
84
51
|
end
|
|
85
52
|
|
|
86
|
-
def
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def stop
|
|
92
|
-
boss_group&.shutdownGracefully()
|
|
93
|
-
worker_group&.shutdownGracefully()
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def <<(handler)
|
|
97
|
-
channel_initializer.handlers << handler
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def add_listener(*listener)
|
|
101
|
-
channel_initializer.add_listener(*listener)
|
|
53
|
+
def log_requests?
|
|
54
|
+
@log_requests ||= begin
|
|
55
|
+
value = @options[:log_requests]
|
|
56
|
+
value.nil? ? DEFAULT_LOG_REQUESTS : value
|
|
57
|
+
end
|
|
102
58
|
end
|
|
103
|
-
|
|
104
|
-
# def all_exist?(*files)
|
|
105
|
-
# files.all? { |f| File.exist?(f) }
|
|
106
|
-
# end
|
|
107
|
-
|
|
108
|
-
# def init_ssl_context(certificate, private_key)
|
|
109
|
-
# return certificate_key_pair(certificate, private_key) if all_exist?(certificate, private_key)
|
|
110
|
-
# options[:use_jdk_ssl_provider] ? jdk_ssl_provider : self_signed_certificate
|
|
111
|
-
# end
|
|
112
59
|
end
|
|
113
60
|
# module ServerInstanceMethods
|
|
114
61
|
end
|
|
@@ -36,6 +36,15 @@ module WebSocket
|
|
|
36
36
|
channel_initializer.ssl_context = context unless context.nil?
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def all_exist?(*files)
|
|
40
|
+
files.all? { |f| File.exist?(f) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def init_ssl_context(certificate, private_key)
|
|
44
|
+
return certificate_key_pair(certificate, private_key) if all_exist?(certificate, private_key)
|
|
45
|
+
options[:use_jdk_ssl_provider] ? jdk_ssl_provider : self_signed_certificate
|
|
46
|
+
end
|
|
47
|
+
|
|
39
48
|
def ssl_context
|
|
40
49
|
@ssl_context ||= init_ssl_context(options[:ssl_certificate_file_path], options[:ssl_private_key_file_path])
|
|
41
50
|
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
|
-
|
|
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(
|
|
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
|
data/lib/websocket/version.rb
CHANGED
data/lib/websocket_client.rb
CHANGED
data/lib/websocket_server.rb
CHANGED
|
@@ -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.
|
|
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-
|
|
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
|
|
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
|
|
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
|