rakie 0.0.2 → 0.0.8

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.
@@ -0,0 +1,134 @@
1
+ module Rakie
2
+ class HttpServer
3
+ class Session
4
+ # @return [HttpRequest]
5
+ attr_accessor :request
6
+
7
+ # @type [Array<HttpResponse>]
8
+ attr_accessor :responses
9
+
10
+ def initialize
11
+ @request = HttpRequest.new
12
+ @responses = []
13
+ end
14
+ end
15
+
16
+ attr_reader :channel, :opt, :host, :port
17
+
18
+ def initialize(host: '127.0.0.1', port: 10086, delegate: nil)
19
+ @host = host
20
+ @port = port
21
+
22
+ @channel = TCPServerChannel.new(host, port, self)
23
+
24
+ # @type [Hash{Channel=>Session}]
25
+ @sessions = {}
26
+ @delegate = delegate
27
+ @opt = {}
28
+ end
29
+
30
+ def on_accept(channel)
31
+ channel.delegate = self
32
+ @sessions[channel] = Session.new
33
+ Log.debug("Rakie::HTTPServer accept client: #{channel}")
34
+ end
35
+
36
+ def on_recv(channel, data)
37
+ # Log.debug("Rakie::HTTPServer recv: #{data}")
38
+ session = @sessions[channel]
39
+
40
+ if session == nil
41
+ return 0
42
+ end
43
+
44
+ # @type [HttpRequest] request
45
+ request = session.request
46
+
47
+ if request.parse_status == ParseStatus::COMPLETE
48
+ request = HttpRequest.new
49
+ session.request = request
50
+ end
51
+
52
+ len = request.parse(data)
53
+
54
+ Log.debug("Rakie::HttpServer receive request: #{request.to_s}")
55
+
56
+ if request.parse_status == ParseStatus::COMPLETE
57
+ response = HttpResponse.new
58
+
59
+ if upgrade = request.headers["upgrade"]
60
+ if websocket_delegate = @opt[:websocket_delegate]
61
+ websocket_delegate.upgrade(request, response)
62
+ Log.debug("Rakie::HttpServer upgrade protocol")
63
+ end
64
+
65
+ elsif @delegate != nil
66
+ @delegate.handle(request, response)
67
+
68
+ else
69
+ response.headers["content-type"] = HttpMIME::HTML
70
+ response.content = "<html><body><h1>Rakie!</h1></body></html>"
71
+ end
72
+
73
+ if header_connection = request.headers["connection"]
74
+ response.headers["connection"] = header_connection
75
+ end
76
+
77
+ if response.content.length > 0
78
+ response.headers["content-length"] = response.content.length
79
+ end
80
+
81
+ response.headers["server"] = Rakie.full_version_s
82
+ session.responses << response
83
+ response_data = response.to_s
84
+
85
+ Log.debug("Rakie::HttpServer response: #{response_data}")
86
+
87
+ channel.write(response_data) # Response data
88
+
89
+ elsif request.parse_status == ParseStatus::ERROR
90
+ channel.close
91
+ @sessions.delete(channel)
92
+
93
+ Log.debug("Rakie::HttpServer: Illegal request")
94
+ return len
95
+ end
96
+
97
+ return len
98
+ end
99
+
100
+ def on_send(channel)
101
+ session = @sessions[channel]
102
+ # @type [HttpRequest]
103
+ last_response = session.responses.shift
104
+
105
+ if last_response
106
+ if connect_status = last_response.headers["connection"]
107
+ if connect_status.downcase == "close"
108
+ Log.debug("Rakie::HttpServer: send finish and close channel")
109
+ channel.close
110
+ @sessions.delete(channel)
111
+ end
112
+ end
113
+
114
+ if upgrade = last_response.headers["upgrade"]
115
+ websocket_delegate = @opt[:websocket_delegate]
116
+
117
+ if websocket_delegate
118
+ websocket_delegate.on_accept(channel)
119
+ @sessions.delete(channel)
120
+ return
121
+ end
122
+
123
+ Log.debug("Rakie::HttpServer: no websocket delegate and close channel")
124
+ channel.close
125
+ @sessions.delete(channel)
126
+ end
127
+ end
128
+ end
129
+
130
+ def on_close(channel)
131
+ @sessions.delete(channel)
132
+ end
133
+ end
134
+ end
data/lib/rakie/log.rb ADDED
@@ -0,0 +1,96 @@
1
+ module Rakie
2
+ class Log
3
+ attr_accessor :out, :level
4
+
5
+ @instance = nil
6
+
7
+ LEVEL_INFO = 0
8
+ LEVEL_ERROR = 1
9
+ LEVEL_DEBUG = 2
10
+
11
+ def initialize
12
+ @level = Rakie.current_mode == Rakie::MODE_DEV ? LEVEL_DEBUG : LEVEL_ERROR
13
+ @out = STDOUT
14
+ end
15
+
16
+ def level_text(level=nil)
17
+ unless level
18
+ level = @level
19
+ end
20
+
21
+ case level
22
+ when LEVEL_INFO
23
+ return "INFO"
24
+
25
+ when LEVEL_ERROR
26
+ return "ERROR"
27
+
28
+ when LEVEL_DEBUG
29
+ return "DEBUG"
30
+ end
31
+ end
32
+
33
+ def level_info?
34
+ @level >= LEVEL_INFO
35
+ end
36
+
37
+ def level_error?
38
+ @level >= LEVEL_ERROR
39
+ end
40
+
41
+ def level_debug?
42
+ @level >= LEVEL_DEBUG
43
+ end
44
+
45
+ def self.instance
46
+ @instance ||= Log.new
47
+ end
48
+
49
+ def self.info(message, who=nil)
50
+ unless self.instance.level_info?
51
+ return
52
+ end
53
+
54
+ if who
55
+ message = "#{who}: #{message}"
56
+ end
57
+
58
+ level = self.instance.level_text(LEVEL_INFO)
59
+ self.instance.out.write("[#{Time.now.to_s}][#{level}] #{message}\n")
60
+ end
61
+
62
+ def self.error(message, who=nil)
63
+ unless self.instance.level_error?
64
+ return
65
+ end
66
+
67
+ if who
68
+ message = "#{who}: #{message}"
69
+ end
70
+
71
+ level = self.instance.level_text(LEVEL_ERROR)
72
+ self.instance.out.write("[#{Time.now.to_s}][#{level}] #{message}\n")
73
+ end
74
+
75
+ def self.debug(message, who=nil)
76
+ unless self.instance.level_debug?
77
+ return
78
+ end
79
+
80
+ if who
81
+ message = "#{who}: #{message}"
82
+ end
83
+
84
+ level = self.instance.level_text(LEVEL_DEBUG)
85
+ self.instance.out.print("[#{Time.now.to_s}][#{level}] #{message}\n")
86
+ end
87
+
88
+ def self.level
89
+ self.instance.level
90
+ end
91
+
92
+ def self.level=(level)
93
+ self.instance.level = level
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,63 @@
1
+ module Rakie
2
+ class ParseStatus
3
+ ERROR = -1
4
+ CONTINUE = 0
5
+ PENDING = 1
6
+ COMPLETE = 2
7
+ end
8
+
9
+ module Proto
10
+ PARSE_BEGIN = 0
11
+
12
+ # @return [Integer]
13
+ def parse_status
14
+ @parse_status ||= ParseStatus::CONTINUE
15
+ end
16
+
17
+ # @return [Integer]
18
+ def parse_state
19
+ @parse_state ||= PARSE_BEGIN
20
+ end
21
+
22
+ # @param [Integer] state
23
+ def parse_state=(state)
24
+ @parse_state = state
25
+ # puts("Set state: #{@parse_state}")
26
+ end
27
+
28
+ # @return [Integer]
29
+ def parse_offset
30
+ @parse_offset ||= 0
31
+ end
32
+
33
+ # @param [Integer] offset
34
+ def parse_offset=(offset)
35
+ @parse_offset = offset
36
+ end
37
+
38
+ # @param [String] source
39
+ def parse(source)
40
+ status = ParseStatus::CONTINUE
41
+
42
+ while status == ParseStatus::CONTINUE
43
+ status = self.deserialize(source)
44
+ end
45
+
46
+ if status == ParseStatus::PENDING
47
+ status = ParseStatus::CONTINUE
48
+ end
49
+
50
+ offset = @parse_offset
51
+ @parse_status = status
52
+ @parse_offset = 0
53
+
54
+ return offset
55
+ end
56
+
57
+ # @param [Object] object
58
+ # @return [String]
59
+ def to_s
60
+ self.serialize
61
+ end
62
+ end
63
+ end
@@ -31,7 +31,7 @@ module Rakie
31
31
  :entity => ""
