crap_server 0.0.4.2 → 0.0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8f32930965a763afe13876581ab27b27c5c4803
4
- data.tar.gz: 29ae4fb42d5d261b4e2a4d4e48e3a38f2d5a6282
3
+ metadata.gz: 13e8f04ebe8da4fdb6e846e27fff6e7818f8d603
4
+ data.tar.gz: 760267e338c5e9a374f375ce7f87ebca81e1d284
5
5
  SHA512:
6
- metadata.gz: fbb0d3e5004bdafdafffb4b9b6d72188f771e7976ef60d411bb394d30bc35cbe5c1fa059af2c1c09beea38ddee2642cd3400daf535a66ca7036fc28f6cd09c77
7
- data.tar.gz: f7d46b54a5e050e13d7f664ccb1f6034a89c45891b287d2ebfffebbc3aa2f16916d54b7be6d2cfa14d2cf3b642cb7dbc20aea742108f554ab7f8c6143bf005bb
6
+ metadata.gz: cadc65e83f29aadbe922cc61627a4eed560822480b61589f502808405312c56123415faaf4370a8932541b57c37cdc3d54483c260d836a19eba6c89fb32ea8a8
7
+ data.tar.gz: db8560beea1798a34a85d886393d8da833edf69a1973e55404ba5194e7013c2807734970f7636d0d764a72df3044c4fdb04999e80015058a6b069f56efa6f8d9
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # 0.0.5
2
+
3
+ * Fixed a bug that prevent to close lasts connections until get a new connection.
4
+ * Refactoring some code.
@@ -80,45 +80,31 @@ module CrapServer
80
80
  def start_ipv6_socket
81
81
  # :INET6 is to open an IPv6 connection
82
82
  # :STREAM is to open a TCP socket
83
- # After this line, the app is not yet ready to work, we only opened a socket
84
- socket_ipv6 = Socket.new(:INET6, :STREAM)
85
-
86
- begin
87
- # Now, bind the port.
88
- # ::1 is loopback for IPv6
89
- socket_ipv6.bind(Socket.pack_sockaddr_in(config.port, '::1'))
90
- rescue Errno::EADDRINUSE
91
- socket_ipv6.close
92
- raise ConnectionError.new "Unable to bind #{config.port} port."
93
- end
94
- socket_ipv6.listen(config.max_pending_connections)
95
- # Tell to the Kernel that is ok to rebind the port if is in TIME_WAIT state (after close the connection
96
- # and the Kernel wait for client acknowledgement)
97
- socket_ipv6.setsockopt(:SOCKET, :REUSEADDR, true)
98
-
99
- @socket6 = socket_ipv6
83
+ @socket6 = start_socket :INET6, :STREAM, '::1'
100
84
  end
101
85
 
102
86
  def start_ipv4_socket
103
- # :INET6 is to open an IPv6 connection
87
+ # :INET is to open an IPv4 connection
104
88
  # :STREAM is to open a TCP socket
105
- # After this line, the app is not yet ready to work, we only opened a socket
106
- socket_ipv4 = Socket.new(:INET, :STREAM)
89
+ @socket4 = start_socket :INET, :STREAM, '0.0.0.0'
90
+ end
91
+
92
+ def start_socket(version, type, loopback)
93
+ socket = Socket.new(version, type)
107
94
 
108
95
  begin
109
96
  # Now, bind the port.
110
- socket_ipv4.bind(Socket.pack_sockaddr_in(config.port, '0.0.0.0'))
97
+ socket.bind(Socket.pack_sockaddr_in(config.port, loopback))
111
98
  rescue Errno::EADDRINUSE
112
- socket_ipv4.close
99
+ socket.close
113
100
  raise ConnectionError.new "Unable to bind #{config.port} port."
114
101
  end
115
102
 
116
- socket_ipv4.listen(config.max_pending_connections)
103
+ socket.listen(config.max_pending_connections)
117
104
  # Tell to the Kernel that is ok to rebind the port if is in TIME_WAIT state (after close the connection
118
105
  # and the Kernel wait for client acknowledgement)
119
- socket_ipv4.setsockopt(:SOCKET, :REUSEADDR, true)
120
-
121
- @socket4 = socket_ipv4
106
+ socket.setsockopt(:SOCKET, :REUSEADDR, true)
107
+ socket
122
108
  end
123
109
 
124
110
  def socket_ipv6
@@ -101,61 +101,87 @@ module CrapServer
101
101
  protected
102
102
 
103
103
  # Evented loop (Reactor pattern)
