midori.rb 0.6.0 → 0.7.0

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: ccffda67e06a88ed46a9e81ac52823498d331a147869f54a3c520bc70946f469
4
- data.tar.gz: 2abeba1e323655b28a547814eccc536773b35316075b3852897ec109b4272719
3
+ metadata.gz: f6d14d7e6c7a05f01d72029dc8d09ad83c37328d392d8c745b938025181d9812
4
+ data.tar.gz: dc2d8754f72ff25354f33fd0a15a0e23a1617eaa4a82ec94b21f9e47b2ed5eda
5
5
  SHA512:
6
- metadata.gz: d68c112f68c228a79b46f2983e0bd4ba9b0ff25b8aa9025eca7893909719e7213a8236fca26d78ba2aad12926481d7f989d920148e00b866f9f86c8a6b3cff20
7
- data.tar.gz: 6eae1c01af1fa93acf6bf817ce1c04121918a53d1f849815778eed0f974c36259bd1ee6df3901b86128d247b77dfca5c81e04e5e1477836aa2dd31c0c2a1061e
6
+ metadata.gz: 0f4bf5b25cb38d3f5b8cf2a8f685956086d920ccc9cee3c838cc1fc3a94c1e482576f193d4d6c03505104b32d403a959da924e7243105f87b5faebc5d2d17b3e
7
+ data.tar.gz: cc1e70247c020875415d73e2bba4190c9f33c3ad52dacff0574eb89b5a6f3e1ee2c68efbbd330e4af83e9b86270d64fb26ac27133a30a8ebe68ed0cbbfbffd07
@@ -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
- NUM2INT(rb_ary_entry(mask, 0)),
21
- NUM2INT(rb_ary_entry(mask, 1)),
22
- NUM2INT(rb_ary_entry(mask, 2)),
23
- NUM2INT(rb_ary_entry(mask, 3))
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
 
@@ -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
@@ -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 [IO] socket raw socket
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 TCPServer
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
- self.setsockopt(6, Socket::TCP_FASTOPEN, opt)
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
- @server = TCPServer.new(@bind, @port)
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
- _sock_domain, remote_port, _remote_hostname, remote_ip = monitor.io.peeraddr
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))
@@ -1,5 +1,5 @@
1
1
  # Midori Module
2
2
  module Midori
3
3
  # Current Version Code
4
- VERSION = '0.6.0'.freeze
4
+ VERSION = '0.7.0'.freeze
5
5
  end
@@ -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
- @msg = self.mask(masked_msg, mask)
46
- @msg = @msg.pack('C*').force_encoding('utf-8') if [0x1, 0x9, 0xA].include? opcode
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.6.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-06-29 00:00:00.000000000 Z
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.6
136
+ rubygems_version: 2.7.7
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: High performance ruby web framework