32
32
  }
33
33
  }
34
- puts("SimpleServer accept client: #{channel}")
34
+ Log.debug("SimpleServer accept client: #{channel}")
35
35
  end
36
36
 
37
37
  def parse_data_type(client, data)
@@ -41,7 +41,7 @@ module Rakie
41
41
  client[:parse_status] = PARSE_LEN
42
42
  client[:parse_offset] += 1
43
43
 
44
- puts("SimpleServer parse data type ok")
44
+ Log.debug("SimpleServer parse data type ok")
45
45
  return PARSE_OK
46
46
  end
47
47
 
@@ -63,7 +63,7 @@ module Rakie
63
63
  client[:parse_status] = PARSE_ENTITY
64
64
  client[:parse_offset] = offset + 4
65
65
 
66
- puts("SimpleServer parse data len ok")
66
+ Log.debug("SimpleServer parse data len ok")
67
67
  return PARSE_OK
68
68
  end
69
69
 
@@ -79,7 +79,7 @@ module Rakie
79
79
  client[:parse_status] = PARSE_TYPE
80
80
  client[:parse_offset] = offset + len
81
81
 
82
- puts("SimpleServer parse data entity ok")
82
+ Log.debug("SimpleServer parse data entity ok")
83
83
  return PARSE_COMPLETE
84
84
  end
85
85
 
