tipi 0.32 → 0.33
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 +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
|