tipi 0.32 → 0.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +3 -3
- data/bin/tipi +13 -0
- data/examples/http_server_forked.rb +4 -5
- data/examples/http_server_throttled_accept.rb +23 -0
- data/lib/tipi.rb +2 -4
- data/lib/tipi/configuration.rb +1 -1
- data/lib/tipi/http1_adapter.rb +8 -8
- data/lib/tipi/http2_adapter.rb +1 -1
- data/lib/tipi/rack_adapter.rb +10 -2
- data/lib/tipi/version.rb +1 -1
- data/lib/tipi/websocket.rb +1 -1
- data/test/test_http_server.rb +9 -5
- data/tipi.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adbbb6098994749bc96df90a6c73820ca54245c6026141768c83d883677fd6d3
|
4
|
+
data.tar.gz: daf182efaff0561bb6ff85706ae14ab70de68f840290eb5bb88e870fc0a29199
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78c8fb0c465779673563fb87857fdc935c4906830086f664657c00b2b80686f4fa35c3673a554976d26a41af072686ad2c197dd1fbd6a14d875480831e8455ff
|
7
|
+
data.tar.gz: bbb9c98e7f167aae1a006fd30ac7557ddf9671d3951e00012582b748f3afea363e53b166c40ec1af3be0f5c6d96d1991f45d9e549f5fd23e614345508719ef5f
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tipi (0.
|
4
|
+
tipi (0.33)
|
5
5
|
http-2 (~> 0.10.0)
|
6
6
|
http_parser.rb (~> 0.6.0)
|
7
|
-
polyphony (~> 0.
|
7
|
+
polyphony (~> 0.47.5.1)
|
8
8
|
rack (>= 2.0.8, < 2.3.0)
|
9
9
|
websocket (~> 1.2.8)
|
10
10
|
|
@@ -24,7 +24,7 @@ GEM
|
|
24
24
|
builder
|
25
25
|
minitest (>= 5.0)
|
26
26
|
ruby-progressbar
|
27
|
-
polyphony (0.
|
27
|
+
polyphony (0.47.5.1)
|
28
28
|
rack (2.2.3)
|
29
29
|
rake (12.3.3)
|
30
30
|
ruby-progressbar (1.10.1)
|
data/bin/tipi
CHANGED
@@ -7,7 +7,20 @@ require File.expand_path('../lib/tipi/configuration', __dir__)
|
|
7
7
|
config = {}
|
8
8
|
#config[:forked] = 4
|
9
9
|
|
10
|
+
puts DATA.read
|
11
|
+
puts
|
12
|
+
|
10
13
|
configuration_manager = spin { Tipi::Configuration.supervise_config }
|
11
14
|
|
12
15
|
configuration_manager << config
|
13
16
|
configuration_manager.await
|
17
|
+
|
18
|
+
__END__
|
19
|
+
|
20
|
+
ooo
|
21
|
+
oo
|
22
|
+
o
|
23
|
+
\|/
|
24
|
+
/ \ Tipi - A better web server for a better world
|
25
|
+
/___\
|
26
|
+
|
@@ -7,18 +7,15 @@ require 'tipi'
|
|
7
7
|
|
8
8
|
opts = {
|
9
9
|
reuse_addr: true,
|
10
|
+
reuse_port: true,
|
10
11
|
dont_linger: true
|
11
12
|
}
|
12
13
|
|
13
|
-
server = Polyphony::HTTP::Server.listen('0.0.0.0', 1234, opts)
|
14
|
-
|
15
|
-
puts 'Listening on port 1234'
|
16
|
-
|
17
14
|
child_pids = []
|
18
15
|
8.times do
|
19
16
|
pid = Polyphony.fork do
|
20
17
|
puts "forked pid: #{Process.pid}"
|
21
|
-
|
18
|
+
Tipi.serve('0.0.0.0', 1234, opts) do |req|
|
22
19
|
req.respond("Hello world! from pid: #{Process.pid}\n")
|
23
20
|
end
|
24
21
|
rescue Interrupt
|
@@ -26,4 +23,6 @@ child_pids = []
|
|
26
23
|
child_pids << pid
|
27
24
|
end
|
28
25
|
|
26
|
+
puts 'Listening on port 1234'
|
27
|
+
|
29
28
|
child_pids.each { |pid| Thread.current.backend.waitpid(pid) }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'tipi'
|
5
|
+
|
6
|
+
::Exception.__disable_sanitized_backtrace__ = true
|
7
|
+
|
8
|
+
opts = {
|
9
|
+
reuse_addr: true,
|
10
|
+
reuse_port: true,
|
11
|
+
dont_linger: true
|
12
|
+
}
|
13
|
+
|
14
|
+
server = Tipi.listen('0.0.0.0', 1234, opts)
|
15
|
+
|
16
|
+
puts 'Listening on port 1234'
|
17
|
+
|
18
|
+
throttler = Polyphony::Throttler.new(interval: 5)
|
19
|
+
server.accept_loop do |socket|
|
20
|
+
throttler.call do
|
21
|
+
spin { Tipi.client_loop(socket, opts) { |req| req.respond("Hello world!\n") } }
|
22
|
+
end
|
23
|
+
end
|
data/lib/tipi.rb
CHANGED
@@ -28,10 +28,8 @@ module Tipi
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def accept_loop(server, opts, &handler)
|
31
|
-
|
32
|
-
client = server.accept
|
31
|
+
server.accept_loop do |client|
|
33
32
|
spin { client_loop(client, opts, &handler) }
|
34
|
-
snooze
|
35
33
|
rescue OpenSSL::SSL::SSLError
|
36
34
|
# disregard
|
37
35
|
end
|
@@ -47,7 +45,7 @@ module Tipi
|
|
47
45
|
|
48
46
|
def protocol_adapter(socket, opts)
|
49
47
|
use_http2 = socket.respond_to?(:alpn_protocol) &&
|
50
|
-
|
48
|
+
socket.alpn_protocol == H2_PROTOCOL
|
51
49
|
klass = use_http2 ? HTTP2Adapter : HTTP1Adapter
|
52
50
|
klass.new(socket, opts)
|
53
51
|
end
|
data/lib/tipi/configuration.rb
CHANGED
data/lib/tipi/http1_adapter.rb
CHANGED
@@ -15,7 +15,7 @@ module Tipi
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def each(&block)
|
18
|
-
@conn.
|
18
|
+
@conn.recv_loop do |data|
|
19
19
|
return if handle_incoming_data(data, &block)
|
20
20
|
end
|
21
21
|
rescue SystemCallError, IOError
|
@@ -65,7 +65,7 @@ module Tipi
|
|
65
65
|
# callback
|
66
66
|
def consume_request
|
67
67
|
request = @requests_head
|
68
|
-
@conn.
|
68
|
+
@conn.recv_loop do |data|
|
69
69
|
@parser << data
|
70
70
|
return if request.complete?
|
71
71
|
end
|
@@ -164,7 +164,7 @@ module Tipi
|
|
164
164
|
# @param headers
|
165
165
|
def respond(body, headers)
|
166
166
|
consume_request if @parsing
|
167
|
-
data =
|
167
|
+
data = format_headers(headers, body)
|
168
168
|
if body
|
169
169
|
if @parser.http_minor == 0
|
170
170
|
data << body
|
@@ -172,7 +172,7 @@ module Tipi
|
|
172
172
|
data << body.bytesize.to_s(16) << CRLF << body << CRLF_ZERO_CRLF_CRLF
|
173
173
|
end
|
174
174
|
end
|
175
|
-
@conn.write(
|
175
|
+
@conn.write(data.join)
|
176
176
|
end
|
177
177
|
|
178
178
|
DEFAULT_HEADERS_OPTS = {
|
@@ -186,8 +186,8 @@ module Tipi
|
|
186
186
|
# @param empty_response [boolean] whether a response body will be sent
|
187
187
|
# @return [void]
|
188
188
|
def send_headers(headers, opts = DEFAULT_HEADERS_OPTS)
|
189
|
-
data =
|
190
|
-
@conn.write(
|
189
|
+
data = format_headers(headers, true)
|
190
|
+
@conn.write(data.join)
|
191
191
|
end
|
192
192
|
|
193
193
|
# Sends a response body chunk. If no headers were sent, default headers are
|
@@ -200,7 +200,7 @@ module Tipi
|
|
200
200
|
data = []
|
201
201
|
data << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
|
202
202
|
data << "0\r\n\r\n" if done
|
203
|
-
@conn.write(
|
203
|
+
@conn.write(data.join)
|
204
204
|
end
|
205
205
|
|
206
206
|
# Finishes the response to the current request. If no headers were sent,
|
@@ -221,7 +221,7 @@ module Tipi
|
|
221
221
|
# @param headers [Hash] response headers
|
222
222
|
# @param empty_response [boolean] whether a response body will be sent
|
223
223
|
# @return [String] formatted response headers
|
224
|
-
def
|
224
|
+
def format_headers(headers, body)
|
225
225
|
status = headers[':status'] || (body ? 200 : 204)
|
226
226
|
lines = [format_status_line(body, status)]
|
227
227
|
headers.each do |k, v|
|
data/lib/tipi/http2_adapter.rb
CHANGED
data/lib/tipi/rack_adapter.rb
CHANGED
@@ -68,10 +68,18 @@ module Tipi
|
|
68
68
|
else RACK_ENV[key]
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def respond(request, (status_code, headers, body))
|
73
73
|
headers[':status'] = status_code.to_s
|
74
|
-
|
74
|
+
|
75
|
+
content =
|
76
|
+
if body.respond_to?(:to_path)
|
77
|
+
File.open(body.to_path, 'rb') { |f| f.read }
|
78
|
+
else
|
79
|
+
body.first
|
80
|
+
end
|
81
|
+
|
82
|
+
request.respond(content, headers)
|
75
83
|
end
|
76
84
|
end
|
77
85
|
end
|
data/lib/tipi/version.rb
CHANGED
data/lib/tipi/websocket.rb
CHANGED
data/test/test_http_server.rb
CHANGED
@@ -23,11 +23,13 @@ class IO
|
|
23
23
|
|
24
24
|
def self.mockup_connection(input, output, output2)
|
25
25
|
eg(
|
26
|
-
:read => ->(*args) { input.read(*args) },
|
27
|
-
:read_loop => ->(*args, &block) { input.read_loop(*args, &block) },
|
28
|
-
:
|
29
|
-
|
30
|
-
:
|
26
|
+
:read => ->(*args) { p [:read]; input.read(*args) },
|
27
|
+
:read_loop => ->(*args, &block) { p [:read_loop, caller]; input.read_loop(*args, &block) },
|
28
|
+
:recv_loop => ->(*args, &block) { p [:recv_loop]; input.read_loop(*args, &block) },
|
29
|
+
:readpartial => ->(*args) { p [:readpartial]; input.readpartial(*args) },
|
30
|
+
:recv => ->(*args) { p [:recv]; input.readpartial(*args) },
|
31
|
+
:<< => ->(*args) { p [:<<, args]; output.write(*args) },
|
32
|
+
:write => ->(*args) { p [:write, args]; output.write(*args) },
|
31
33
|
:close => -> { output.close },
|
32
34
|
:eof? => -> { output2.closed? }
|
33
35
|
)
|
@@ -158,12 +160,14 @@ class HTTP1ServerTest < MiniTest::Test
|
|
158
160
|
request = req
|
159
161
|
req.send_headers
|
160
162
|
req.each_chunk do |c|
|
163
|
+
puts "chunk: #{c.inspect}"
|
161
164
|
chunks << c
|
162
165
|
req << c.upcase
|
163
166
|
end
|
164
167
|
req.finish
|
165
168
|
end
|
166
169
|
|
170
|
+
p connection
|
167
171
|
connection << <<~HTTP.http_lines
|
168
172
|
POST / HTTP/1.1
|
169
173
|
Transfer-Encoding: chunked
|
data/tipi.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.executables = ['tipi']
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'polyphony', '~>0.
|
22
|
+
s.add_runtime_dependency 'polyphony', '~>0.47.5.1'
|
23
23
|
|
24
24
|
s.add_runtime_dependency 'http_parser.rb', '~>0.6.0'
|
25
25
|
s.add_runtime_dependency 'http-2', '~>0.10.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tipi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.33'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: polyphony
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.47.5.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.47.5.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: http_parser.rb
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- examples/http_server_graceful.rb
|
186
186
|
- examples/http_server_simple.rb
|
187
187
|
- examples/http_server_throttled.rb
|
188
|
+
- examples/http_server_throttled_accept.rb
|
188
189
|
- examples/http_server_timeout.rb
|
189
190
|
- examples/http_ws_server.rb
|
190
191
|
- examples/https_server.rb
|
@@ -240,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
240
241
|
- !ruby/object:Gem::Version
|
241
242
|
version: '0'
|
242
243
|
requirements: []
|
243
|
-
rubygems_version: 3.1.
|
244
|
+
rubygems_version: 3.1.4
|
244
245
|
signing_key:
|
245
246
|
specification_version: 4
|
246
247
|
summary: Tipi - the All-in-one Web Server for Ruby Apps
|