em-midori 0.1.1 → 0.1.2
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/em-midori.rb +2 -0
- data/lib/em-midori/api.rb +5 -1
- data/lib/em-midori/api_engine.rb +5 -5
- data/lib/em-midori/clean_room.rb +3 -3
- data/lib/em-midori/configure.rb +1 -1
- data/lib/em-midori/const.rb +3 -3
- data/lib/em-midori/core_ext/proc.rb +8 -0
- data/lib/em-midori/error.rb +3 -1
- data/lib/em-midori/request.rb +3 -3
- data/lib/em-midori/sandbox.rb +30 -0
- data/lib/em-midori/server.rb +10 -8
- data/lib/em-midori/version.rb +1 -1
- data/lib/em-midori/websocket.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f38d205f0e4f20a31cfdec6103d2f51367dc4f8
|
4
|
+
data.tar.gz: 5edb796b384fdf26b0f2ad2e1e4c7d4ff74308b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1fb15aa76bac728a030b5f2989c401cddd29a279505fd51c9b52c6c74c3c00759336edcc091cc864b7f3cab060de7bbf7de3c0e77cc2019e62e4cc48cee3f15
|
7
|
+
data.tar.gz: c3dd1c67a230b4a3de6d5b7e1a41d225021728c50951d4993703c1579d2e2c18086bd5ec8ba144023acdff81c403938b4b2c3a00a5be43f2f2422461ac511fcb
|
data/lib/em-midori.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative 'em-midori/core_ext/configurable'
|
|
11
11
|
require_relative 'em-midori/core_ext/string'
|
12
12
|
require_relative 'em-midori/core_ext/promise'
|
13
13
|
require_relative 'em-midori/core_ext/define_class'
|
14
|
+
require_relative 'em-midori/core_ext/proc'
|
14
15
|
|
15
16
|
require_relative 'em-midori/version'
|
16
17
|
require_relative 'em-midori/const'
|
@@ -21,6 +22,7 @@ require_relative 'em-midori/response'
|
|
21
22
|
require_relative 'em-midori/api'
|
22
23
|
require_relative 'em-midori/api_engine'
|
23
24
|
require_relative 'em-midori/route'
|
25
|
+
require_relative 'em-midori/sandbox'
|
24
26
|
require_relative 'em-midori/server'
|
25
27
|
require_relative 'em-midori/websocket'
|
26
28
|
require_relative 'em-midori/eventsource'
|
data/lib/em-midori/api.rb
CHANGED
@@ -107,7 +107,7 @@ class Midori::API
|
|
107
107
|
# puts 'Hello World'
|
108
108
|
# end
|
109
109
|
def eventsource(path, &block) end
|
110
|
-
|
110
|
+
|
111
111
|
# Mount a route prefix with another API defined
|
112
112
|
# @param [String] prefix prefix of the route String
|
113
113
|
# @param [Class] api inherited from Midori::API
|
@@ -117,6 +117,10 @@ class Midori::API
|
|
117
117
|
@routes[:MOUNT] << [prefix, api]
|
118
118
|
end
|
119
119
|
|
120
|
+
def capture(error, &block)
|
121
|
+
Midori::Sandbox.add_rule(error, block)
|
122
|
+
end
|
123
|
+
|
120
124
|
# Implementation of route DSL
|
121
125
|
# @param [ String ] method HTTP method
|
122
126
|
# @param [ String, Regexp ] path path definition
|
data/lib/em-midori/api_engine.rb
CHANGED
@@ -56,16 +56,16 @@ class Midori::APIEngine
|
|
56
56
|
# Send 101 Switching Protocol
|
57
57
|
connection.send_data Midori::Response.new(101, Midori::APIEngine.websocket_header(request.header['Sec-WebSocket-Key']), '')
|
58
58
|
connection.websocket.request = request
|
59
|
-
|
59
|
+
Midori::Sandbox.run(clean_room, route.function, connection.websocket)
|
60
60
|
return Midori::Response.new
|
61
61
|
elsif request.eventsource?
|
62
62
|
connection.send_data Midori::Response.new(200, Midori::Const::EVENTSOURCE_HEADER, '')
|
63
|
-
|
63
|
+
Midori::Sandbox.run(clean_room, route.function, connection.eventsource)
|
64
64
|
return Midori::Response.new
|
65
65
|
else
|
66
|
-
result =
|
67
|
-
clean_room.body = result
|
68
|
-
response = clean_room.raw_response
|
66
|
+
result = Midori::Sandbox.run(clean_room, route.function)
|
67
|
+
clean_room.body = result unless result.nil?
|
68
|
+
response = (result.is_a?Midori::Response) ? result : clean_room.raw_response
|
69
69
|
route.middlewares.reverse_each { |middleware| response = middleware.after(request, response) }
|
70
70
|
return response
|
71
71
|
end
|
data/lib/em-midori/clean_room.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
##
|
2
2
|
# This class is used to be sandbox of requests processing.
|
3
|
-
# @attr [Fixnum]
|
3
|
+
# @attr [Fixnum] status HTTP response code
|
4
4
|
# @attr [Hash] header HTTP response header
|
5
|
-
# @attr [Object] body HTTP response body. String could is accepted by default, but could leave for further process with +Midori::
|
5
|
+
# @attr [Object] body HTTP response body. String could is accepted by default, but could leave for further process with +Midori::Middleware+
|
6
6
|
# @attr [Midori::Request] request HTTP request
|
7
7
|
class Midori::CleanRoom
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :status, :header, :body, :request
|
9
9
|
# @param [Midori::Request] request HTTP request
|
10
10
|
def initialize(request)
|
11
11
|
@status = 200
|
data/lib/em-midori/configure.rb
CHANGED
data/lib/em-midori/const.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
##
|
2
|
-
# Module for store Midori
|
2
|
+
# Module for store Midori Const
|
3
3
|
module Midori::Const
|
4
4
|
# Hash table for converting numbers to HTTP/1.1 status code line
|
5
5
|
STATUS_CODE = {
|
@@ -51,14 +51,14 @@ module Midori::Const
|
|
51
51
|
'Server' => "Midori/#{Midori::VERSION}"
|
52
52
|
}
|
53
53
|
|
54
|
-
# Default header for
|
54
|
+
# Default header for EventSource response
|
55
55
|
EVENTSOURCE_HEADER = {
|
56
56
|
'Content-Type' => 'text-event-stream',
|
57
57
|
'Cache-Control' => 'no-cache',
|
58
58
|
'Connection' => 'keep-alive'
|
59
59
|
}
|
60
60
|
|
61
|
-
# Default header for
|
61
|
+
# Default header for WebSocket response
|
62
62
|
WEBSOCKET_HEADER = {
|
63
63
|
'Upgrade' => 'websocket',
|
64
64
|
'Connection' => 'Upgrade'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Proc
|
2
|
+
# @note Converting {Proc} to {Lambda} may have incorrect behaviours on corner cases.
|
3
|
+
# @note See {Ruby Language Issues}[https://bugs.ruby-lang.org/issues/7314] for more details.
|
4
|
+
def to_lambda (instance = Object.new)
|
5
|
+
instance.define_singleton_method(:_, &self)
|
6
|
+
instance.method(:_).to_proc
|
7
|
+
end
|
8
|
+
end
|
data/lib/em-midori/error.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
##
|
2
|
-
# This module store errors to be handled
|
2
|
+
# This module store errors to be handled inside Midori
|
3
3
|
module Midori::Error
|
4
4
|
# No route matched
|
5
5
|
class NotFound < StandardError; end
|
6
|
+
# Internal Error
|
7
|
+
class InternalError < StandardError; end
|
6
8
|
# Midori doesn't support continuous frame of WebSockets yet
|
7
9
|
class ContinuousFrame < StandardError; end
|
8
10
|
# WebSocket OpCode not defined in RFC standards
|
data/lib/em-midori/request.rb
CHANGED
@@ -54,19 +54,19 @@ class Midori::Request
|
|
54
54
|
@parsed = true
|
55
55
|
end
|
56
56
|
|
57
|
-
#
|
57
|
+
# Syntactic sugar for whether a request is parsed
|
58
58
|
# @return [Boolean] parsed or not
|
59
59
|
def parsed?
|
60
60
|
@parsed
|
61
61
|
end
|
62
62
|
|
63
|
-
#
|
63
|
+
# Syntactic sugar for whether a request is a websocket request
|
64
64
|
# @return [Boolean] websocket or not
|
65
65
|
def websocket?
|
66
66
|
@is_websocket
|
67
67
|
end
|
68
68
|
|
69
|
-
#
|
69
|
+
# Syntactic sugar for whether a request is an eventsource request
|
70
70
|
# @return [Boolean] eventsource or not
|
71
71
|
def eventsource?
|
72
72
|
@is_eventsource
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Midori::Sandbox
|
2
|
+
class << self
|
3
|
+
def class_initialize
|
4
|
+
@handlers = Hash.new
|
5
|
+
@handlers[Midori::Error::InternalError] = proc {|_e| Midori::Response.new(500, {}, 'Internal Server Error')}
|
6
|
+
@handlers[Midori::Error::NotFound] = proc {|_e| Midori::Response.new(404, {}, '404 Not Found')}
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_rule(class_name, block)
|
10
|
+
@handlers[class_name] = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def capture(error)
|
14
|
+
if @handlers[error.class].nil?
|
15
|
+
@handlers[Midori::Error::InternalError].call(error)
|
16
|
+
else
|
17
|
+
@handlers[error.class].call(error)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(clean_room, function, *args)
|
22
|
+
begin
|
23
|
+
function.to_lambda(clean_room).call(*args)
|
24
|
+
rescue StandardError => e
|
25
|
+
capture(e)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
class_initialize
|
30
|
+
end
|
data/lib/em-midori/server.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
##
|
2
|
-
#
|
2
|
+
# Logic to EventMachine TCP Server, running inside +EM::Connection+
|
3
3
|
# @attr [Midori::Request] request
|
4
4
|
# @attr [Class] api inherited from Midori::API
|
5
5
|
# @attr [Midori::WebSocket] websocket websocket instance
|
@@ -17,7 +17,7 @@ module Midori::Server
|
|
17
17
|
@eventsource = Midori::EventSource.new(self)
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
20
|
+
# Logic of receiving data
|
21
21
|
# @param [String] data raw data
|
22
22
|
def receive_data(data)
|
23
23
|
lambda do
|
@@ -37,17 +37,17 @@ module Midori::Server
|
|
37
37
|
end.call
|
38
38
|
end
|
39
39
|
|
40
|
-
#
|
40
|
+
# Logic of receiving new request
|
41
41
|
# @param [String] data raw data
|
42
42
|
def receive_new_request(data)
|
43
43
|
begin
|
44
44
|
@request.parse(data)
|
45
45
|
@response = @api.receive(request, self)
|
46
46
|
call_event(:open) if @request.websocket?
|
47
|
-
rescue Midori::Error::NotFound =>
|
48
|
-
@response = Midori::
|
47
|
+
rescue Midori::Error::NotFound => e
|
48
|
+
@response = Midori::Sandbox.capture(e)
|
49
49
|
rescue => e
|
50
|
-
@response = Midori::
|
50
|
+
@response = Midori::Sandbox.capture(e)
|
51
51
|
@logger.error e.inspect.red
|
52
52
|
@logger.warn e.backtrace.join("\n").yellow
|
53
53
|
end
|
@@ -57,7 +57,7 @@ module Midori::Server
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
60
|
+
# Logic of receiving WebSocket request
|
61
61
|
# @param [StringIO] data raw data
|
62
62
|
def websocket_request(data)
|
63
63
|
@websocket.decode(data)
|
@@ -76,7 +76,9 @@ module Midori::Server
|
|
76
76
|
close_connection_after_writing
|
77
77
|
rescue Midori::Error::PingPongSizeTooLarge => e
|
78
78
|
@logger.warn e.inspect.yellow
|
79
|
-
call_event(:error) #
|
79
|
+
call_event(:error) # Too large ping request
|
80
|
+
send_data "\b" # Opcode 0x8
|
81
|
+
close_connection_after_writing
|
80
82
|
rescue => e
|
81
83
|
call_event(:error)
|
82
84
|
@logger.error e.inspect.red
|
data/lib/em-midori/version.rb
CHANGED
data/lib/em-midori/websocket.rb
CHANGED
@@ -14,7 +14,7 @@ class Midori::WebSocket
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# Decode raw data send from client
|
17
|
-
# @param [
|
17
|
+
# @param [StringIO] data raw data
|
18
18
|
def decode(data)
|
19
19
|
# Fin and Opcode
|
20
20
|
byte_tmp = data.getbyte
|
@@ -29,7 +29,7 @@ class Midori::WebSocket
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# Decode masked message send from client
|
32
|
-
# @param [
|
32
|
+
# @param [StringIO] data raw data
|
33
33
|
def decode_mask(data)
|
34
34
|
# Mask
|
35
35
|
byte_tmp = data.getbyte
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-midori
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HeckPsi Lab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/em-midori/const.rb
|
70
70
|
- lib/em-midori/core_ext/configurable.rb
|
71
71
|
- lib/em-midori/core_ext/define_class.rb
|
72
|
+
- lib/em-midori/core_ext/proc.rb
|
72
73
|
- lib/em-midori/core_ext/promise.rb
|
73
74
|
- lib/em-midori/core_ext/string.rb
|
74
75
|
- lib/em-midori/error.rb
|
@@ -78,6 +79,7 @@ files:
|
|
78
79
|
- lib/em-midori/response.rb
|
79
80
|
- lib/em-midori/route.rb
|
80
81
|
- lib/em-midori/runner.rb
|
82
|
+
- lib/em-midori/sandbox.rb
|
81
83
|
- lib/em-midori/server.rb
|
82
84
|
- lib/em-midori/version.rb
|
83
85
|
- lib/em-midori/websocket.rb
|