crap_server 0.0.4.2 → 0.0.5.0
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 +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
|