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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/crap_server/application.rb +12 -26
- data/lib/crap_server/connection_handler.rb +66 -40
- data/lib/crap_server/forker.rb +0 -1
- data/lib/crap_server/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13e8f04ebe8da4fdb6e846e27fff6e7818f8d603
|
4
|
+
data.tar.gz: 760267e338c5e9a374f375ce7f87ebca81e1d284
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cadc65e83f29aadbe922cc61627a4eed560822480b61589f502808405312c56123415faaf4370a8932541b57c37cdc3d54483c260d836a19eba6c89fb32ea8a8
|
7
|
+
data.tar.gz: db8560beea1798a34a85d886393d8da833edf69a1973e55404ba5194e7013c2807734970f7636d0d764a72df3044c4fdb04999e80015058a6b069f56efa6f8d9
|
data/CHANGELOG.md
ADDED
@@ -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
|
-
|
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
|
-
# :
|
87
|
+
# :INET is to open an IPv4 connection
|
104
88
|
# :STREAM is to open a TCP socket
|
105
|
-
|
106
|
-
|
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
|
-
|
97
|
+
socket.bind(Socket.pack_sockaddr_in(config.port, loopback))
|
111
98
|
rescue Errno::EADDRINUSE
|
112
|
-
|
99
|
+
socket.close
|
113
100
|
raise ConnectionError.new "Unable to bind #{config.port} port."
|
114
101
|
end
|
115
102
|
|
116
|
-
|
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
|
-
|
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
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
data/lib/crap_server/forker.rb
CHANGED
data/lib/crap_server/version.rb
CHANGED
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
|
+
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-
|
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
|