midori.rb 0.6.0 → 0.7.0
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/ext/midori/websocket.c +34 -8
- data/lib/midori.rb +1 -1
- data/lib/midori/configure.rb +1 -0
- data/lib/midori/connection.rb +4 -3
- data/lib/midori/core_ext/{tcp_server.rb → socket.rb} +9 -2
- data/lib/midori/runner.rb +12 -3
- data/lib/midori/server.rb +1 -2
- data/lib/midori/version.rb +1 -1
- data/lib/midori/websocket.rb +6 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6d14d7e6c7a05f01d72029dc8d09ad83c37328d392d8c745b938025181d9812
|
4
|
+
data.tar.gz: dc2d8754f72ff25354f33fd0a15a0e23a1617eaa4a82ec94b21f9e47b2ed5eda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f4bf5b25cb38d3f5b8cf2a8f685956086d920ccc9cee3c838cc1fc3a94c1e482576f193d4d6c03505104b32d403a959da924e7243105f87b5faebc5d2d17b3e
|
7
|
+
data.tar.gz: cc1e70247c020875415d73e2bba4190c9f33c3ad52dacff0574eb89b5a6f3e1ee2c68efbbd330e4af83e9b86270d64fb26ac27133a30a8ebe68ed0cbbfbffd07
|
data/ext/midori/websocket.c
CHANGED
@@ -1,32 +1,58 @@
|
|
1
1
|
#include <ruby.h>
|
2
|
+
#include <ruby/encoding.h>
|
2
3
|
|
3
4
|
VALUE Midori = Qnil;
|
4
5
|
VALUE MidoriWebSocket = Qnil;
|
5
6
|
|
6
7
|
void Init_midori_ext();
|
7
8
|
VALUE method_midori_websocket_mask(VALUE self, VALUE payload, VALUE mask);
|
9
|
+
VALUE method_midori_websocket_mask_str(VALUE self, VALUE payload, VALUE mask);
|
8
10
|
|
9
|
-
void Init_midori_ext()
|
11
|
+
void Init_midori_ext()
|
12
|
+
{
|
10
13
|
Midori = rb_define_module("Midori");
|
11
14
|
MidoriWebSocket = rb_define_class_under(Midori, "WebSocket", rb_cObject);
|
12
15
|
rb_define_protected_method(MidoriWebSocket, "mask", method_midori_websocket_mask, 2);
|
16
|
+
rb_define_protected_method(MidoriWebSocket, "mask_str", method_midori_websocket_mask_str, 2);
|
13
17
|
}
|
14
18
|
|
15
|
-
VALUE method_midori_websocket_mask(VALUE self, VALUE payload, VALUE mask)
|
19
|
+
VALUE method_midori_websocket_mask(VALUE self, VALUE payload, VALUE mask)
|
20
|
+
{
|
16
21
|
long n = RARRAY_LEN(payload), i, p, m;
|
17
22
|
VALUE unmasked = rb_ary_new2(n);
|
18
23
|
|
19
24
|
int mask_array[] = {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
};
|
25
|
+
NUM2INT(rb_ary_entry(mask, 0)),
|
26
|
+
NUM2INT(rb_ary_entry(mask, 1)),
|
27
|
+
NUM2INT(rb_ary_entry(mask, 2)),
|
28
|
+
NUM2INT(rb_ary_entry(mask, 3))};
|
25
29
|
|
26
|
-
for (i = 0; i < n; i++)
|
30
|
+
for (i = 0; i < n; i++)
|
31
|
+
{
|
27
32
|
p = NUM2INT(rb_ary_entry(payload, i));
|
28
33
|
m = mask_array[i % 4];
|
29
34
|
rb_ary_store(unmasked, i, INT2NUM(p ^ m));
|
30
35
|
}
|
31
36
|
return unmasked;
|
32
37
|
}
|
38
|
+
|
39
|
+
VALUE method_midori_websocket_mask_str(VALUE self, VALUE payload, VALUE mask)
|
40
|
+
{
|
41
|
+
long n = RARRAY_LEN(payload), i, p, m;
|
42
|
+
char result[n];
|
43
|
+
|
44
|
+
int mask_array[] = {
|
45
|
+
NUM2INT(rb_ary_entry(mask, 0)),
|
46
|
+
NUM2INT(rb_ary_entry(mask, 1)),
|
47
|
+
NUM2INT(rb_ary_entry(mask, 2)),
|
48
|
+
NUM2INT(rb_ary_entry(mask, 3))};
|
49
|
+
|
50
|
+
for (i = 0; i < n; i++)
|
51
|
+
{
|
52
|
+
p = NUM2INT(rb_ary_entry(payload, i));
|
53
|
+
m = mask_array[i % 4];
|
54
|
+
result[i] = p ^ m;
|
55
|
+
}
|
56
|
+
|
57
|
+
return rb_enc_str_new(result, n, rb_utf8_encoding());
|
58
|
+
}
|
data/lib/midori.rb
CHANGED
@@ -13,8 +13,8 @@ require_relative 'midori/core_ext/configurable'
|
|
13
13
|
require_relative 'midori/core_ext/define_class'
|
14
14
|
require_relative 'midori/core_ext/http_header'
|
15
15
|
require_relative 'midori/core_ext/proc'
|
16
|
+
require_relative 'midori/core_ext/socket'
|
16
17
|
require_relative 'midori/core_ext/string'
|
17
|
-
require_relative 'midori/core_ext/tcp_server'
|
18
18
|
|
19
19
|
require_relative 'midori/version'
|
20
20
|
|
data/lib/midori/configure.rb
CHANGED
@@ -13,6 +13,7 @@ class Midori::Configure
|
|
13
13
|
set :trusted_proxies, /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|
|
14
14
|
\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/ix
|
15
15
|
set :tcp_fast_open, true
|
16
|
+
set :socket_reuse_port, false
|
16
17
|
set :keep_alive, true
|
17
18
|
set :keep_alive_timeout, 75
|
18
19
|
set :keep_alive_requests, 1000
|
data/lib/midori/connection.rb
CHANGED
@@ -11,15 +11,16 @@ class Midori::Connection
|
|
11
11
|
# @param [IO] socket raw socket
|
12
12
|
def initialize(socket)
|
13
13
|
@registered = false
|
14
|
-
@socket = socket
|
14
|
+
@socket = socket[0]
|
15
|
+
@peer_addr = socket[1].ip_unpack
|
15
16
|
@monitor = nil
|
16
17
|
@close_flag = false
|
17
18
|
@buffer = ''
|
18
|
-
listen(socket)
|
19
|
+
listen(@socket)
|
19
20
|
end
|
20
21
|
|
21
22
|
# Register events of connection
|
22
|
-
# @param [
|
23
|
+
# @param [Array] socket raw socket
|
23
24
|
def listen(socket)
|
24
25
|
EventLoop.register(socket, :rw) do |monitor|
|
25
26
|
@monitor = monitor
|
@@ -1,9 +1,16 @@
|
|
1
|
-
class
|
1
|
+
class Socket
|
2
2
|
def tcp_fast_open
|
3
3
|
# macOS devices option is DIFFERENT from Linux and FreeBSD
|
4
4
|
opt = (/darwin/ =~ RUBY_PLATFORM) ? 1 : 5
|
5
5
|
# Magic number 6 may refer to Socket::SOL_TCP or Socket::IPPROTO_TCP
|
6
|
-
|
6
|
+
setsockopt(6, Socket::TCP_FASTOPEN, opt)
|
7
|
+
true
|
8
|
+
rescue => _e
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def reuse_port
|
13
|
+
setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1)
|
7
14
|
true
|
8
15
|
rescue => _e
|
9
16
|
false
|
data/lib/midori/runner.rb
CHANGED
@@ -30,9 +30,7 @@ class Midori::Runner
|
|
30
30
|
def start
|
31
31
|
return false if running? || EventLoop.running?
|
32
32
|
@logger.info "Midori #{Midori::VERSION} is now running on #{bind}:#{port}".blue
|
33
|
-
|
34
|
-
tfo = @server.tcp_fast_open if Midori::Configure.tcp_fast_open
|
35
|
-
@logger.warn 'Failed to use TCP Fast Open feature on your OS'.yellow unless tfo
|
33
|
+
init_socket
|
36
34
|
async_fiber(Fiber.new do
|
37
35
|
@logger.info 'Midori is booting...'.blue
|
38
36
|
@before.call
|
@@ -47,6 +45,17 @@ class Midori::Runner
|
|
47
45
|
nil
|
48
46
|
end
|
49
47
|
|
48
|
+
private def init_socket
|
49
|
+
@server = Socket.new Socket::AF_INET, Socket::SOCK_STREAM
|
50
|
+
@server.reuse_port if Midori::Configure.socket_reuse_port
|
51
|
+
@server.bind Addrinfo.tcp @bind, @port
|
52
|
+
@server.listen Socket::SOMAXCONN
|
53
|
+
if Midori::Configure.tcp_fast_open
|
54
|
+
tfo = @server.tcp_fast_open
|
55
|
+
@logger.warn 'Failed to use TCP Fast Open feature on your OS'.yellow unless tfo
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
50
59
|
# Stop the Midori server
|
51
60
|
# @note This is an async method, but no callback
|
52
61
|
# @return [Boolean] [true] stop successfully
|
data/lib/midori/server.rb
CHANGED
@@ -32,8 +32,7 @@ module Midori::Server
|
|
32
32
|
def receive_data(monitor)
|
33
33
|
async_fiber(Fiber.new do
|
34
34
|
begin
|
35
|
-
|
36
|
-
@request.ip, @request.port = remote_port, remote_ip
|
35
|
+
@request.ip, @request.port = @peer_addr
|
37
36
|
data = monitor.io.read_nonblock(16_384)
|
38
37
|
if @request.parsed? && @request.body_parsed?
|
39
38
|
websocket_request(StringIO.new(data))
|
data/lib/midori/version.rb
CHANGED
data/lib/midori/websocket.rb
CHANGED
@@ -24,7 +24,7 @@ class Midori::WebSocket
|
|
24
24
|
@opcode = byte_tmp & 0b00001111
|
25
25
|
# NOT Support Multiple Fragments
|
26
26
|
raise Midori::Exception::ContinuousFrame unless fin
|
27
|
-
raise Midori::Exception::OpCodeError unless [0x1, 0x2, 0x8, 0x9, 0xA].include? opcode
|
27
|
+
raise Midori::Exception::OpCodeError unless [0x1, 0x2, 0x8, 0x9, 0xA].include? @opcode
|
28
28
|
close if @opcode == 0x8 # Close Frame
|
29
29
|
# return if @opcode == 0x9 || @opcode == 0xA # Ping Pong
|
30
30
|
decode_mask(data)
|
@@ -42,8 +42,11 @@ class Midori::WebSocket
|
|
42
42
|
mask = Array.new(4) { data.getbyte }
|
43
43
|
# Message
|
44
44
|
masked_msg = Array.new(payload) { data.getbyte }
|
45
|
-
|
46
|
-
|
45
|
+
if [0x1, 0x9, 0xA].include? opcode
|
46
|
+
@msg = mask_str(masked_msg, mask)
|
47
|
+
else # [0x2]
|
48
|
+
@msg = mask(masked_msg, mask)
|
49
|
+
end
|
47
50
|
# For debug
|
48
51
|
# data.rewind
|
49
52
|
# data.bytes {|byte| puts byte.to_s(16)}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: midori.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HeckPsi Lab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: murasaki
|
@@ -91,8 +91,8 @@ files:
|
|
91
91
|
- lib/midori/core_ext/define_class.rb
|
92
92
|
- lib/midori/core_ext/http_header.rb
|
93
93
|
- lib/midori/core_ext/proc.rb
|
94
|
+
- lib/midori/core_ext/socket.rb
|
94
95
|
- lib/midori/core_ext/string.rb
|
95
|
-
- lib/midori/core_ext/tcp_server.rb
|
96
96
|
- lib/midori/env.rb
|
97
97
|
- lib/midori/eventsource.rb
|
98
98
|
- lib/midori/exception.rb
|
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
133
|
version: '0'
|
134
134
|
requirements: []
|
135
135
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.7.
|
136
|
+
rubygems_version: 2.7.7
|
137
137
|
signing_key:
|
138
138
|
specification_version: 4
|
139
139
|
summary: High performance ruby web framework
|