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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2dcc440db5d1538e1e4530d9d6879c9a4115ee85
4
- data.tar.gz: b6912e55681783ebcd555de7b13c5d8681a213a8
3
+ metadata.gz: 6f38d205f0e4f20a31cfdec6103d2f51367dc4f8
4
+ data.tar.gz: 5edb796b384fdf26b0f2ad2e1e4c7d4ff74308b4
5
5
  SHA512:
6
- metadata.gz: 6b004b9d39d894840e6c2652dda4162d25be4be82f5532c3bedf61a189103e64b9d874312a686ccaa60469977d4f070bc4a6e09959cbcc24db3f7448ca0af648
7
- data.tar.gz: 9d4c89c1930ce59fe8590f2f26f2fda1972d768145c054803e8f0f2d8aecf840a44f52c50d026c5026cb0233ed8759ff6f443b11e9dd89043ee301a09a2fae88
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
@@ -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
- -> { clean_room.instance_exec(connection.websocket, &route.function) }.call
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
- -> { clean_room.instance_exec(connection.eventsource, &route.function) }.call
63
+ Midori::Sandbox.run(clean_room, route.function, connection.eventsource)
64
64
  return Midori::Response.new
65
65
  else
66
- result = -> { clean_room.instance_exec(&route.function) }.call
67
- clean_room.body = result if result.is_a?String
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
@@ -1,11 +1,11 @@
1
1
  ##
2
2
  # This class is used to be sandbox of requests processing.
3
- # @attr [Fixnum] code HTTP response code
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::Midlleware+
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 :code, :header, :body, :request
8
+ attr_accessor :status, :header, :body, :request
9
9
  # @param [Midori::Request] request HTTP request
10
10
  def initialize(request)
11
11
  @status = 200
@@ -1,5 +1,5 @@
1
1
  ##
2
- # Default configuration of Midori, extends +Midori::Configurable+
2
+ # Default configuration of Midori, extends +Configurable+
3
3
  class Midori::Configure
4
4
  extend Configurable
5
5
 
@@ -1,5 +1,5 @@
1
1
  ##
2
- # Module for store Midori Consts
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 Evenrsource response
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 Websocket response
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
@@ -1,8 +1,10 @@
1
1
  ##
2
- # This module store errors to be handled in Midori
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
@@ -54,19 +54,19 @@ class Midori::Request
54
54
  @parsed = true
55
55
  end
56
56
 
57
- # Syntatic sugar for whether a request is parsed
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
- # Syntatic sugar for whether a request is a websocket request
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
- # Syntatic sugar for whether a request is an eventsource request
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
@@ -1,5 +1,5 @@
1
1
  ##
2
- # Logics to EventMachine TCP Server, running inside +EM::Connection+
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
- # Logics of receiving data
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
- # Logics of receiving new request
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 => _e
48
- @response = Midori::Response.new(404, {}, '404 Not Found')
47
+ rescue Midori::Error::NotFound => e
48
+ @response = Midori::Sandbox.capture(e)
49
49
  rescue => e
50
- @response = Midori::Response.new(500, {}, 'Internal Server Error')
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
- # Logics of receiving WebSocket request
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) # Neglect Too large ping request
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
@@ -1,5 +1,5 @@
1
1
  # Midori Module
2
2
  module Midori
3
3
  # Current Version Code
4
- VERSION = '0.1.1'.freeze
4
+ VERSION = '0.1.2'.freeze
5
5
  end
@@ -14,7 +14,7 @@ class Midori::WebSocket
14
14
  end
15
15
 
16
16
  # Decode raw data send from client
17
- # @param [String] data raw data
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 [String] data raw data
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.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-07 00:00:00.000000000 Z
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