104
- def accept_loop
104
+ def accept_loop(&block)
105
105
  loop {
106
+ logger.debug 'Start loop'
106
107
  @readables, @writables = IO.select(to_read, to_write)
107
108
 
108
- @readables.each do |socket|
109
- if @sockets.include? socket
110
- io, addr = socket.accept
111
- set_address io, addr
112
- set_close_after_write io if config.auto_close_connection
113
- # Disabling Nagle's algorithm. Is fucking slow :P
114
- io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
115
- # We add him to the read queue
116
- add_to_read io
117
- else
118
- begin
119
- _, data = socket, socket.read_nonblock(config.read_buffer_size)
120
- yield data, socket, address(socket)
121
- # We close the connection if we auto_close_connection is true and the user didn't write in the buffer.
122
- close socket if config.auto_close_connection && buffer(socket).nil?
123
- rescue Errno::EAGAIN
124
- rescue EOFError
125
- remove_to_read socket
126
- end
109
+ process_readables &block
110
+ process_writables
111
+ }
112
+ end
113
+
114
+ protected
115
+
116
+ def process_readables(&block)
117
+ @readables.each do |socket|
118
+ if @sockets.include? socket
119
+ accept_connection socket
120
+ else
121
+ begin
122
+ read_and_process_data socket, &block
123
+ rescue Errno::EAGAIN
124
+ rescue EOFError
125
+ remove_to_read socket
127
126
  end
128
127
  end
128
+ end
129
+ end
129
130
 
130
- @writables.each do |socket|
131
- begin
132
- string = buffer socket
133
- bytes = socket.write_nonblock string
134
- string.slice! 0, bytes
135
- if string.empty?
136
- # If we don't have more data to send to the client
137
- if close_after_write socket
138
- close socket
139
- else
140
- remove_to_write socket
141
- end
142
- else
143
- set_buffer socket, string
144
- remove_to_read socket
145
- end
146
- # If the client close the connection, we remove is from read and from write
147
- rescue Errno::ECONNRESET, Errno::EPIPE
131
+ def process_writables
132
+ @writables.each do |socket|
133
+ begin
134
+ string = buffer socket
135
+ bytes = socket.write_nonblock string
136
+ string.slice! 0, bytes
137
+ if string.empty?
138
+ # If we don't have more data to send to the client
148
139
  if close_after_write socket
149
140
  close socket
141
+ else
142
+ remove_to_write socket
150
143
  end
144
+ else
145
+ set_buffer socket, string
146
+ remove_to_read socket
147
+ end
148
+ # If the client close the connection, we remove is from read and from write
149
+ rescue Errno::ECONNRESET, Errno::EPIPE
150
+ if close_after_write socket
151
+ close socket
151
152
  end
152
153
  end
153
- }
154
+ end
155
+ end
156
+
157
+ def accept_connection(socket)
158
+ begin
159
+ io, addr = socket.accept_nonblock
160
+ set_address io, addr
161
+ set_close_after_write io if config.auto_close_connection
162
+ # Disabling Nagle's algorithm. Is fucking slow :P
163
+ io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
164
+ # We add him to the read queue
165
+ add_to_read io
166
+ rescue Errno::EINPROGRESS, IO::EAGAINWaitReadable
167
+ end
168
+ end
169
+
170
+ def read_and_process_data(socket, &block)
171
+ _, data = socket, socket.read_nonblock(config.read_buffer_size)
172
+ block.call data, socket, address(socket)
173
+ # We close the connection if we auto_close_connection is true and the user didn't write in the buffer.
174
+ if config.auto_close_connection && buffer(socket).nil?
175
+ close socket
176
+ end
154
177
  end
155
178
 
156
- protected
157
179
  def config
158
180
  CrapServer::Application.send(:config)
159
181
  end
182
+
183
+ def logger
184
+ CrapServer::Application.send(:logger)
185
+ end
160
186
  end
161
187
  end
@@ -41,7 +41,6 @@ module CrapServer
41
41
  def spawn_child
42
42
  fork do
43
43
  begin
44
-
45
44
  CrapServer::Application.send(:per_process_block).call if not CrapServer::Application.send(:per_process_block).nil?
46
45
  pool = CrapServer::ThreadPool.new @sockets
47
46
  pool.run &@block_proc
@@ -1,3 +1,3 @@
1
1
  module CrapServer
2
- VERSION = '0.0.4.2'
2
+ VERSION = '0.0.5.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crap_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4.2
4
+ version: 0.0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andres Jose Borek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-08 00:00:00.000000000 Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -47,6 +47,7 @@ extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
49
  - ".gitignore"
50
+ - CHANGELOG.md
50
51
  - Gemfile
51
52
  - LICENSE.txt
52
53
  - README.md