rakie 0.0.2 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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