em-midori 0.1.6.1 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/midori/api.rb +25 -4
- data/lib/midori/api_engine.rb +10 -1
- data/lib/midori/clean_room.rb +2 -0
- data/lib/midori/core_ext/proc.rb +7 -2
- data/lib/midori/core_ext/promise.rb +14 -7
- data/lib/midori/core_ext/promise_exception.rb +7 -1
- data/lib/midori/core_ext/safe_require.rb +4 -1
- data/lib/midori/eventsource.rb +1 -0
- data/lib/midori/extension/file.rb +6 -0
- data/lib/midori/extension/ohm.rb +6 -2
- data/lib/midori/extension/postgres.rb +21 -0
- data/lib/midori/extension/redis.rb +11 -0
- data/lib/midori/extension/sequel.rb +11 -9
- data/lib/midori/middleware.rb +3 -0
- data/lib/midori/request.rb +5 -1
- data/lib/midori/response.rb +4 -3
- data/lib/midori/route.rb +2 -0
- data/lib/midori/runner.rb +5 -0
- data/lib/midori/sandbox.rb +16 -0
- data/lib/midori/server.rb +9 -4
- data/lib/midori/version.rb +1 -1
- data/lib/midori/websocket.rb +15 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b8f1d0f52bac821c37368d97470d9babb3a5666
|
4
|
+
data.tar.gz: 50c9efd29749da9a5f12eaf3b769169b754d7024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 539fd19c14ec8a1bfbde7f4c2f8d01c41f29db187377ec8e7c0b56ab60aec097d4957067c43fb1525ed8b55c85da5315e20f73be02ba69903cf3b4c49d91ab44
|
7
|
+
data.tar.gz: 112bb41011fc2bf23aaf83ec10f92433f7b9bc29b7fd2b57b877dd4fad0cbf414cc1cde2717edde005403ec8c3924a96a96ee315031d720055b2687a482b9cd2
|
data/lib/midori/api.rb
CHANGED
@@ -2,7 +2,14 @@
|
|
2
2
|
# This class provides methods to be inherited as route definition.
|
3
3
|
class Midori::API
|
4
4
|
class << self
|
5
|
+
# @!attribute routes
|
6
|
+
# @return [Hash] merged routes defined in the instance
|
7
|
+
# @!attribute scope_middlewares
|
8
|
+
# @return [Array] global middlewares under the scope
|
5
9
|
attr_accessor :routes, :scope_middlewares
|
10
|
+
|
11
|
+
# Init private variables of class
|
12
|
+
# @return [ nil ] nil
|
6
13
|
def class_initialize
|
7
14
|
@routes = {
|
8
15
|
GET: [],
|
@@ -18,6 +25,7 @@ class Midori::API
|
|
18
25
|
}
|
19
26
|
@scope_middlewares = []
|
20
27
|
@temp_middlewares = []
|
28
|
+
nil
|
21
29
|
end
|
22
30
|
|
23
31
|
# Add GET method as a DSL for route definition
|
@@ -109,16 +117,26 @@ class Midori::API
|
|
109
117
|
def eventsource(path, &block) end
|
110
118
|
|
111
119
|
# Mount a route prefix with another API defined
|
112
|
-
# @param [String] prefix prefix of the route String
|
113
|
-
# @param [Class] api inherited from Midori::API
|
114
|
-
# @return [nil] nil
|
120
|
+
# @param [ String ] prefix prefix of the route String
|
121
|
+
# @param [ Class ] api inherited from Midori::API
|
122
|
+
# @return [ nil ] nil
|
115
123
|
def mount(prefix, api)
|
116
124
|
raise ArgumentError if prefix == '/' # Cannot mount route API
|
117
125
|
@routes[:MOUNT] << [prefix, api]
|
126
|
+
nil
|
118
127
|
end
|
119
128
|
|
129
|
+
# Definitions for global error handler
|
130
|
+
# @param [ Class ] error Error class, must be inherited form StandardError
|
131
|
+
# @yield what to do to deal with error
|
132
|
+
# @yieldparam [ StandardError ] e the detailed error
|
133
|
+
# @example Basic Usage
|
134
|
+
# capture Midori::InternalError do |e|
|
135
|
+
# Midori::Response(500, {}, e.backtrace)
|
136
|
+
# end
|
120
137
|
def capture(error, &block)
|
121
138
|
Midori::Sandbox.add_rule(error, block)
|
139
|
+
nil
|
122
140
|
end
|
123
141
|
|
124
142
|
# Implementation of route DSL
|
@@ -149,6 +167,9 @@ class Midori::API
|
|
149
167
|
nil
|
150
168
|
end
|
151
169
|
|
170
|
+
# Use a middleware in the next route
|
171
|
+
# @param [Class] middleware Inherited from +Midori::Middleware+
|
172
|
+
# @return [nil] nil
|
152
173
|
def filter(middleware, *args)
|
153
174
|
middleware = middleware.new(*args)
|
154
175
|
@temp_middlewares << middleware
|
@@ -169,7 +190,7 @@ class Midori::API
|
|
169
190
|
end
|
170
191
|
end
|
171
192
|
|
172
|
-
private_class_method :add_route
|
193
|
+
private_class_method :add_route, :inherited
|
173
194
|
|
174
195
|
# Constants of supported methods in route definition
|
175
196
|
METHODS = %w(get post put delete options link unlink websocket eventsource).freeze
|
data/lib/midori/api_engine.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
+
##
|
2
|
+
# Merge and manage all APIs.
|
3
|
+
# @attr [ Hash ] routes A hash of all routes merged
|
1
4
|
class Midori::APIEngine
|
2
5
|
attr_accessor :routes
|
6
|
+
|
7
|
+
# Init an API Engine
|
8
|
+
# @param [ Class ] root_api API inherited from [ Midori::API ]
|
9
|
+
# @param [ Symbol ] type type mustermann support
|
3
10
|
def initialize(root_api, type = :sinatra)
|
4
11
|
@routes = {
|
5
12
|
GET: [],
|
@@ -23,8 +30,8 @@ class Midori::APIEngine
|
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
33
|
+
# Merge all routes with a Depth-first search
|
26
34
|
def merge(prefix, root_api, middlewares)
|
27
|
-
# Merge all routes with a Depth-first search
|
28
35
|
root_api.routes[:MOUNT].each do |mount|
|
29
36
|
root_api.routes.merge!(merge(mount[0], mount[1], root_api.scope_middlewares)) do |_key, old_val, new_val|
|
30
37
|
old_val + new_val
|
@@ -81,4 +88,6 @@ class Midori::APIEngine
|
|
81
88
|
header['Sec-WebSocket-Accept'] = Digest::SHA1.base64digest(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
|
82
89
|
header
|
83
90
|
end
|
91
|
+
|
92
|
+
private :merge
|
84
93
|
end
|
data/lib/midori/clean_room.rb
CHANGED
data/lib/midori/core_ext/proc.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
##
|
2
|
+
# Meta-programming Proc for Syntactic Sugars
|
1
3
|
class Proc
|
2
|
-
#
|
4
|
+
# Convert [ Proc ] to [ Lambda ]
|
5
|
+
# @param [ Object ] instance the context
|
6
|
+
# @return [ Lambda ] Lambda converted
|
7
|
+
# @note Converting [Proc] to [Lambda] may have incorrect behaviours on corner cases.
|
3
8
|
# @note See {Ruby Language Issues}[https://bugs.ruby-lang.org/issues/7314] for more details.
|
4
9
|
def to_lambda (instance = Object.new)
|
5
10
|
instance.define_singleton_method(:_, &self)
|
6
11
|
instance.method(:_).to_proc
|
7
12
|
end
|
8
|
-
end
|
13
|
+
end
|
@@ -2,21 +2,25 @@
|
|
2
2
|
# Meta-programming String for Syntactic Sugars
|
3
3
|
# Referenced from {Qiita}[http://qiita.com/south37/items/99a60345b22ef395d424]
|
4
4
|
class Promise
|
5
|
-
#
|
5
|
+
# Init a Promise
|
6
|
+
# @param [ Proc ] callback an async method
|
6
7
|
def initialize(callback)
|
7
8
|
@callback = callback
|
8
9
|
end
|
9
10
|
|
10
11
|
# Define what to do after a method callbacks
|
11
|
-
# @param [Proc] resolve what on callback
|
12
|
-
# @param [Proc] reject what on callback failed
|
13
|
-
# @return [nil] nil
|
12
|
+
# @param [ Proc ] resolve what on callback
|
13
|
+
# @param [ Proc ] reject what on callback failed
|
14
|
+
# @return [ nil ] nil
|
14
15
|
def then(resolve = ->() {}, reject = ->() {})
|
15
16
|
@callback.call(resolve, reject)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
20
|
+
# A Syntactic Sugar for Promise
|
19
21
|
class DeferPromise < Promise
|
22
|
+
# A Syntactic Sugar for Promise
|
23
|
+
# @param [ proc ] deffered To do what asynchronous
|
20
24
|
def initialize(deffered)
|
21
25
|
super(->(resolve, _reject){
|
22
26
|
EventMachine.defer(proc {
|
@@ -32,7 +36,7 @@ end
|
|
32
36
|
|
33
37
|
module Kernel
|
34
38
|
# Logic dealing of async method
|
35
|
-
# @param [Fiber] fiber a fiber to call
|
39
|
+
# @param [ Fiber ] fiber a fiber to call
|
36
40
|
def async_internal(fiber)
|
37
41
|
chain = lambda do |result|
|
38
42
|
return unless result.is_a?Promise
|
@@ -44,7 +48,7 @@ module Kernel
|
|
44
48
|
end
|
45
49
|
|
46
50
|
# Define an async method
|
47
|
-
# @param [Symbol] method_name method name
|
51
|
+
# @param [ Symbol ] method_name method name
|
48
52
|
# @yield async method
|
49
53
|
# @example
|
50
54
|
# async :hello do
|
@@ -56,12 +60,15 @@ module Kernel
|
|
56
60
|
}
|
57
61
|
end
|
58
62
|
|
63
|
+
# Shortcut to init [ DeferPromise ]
|
64
|
+
# @yield To do what asynchronous
|
65
|
+
# @return [ DerferPromise ] instance
|
59
66
|
def defer(&block)
|
60
67
|
DeferPromise.new(block)
|
61
68
|
end
|
62
69
|
|
63
70
|
# Block the I/O to wait for async method response
|
64
|
-
# @param [Promise] promise promise method
|
71
|
+
# @param [ Promise ] promise promise method
|
65
72
|
# @example
|
66
73
|
# result = await SQL.query('SELECT * FROM hello')
|
67
74
|
def await(promise)
|
@@ -1,7 +1,13 @@
|
|
1
|
+
##
|
2
|
+
# A special error as containers of errors inside [ Promise ]
|
3
|
+
# @attr [ StandardError ] raw_exception raw execption raised
|
1
4
|
class PromiseException < StandardError
|
2
5
|
attr_reader :raw_exception
|
6
|
+
|
7
|
+
# Init PromiseException
|
8
|
+
# @param [ StandardError ] raw_exception raw execption raised
|
3
9
|
def initialize(raw_exception)
|
4
10
|
super(nil)
|
5
11
|
@raw_exception = raw_exception
|
6
12
|
end
|
7
|
-
end
|
13
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Kernel
|
2
|
+
# Raise error if Load Failed
|
3
|
+
# @param [ String ] file file to Load
|
4
|
+
# @param [ String ] prompt To prompt what when load error
|
2
5
|
def safe_require(file, prompt)
|
3
6
|
begin
|
4
7
|
require file
|
@@ -6,4 +9,4 @@ module Kernel
|
|
6
9
|
raise prompt
|
7
10
|
end
|
8
11
|
end
|
9
|
-
end
|
12
|
+
end
|
data/lib/midori/eventsource.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
##
|
2
|
+
# Midori Extension of File reading and writing
|
1
3
|
class Midori::File
|
2
4
|
class << self
|
5
|
+
# Same APIs as File.read
|
6
|
+
# @param [ Array ] args args of File.read
|
3
7
|
def read(*args)
|
4
8
|
await(defer{File.read(*args)})
|
5
9
|
end
|
6
10
|
|
11
|
+
# Same APIs as File.write
|
12
|
+
# @param [ Array ] args args of File.write
|
7
13
|
def write(*args)
|
8
14
|
await(defer{File.write(*args)})
|
9
15
|
end
|
data/lib/midori/extension/ohm.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
safe_require '
|
1
|
+
safe_require 'ohm', 'gem install ohm'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Midori Extension of ohm through meta programming Redic
|
2
5
|
class Redic
|
6
|
+
# Call a redis request asynchronously
|
7
|
+
# @param [ Array ] args args of Redic.call
|
3
8
|
def call(*args)
|
4
9
|
await(defer{
|
5
10
|
@client.connect do
|
@@ -9,4 +14,3 @@ class Redic
|
|
9
14
|
})
|
10
15
|
end
|
11
16
|
end
|
12
|
-
safe_require 'ohm', 'gem install ohm'
|
@@ -1,13 +1,23 @@
|
|
1
1
|
safe_require 'postgres-pr/message', 'gem install postgres-pr'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Midori Extension for Postgres Driver
|
5
|
+
# @attr [ Fixnum ] connected Connection Status
|
3
6
|
class Midori::Postgres
|
4
7
|
attr_reader :connected
|
5
8
|
|
9
|
+
# Init a Postgres Connection
|
10
|
+
# @param [ Array ] args args of EM.connect
|
6
11
|
def initialize(*args)
|
7
12
|
@connected = false
|
8
13
|
@db = EM.connect(*args, EM::P::Postgres3)
|
9
14
|
end
|
10
15
|
|
16
|
+
# Connect the Postgres server
|
17
|
+
# @param [ String ] db_name database name
|
18
|
+
# @param [ String ] username username
|
19
|
+
# @param [ password ] password password
|
20
|
+
# @return [ nil ] nil
|
11
21
|
def connect(db_name, username, password)
|
12
22
|
await(Promise.new(->(resolve, _reject) {
|
13
23
|
@db.connect(db_name, username, password).callback do |status|
|
@@ -17,6 +27,9 @@ class Midori::Postgres
|
|
17
27
|
}))
|
18
28
|
end
|
19
29
|
|
30
|
+
# Make SQL query
|
31
|
+
# @param [ String ] sql sql query
|
32
|
+
# @return [ Midori::Postgres::Result ] query result
|
20
33
|
def query(sql)
|
21
34
|
await(Promise.new(->(resolve, _reject) {
|
22
35
|
begin
|
@@ -29,8 +42,16 @@ class Midori::Postgres
|
|
29
42
|
end
|
30
43
|
end
|
31
44
|
|
45
|
+
##
|
46
|
+
# Postgres Result for Midori Postgres Driver Extension
|
47
|
+
# @attr [ Array ] result result if success
|
48
|
+
# @attr [ Array ] errors exceptions met
|
32
49
|
class Midori::Postgres::Result
|
33
50
|
attr_reader :result, :errors
|
51
|
+
|
52
|
+
# Init a Postgres Result
|
53
|
+
# @param [ Array ] result result if success
|
54
|
+
# @param [ Array ] errors exceptions met
|
34
55
|
def initialize(result, errors)
|
35
56
|
@result = result
|
36
57
|
@errors = errors
|
@@ -1,10 +1,19 @@
|
|
1
1
|
safe_require 'em-hiredis', 'gem install em-hiredis'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Midori Extension for Redis Driver
|
2
5
|
class Midori::Redis
|
6
|
+
|
7
|
+
# Init a Redis Connection
|
8
|
+
# @param [ Array ] args args EM::Hiredis.connect
|
3
9
|
def initialize(*args)
|
4
10
|
@connection = EM::Hiredis.connect(*args)
|
5
11
|
@connection
|
6
12
|
end
|
7
13
|
|
14
|
+
# Call a redis request asynchronously
|
15
|
+
# @param [ String ] sys method name
|
16
|
+
# @param [ Array ] args args of the method calling
|
8
17
|
def method_missing(sys, *args)
|
9
18
|
await(Promise.new(->(resolve, _reject) {
|
10
19
|
@connection.send(sys, *args).callback do |*ret_args|
|
@@ -13,6 +22,8 @@ class Midori::Redis
|
|
13
22
|
}))
|
14
23
|
end
|
15
24
|
|
25
|
+
# Return raw pubsub mode
|
26
|
+
# @return [ EM::Hiredis::Pubsub ] raw pubsub
|
16
27
|
def pubsub
|
17
28
|
@connection.pubsub
|
18
29
|
end
|
@@ -1,14 +1,16 @@
|
|
1
1
|
safe_require 'sequel', 'gem install sequel'
|
2
2
|
require 'sequel/adapters/postgres'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
##
|
5
|
+
# Midori Extension of sequel postgres through meta programming
|
6
|
+
class Sequel::Postgres::Adapter
|
7
|
+
# Call a sql request asynchronously
|
8
|
+
# @param [ String ] sql sql request
|
9
|
+
# @param [ Array ] args args to send
|
10
|
+
# @return [ Array ] sql query result
|
11
|
+
def execute_query(sql, args)
|
12
|
+
@db.log_connection_yield(sql, self, args) do
|
13
|
+
args ? await(defer{async_exec(sql, args)}) : await(defer{async_exec(sql)})
|
12
14
|
end
|
13
15
|
end
|
14
|
-
end
|
16
|
+
end
|
data/lib/midori/middleware.rb
CHANGED
@@ -20,6 +20,9 @@ class Midori::Middleware
|
|
20
20
|
response
|
21
21
|
end
|
22
22
|
|
23
|
+
# Dynamically generate a method to use inside router
|
24
|
+
# @param [ Symbol ] name name of the method
|
25
|
+
# @yield the block to run
|
23
26
|
def self.helper(name, &block)
|
24
27
|
Midori::CleanRoom.class_exec do
|
25
28
|
define_method(name, &block)
|
data/lib/midori/request.rb
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
# @attr [String] ip client ip address
|
4
4
|
# @attr [Fixnum] port client port
|
5
5
|
# @attr [String] protocol protocol version of HTTP request
|
6
|
+
# @attr [String] method HTTP method
|
6
7
|
# @attr [String] path request path
|
7
8
|
# @attr [String] query_string request query string
|
8
9
|
# @attr [Hash] header request header
|
9
10
|
# @attr [String] body request body
|
10
11
|
# @attr [Boolean] parsed whether the request parsed
|
12
|
+
# @attr [Hash] params params in the url
|
11
13
|
class Midori::Request
|
12
14
|
attr_accessor :ip, :port,
|
13
15
|
:protocol, :method, :path, :query_string,
|
@@ -29,7 +31,9 @@ class Midori::Request
|
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
# Init an request with
|
34
|
+
# Init an request with String data
|
35
|
+
# @param [ String ] data
|
36
|
+
# @return [ nil ] nil
|
33
37
|
def parse(data)
|
34
38
|
|
35
39
|
offset = @parser << data
|
data/lib/midori/response.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
##
|
2
2
|
# Class for midori response
|
3
|
-
# @attr [String] HTTP response status
|
4
|
-
# @attr [Hash] HTTP response header
|
5
|
-
# @attr [String] HTTP response body
|
3
|
+
# @attr [String] status HTTP response status
|
4
|
+
# @attr [Hash] header HTTP response header
|
5
|
+
# @attr [String] body HTTP response body
|
6
6
|
class Midori::Response
|
7
7
|
attr_accessor :status, :header, :body
|
8
8
|
|
9
9
|
# @param [Fixnum] code HTTP response code
|
10
10
|
# @param [Hash] header HTTP response header
|
11
11
|
# @param [String] body HTTP response body
|
12
|
+
# Init a Response
|
12
13
|
def initialize(code = 200, header = Midori::Const::DEFAULT_HEADER.clone, body = '')
|
13
14
|
@status = Midori::Const::STATUS_CODE[code]
|
14
15
|
@header = header
|
data/lib/midori/route.rb
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
# @attr [String] method HTTP method
|
4
4
|
# @attr [Regexp] path regex to match
|
5
5
|
# @attr [Proc] function what to do after matched
|
6
|
+
# @attr [Array<Class>] middlewares middlewares used in the route
|
6
7
|
class Midori::Route
|
7
8
|
attr_accessor :method, :path, :function, :middlewares
|
8
9
|
|
10
|
+
# Define a route
|
9
11
|
# @param [String] method HTTP method
|
10
12
|
# @param [Regexp] path regex to match
|
11
13
|
# @param [Proc] function what to do after matched
|
data/lib/midori/runner.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
##
|
2
2
|
# Abstract runner class to control instance of Midori Server
|
3
|
+
# @attr [ String ] bind the address to bind
|
4
|
+
# @attr [ Fixnum ] port the port to bind
|
3
5
|
class Midori::Runner
|
4
6
|
attr_reader :bind, :port
|
5
7
|
|
8
|
+
# Define status of a runner
|
9
|
+
# @param [ Class ] api inherited from [ Midori::API ]
|
10
|
+
# @param [ Class ] configure inherited from [ Midori::Configure ]
|
6
11
|
def initialize(api, configure = Midori::Configure)
|
7
12
|
@logger = configure.logger
|
8
13
|
@bind = configure.bind
|
data/lib/midori/sandbox.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
##
|
2
|
+
# Sandbox for global error capture
|
1
3
|
class Midori::Sandbox
|
2
4
|
class << self
|
3
5
|
def class_initialize
|
@@ -6,10 +8,18 @@ class Midori::Sandbox
|
|
6
8
|
@handlers[Midori::Exception::NotFound] = proc {|_e| Midori::Response.new(404, {}, '404 Not Found')}
|
7
9
|
end
|
8
10
|
|
11
|
+
# Add a rule to Sandbox
|
12
|
+
# @param [ Class ] class_name the class to capture
|
13
|
+
# @param [ Proc ] block what to do when captured
|
14
|
+
# @return [ nil ] nil
|
9
15
|
def add_rule(class_name, block)
|
10
16
|
@handlers[class_name] = block
|
17
|
+
nil
|
11
18
|
end
|
12
19
|
|
20
|
+
# Detect what to run with given error
|
21
|
+
# @param [ StandardError ] error the error captured
|
22
|
+
# @return [ nil ] nil
|
13
23
|
def capture(error)
|
14
24
|
if @handlers[error.class].nil?
|
15
25
|
@handlers[Midori::Exception::InternalError].call(error)
|
@@ -18,6 +28,10 @@ class Midori::Sandbox
|
|
18
28
|
end
|
19
29
|
end
|
20
30
|
|
31
|
+
# Run sandbox inside given clean room
|
32
|
+
# @param [ Midori::CleanRoom ] clean_room Clean room to run
|
33
|
+
# @param [ Proc ] function the block to run
|
34
|
+
# @return [ nil ] nil
|
21
35
|
def run(clean_room, function, *args)
|
22
36
|
begin
|
23
37
|
function.to_lambda(clean_room).call(*args)
|
@@ -26,5 +40,7 @@ class Midori::Sandbox
|
|
26
40
|
end
|
27
41
|
end
|
28
42
|
end
|
43
|
+
|
44
|
+
private_class_method :class_initialize
|
29
45
|
class_initialize
|
30
46
|
end
|
data/lib/midori/server.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
##
|
2
2
|
# Logic to EventMachine TCP Server, running inside +EM::Connection+
|
3
|
-
# @attr [Midori::Request] request
|
4
|
-
# @attr [Class] api inherited from Midori::API
|
5
|
-
# @attr [Midori::WebSocket] websocket websocket instance
|
6
|
-
# @attr [Midori::EventSource] eventsource eventsource instance
|
7
3
|
module Midori::Server
|
4
|
+
# @!attribute request
|
5
|
+
# @return [ Midori::Request ] raw request
|
6
|
+
# @!attribute api
|
7
|
+
# @return [ Class ] inherited from Midori::API
|
8
|
+
# @!attribute websocket
|
9
|
+
# @return [ Midori::WebSocket ] defined websocket instance
|
10
|
+
# @!attribute eventsource
|
11
|
+
# @return [ Midori::EventSource] defined eventsource instance
|
8
12
|
attr_accessor :request, :api, :websocket, :eventsource
|
9
13
|
|
14
|
+
# Define server behaviour
|
10
15
|
# @param [Class] api inherited from Midori::API
|
11
16
|
# @param [Logger] logger global logger
|
12
17
|
def initialize(api, logger)
|
data/lib/midori/version.rb
CHANGED
data/lib/midori/websocket.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
##
|
2
2
|
# This class provides methods for WebSocket connection instance.
|
3
|
-
# @attr [Array<Fixnum>, String] msg message send from client
|
4
|
-
# @attr [Fixnum] opcode operation code of WebSocket
|
5
|
-
# @attr [Hash] events response for different event
|
6
|
-
# @attr [EM::Connection] connection raw EventMachine connection
|
3
|
+
# @attr [ Array<Fixnum>, String ] msg message send from client
|
4
|
+
# @attr [ Fixnum ] opcode operation code of WebSocket
|
5
|
+
# @attr [ Hash ] events response for different event
|
6
|
+
# @attr [ EM::Connection ] connection raw EventMachine connection
|
7
|
+
# @attr [ Midori::Request ] request raw request
|
7
8
|
class Midori::WebSocket
|
8
9
|
attr_accessor :msg, :opcode, :events, :connection, :request
|
9
10
|
|
10
|
-
#
|
11
|
+
# Init a WebSocket instance with a connection
|
12
|
+
# @param [ EM::Connection ] connection raw EventMachine connection
|
11
13
|
def initialize(connection)
|
12
14
|
@events = {}
|
13
15
|
@connection = connection
|
14
16
|
end
|
15
17
|
|
16
18
|
# Decode raw data send from client
|
17
|
-
# @param [StringIO] data raw data
|
19
|
+
# @param [ StringIO ] data raw data
|
18
20
|
def decode(data)
|
19
21
|
# Fin and Opcode
|
20
22
|
byte_tmp = data.getbyte
|
@@ -29,7 +31,7 @@ class Midori::WebSocket
|
|
29
31
|
end
|
30
32
|
|
31
33
|
# Decode masked message send from client
|
32
|
-
# @param [StringIO] data raw data
|
34
|
+
# @param [ StringIO ] data raw data
|
33
35
|
def decode_mask(data)
|
34
36
|
# Mask
|
35
37
|
byte_tmp = data.getbyte
|
@@ -48,7 +50,7 @@ class Midori::WebSocket
|
|
48
50
|
end
|
49
51
|
|
50
52
|
# API definition for events
|
51
|
-
# @param [Symbol] event event name(open, message, close, ping, pong)
|
53
|
+
# @param [ Symbol ] event event name(open, message, close, ping, pong)
|
52
54
|
# @yield what to do after event matched
|
53
55
|
# @example
|
54
56
|
# websocket '/websocket' do |ws|
|
@@ -61,7 +63,7 @@ class Midori::WebSocket
|
|
61
63
|
end
|
62
64
|
|
63
65
|
# Send data
|
64
|
-
# @param [Array<Fixnum>, String] msg data to send
|
66
|
+
# @param [ Array<Fixnum>, String ] msg data to send
|
65
67
|
def send(msg)
|
66
68
|
output = []
|
67
69
|
if msg.is_a?String
|
@@ -77,20 +79,20 @@ class Midori::WebSocket
|
|
77
79
|
end
|
78
80
|
|
79
81
|
# Send a Ping request
|
80
|
-
# @param [String] str string to send
|
82
|
+
# @param [ String ] str string to send
|
81
83
|
def ping(str)
|
82
84
|
heartbeat(0b10001001, str)
|
83
85
|
end
|
84
86
|
|
85
87
|
# Send a Pong request
|
86
|
-
# @param [String] str string to send
|
88
|
+
# @param [ String ] str string to send
|
87
89
|
def pong(str)
|
88
90
|
heartbeat(0b10001010, str)
|
89
91
|
end
|
90
92
|
|
91
93
|
# Ancestor of ping pong
|
92
|
-
# @param [Fixnum] method opcode
|
93
|
-
# @param [String] str string to send
|
94
|
+
# @param [ Fixnum ] method opcode
|
95
|
+
# @param [ String ] str string to send
|
94
96
|
def heartbeat(method, str)
|
95
97
|
raise Midori::Exception::PingPongSizeTooLarge if str.size > 125
|
96
98
|
@connection.send_data [method, str.size, str].pack("CCA#{str.size}")
|
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.7
|
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-12-
|
11
|
+
date: 2016-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|