@@ -104,7 +104,7 @@ module Rakie
104
104
  end
105
105
  end
106
106
 
107
- puts("SimpleServer parse data result #{result}")
107
+ Log.debug("SimpleServer parse data result #{result}")
108
108
 
109
109
  return result
110
110
  end
@@ -117,13 +117,11 @@ module Rakie
117
117
  end
118
118
 
119
119
  def on_recv(channel, data)
120
- puts("SimpleServer recv: #{data}")
120
+ Log.debug("SimpleServer recv: #{data}")
121
121
  client = @clients[channel]
122
122
  client[:parse_offset] = 0
123
123
  result = self.parse_data(client, data)
124
124
 
125
- pp client
126
-
127
125
  if result == PARSE_COMPLETE
128
126
  if @delegate != nil
129
127
  @delegate.handle(client[:request], client[:response])
@@ -137,7 +135,7 @@ module Rakie
137
135
  elsif result == PARSE_ERROR
138
136
  channel.close
139
137
  @clients.delete(channel)
140
- puts("SimpleServer: Illegal request")
138
+ Log.debug("SimpleServer: Illegal request")
141
139
  return client[:parse_offset]
142
140
  end
143
141
 
@@ -145,5 +143,3 @@ module Rakie
145
143
  end
146
144
  end
147
145
  end
148
-
149
- require "pp"
@@ -1,8 +1,24 @@
1
1
  module Rakie
2
2
  class TCPChannel < Channel
3
- def initialize(ip, port, delegate=nil)
4
- @io = TCPSocket.new(ip, port)
5
- super(@io, delegate)
3
+ LOCAL_HOST = '127.0.0.1'
4
+
5
+ # @param host [String]
6
+ # @param port [Integer]
7
+ # @param delegate [Object]
8
+ # @param socket [Socket]
9
+ # @overload initialize(host, port, delegate)
10
+ # @overload initialize(host, port)
11
+ # @overload initialize(host, port, delegate, socket)
12
+ def initialize(host=LOCAL_HOST, port=3001, delegate=nil, socket=nil)
13
+ if socket == nil
14
+ socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
15
+ socket.connect(Socket.pack_sockaddr_in(port, host))
16
+ end
17
+
18
+ @port = port
19
+ @host = host
20
+
21
+ super(socket, delegate)
6
22
  end
7
23
  end
8
24
  end
@@ -1,42 +1,58 @@
1
1
  module Rakie
2
- class TCPServerChannel < Channel
3
- def initialize(ip, port=nil, delegate=nil)
4
- io = nil
2
+ class TCPServerChannel < TCPChannel
3
+ # @param host [String]
4
+ # @param port [Integer]
5
+ # @param delegate [Object]
6
+ # @overload initialize(host, port, delegate)
7
+ # @overload initialize(host, port)
8
+ # @overload initialize(port)
9
+ def initialize(host=LOCAL_HOST, port=3001, delegate=nil)
10
+ socket = nil
5
11
 
6
12
  if port == nil
7
- port = ip
8
- io = TCPServer.new(ip)
9
-
10
- else
11
- io = TCPServer.new(ip, port)
13
+ port = host
14
+ host = LOCAL_HOST
12
15
  end
13
16
 
17
+ socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
18
+ socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
19
+ socket.bind(Socket.pack_sockaddr_in(port, host))
20
+ socket.listen(255)
21
+
14
22
  @clients = []
15
23
 
16
- super(io, delegate)
24
+ super(host, port, delegate, socket)
17
25
  end
18
26
 
27
+ # @param io [Socket]
19
28
  def on_read(io)
20
29
  begin
21
- client_io, = io.accept_nonblock
22
- channel = Channel.new(client_io)
30
+ ret = io.accept_nonblock
31
+ # @type client_io [Socket]
32
+ client_io = ret[0]
33
+ # @type client_info [Addrinfo]
34
+ client_info = ret[1]
35
+ client_name_info = client_info.getnameinfo
36
+ client_host = client_name_info[0]
37
+ client_port = client_name_info[1]
38
+ channel = TCPChannel.new(client_host, client_port, nil, client_io)
23
39
 
24
40
  if @delegate != nil
25
- puts("TCPServerChannel has delegate")
41
+ Log.debug("TCPServerChannel has delegate")
26
42
  @delegate.on_accept(channel)
27
43
 
28
44
  else
29
- puts("TCPServerChannel no delegate")
45
+ Log.debug("TCPServerChannel no delegate")
30
46
  @clients << channel
31
47
  end
32
48
 
33
- puts("TCPServerChannel accept #{channel}")
49
+ Log.debug("TCPServerChannel accept #{channel}")
34
50
 
35
51
  rescue IO::EAGAINWaitReadable
36
- puts("TCPServerChannel accept wait")
52
+ Log.debug("TCPServerChannel accept wait")
37
53
 
38
54
  rescue
39
- puts("TCPServerChannel Accept failed #{io}")
55
+ Log.debug("TCPServerChannel Accept failed #{io}")
40
56
  return Event::HANDLE_FAILED
41
57
  end
42
58