tipi 0.31 → 0.36
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 +29 -0
- data/Gemfile.lock +10 -4
- data/LICENSE +1 -1
- data/TODO.md +13 -47
- data/bin/tipi +13 -0
- data/df/agent.rb +63 -0
- data/df/etc_benchmark.rb +15 -0
- data/df/multi_agent_supervisor.rb +87 -0
- data/df/multi_client.rb +84 -0
- data/df/routing_benchmark.rb +60 -0
- data/df/sample_agent.rb +89 -0
- data/df/server.rb +54 -0
- data/df/sse_page.html +29 -0
- data/df/stress.rb +24 -0
- data/df/ws_page.html +38 -0
- data/examples/http_request_ws_server.rb +34 -0
- data/examples/http_server.rb +6 -6
- data/examples/http_server_forked.rb +4 -5
- data/examples/http_server_form.rb +23 -0
- data/examples/http_server_throttled_accept.rb +23 -0
- data/examples/http_unix_socket_server.rb +17 -0
- data/examples/http_ws_server.rb +10 -12
- data/examples/routing_server.rb +34 -0
- data/examples/websocket_client.rb +1 -2
- data/examples/websocket_demo.rb +4 -2
- data/examples/ws_page.html +1 -2
- data/lib/tipi.rb +7 -5
- data/lib/tipi/config_dsl.rb +153 -0
- data/lib/tipi/configuration.rb +1 -1
- data/lib/tipi/digital_fabric.rb +7 -0
- data/lib/tipi/digital_fabric/agent.rb +225 -0
- data/lib/tipi/digital_fabric/agent_proxy.rb +265 -0
- data/lib/tipi/digital_fabric/executive.rb +100 -0
- data/lib/tipi/digital_fabric/executive/index.html +69 -0
- data/lib/tipi/digital_fabric/protocol.rb +90 -0
- data/lib/tipi/digital_fabric/request_adapter.rb +48 -0
- data/lib/tipi/digital_fabric/service.rb +230 -0
- data/lib/tipi/http1_adapter.rb +59 -37
- data/lib/tipi/http2_adapter.rb +5 -3
- data/lib/tipi/http2_stream.rb +19 -7
- data/lib/tipi/rack_adapter.rb +11 -3
- data/lib/tipi/version.rb +1 -1
- data/lib/tipi/websocket.rb +33 -13
- data/test/helper.rb +1 -2
- data/test/test_http_server.rb +3 -2
- data/test/test_request.rb +108 -0
- data/tipi.gemspec +7 -3
- metadata +59 -7
- data/lib/tipi/request.rb +0 -118
data/lib/tipi/http2_adapter.rb
CHANGED
@@ -15,6 +15,7 @@ module Tipi
|
|
15
15
|
@conn = conn
|
16
16
|
@opts = opts
|
17
17
|
@upgrade_headers = upgrade_headers
|
18
|
+
@first = true
|
18
19
|
|
19
20
|
@interface = ::HTTP2::Server.new
|
20
21
|
@connection_fiber = Fiber.current
|
@@ -37,7 +38,7 @@ module Tipi
|
|
37
38
|
|
38
39
|
def upgrade
|
39
40
|
@conn << UPGRADE_MESSAGE
|
40
|
-
settings = @upgrade_headers['
|
41
|
+
settings = @upgrade_headers['http2-settings']
|
41
42
|
Fiber.current.schedule(nil)
|
42
43
|
@interface.upgrade(settings, @upgrade_headers, '')
|
43
44
|
ensure
|
@@ -49,7 +50,7 @@ module Tipi
|
|
49
50
|
@interface.on(:stream) { |stream| start_stream(stream, &block) }
|
50
51
|
upgrade if @upgrade_headers
|
51
52
|
|
52
|
-
@conn.
|
53
|
+
@conn.recv_loop(&@interface.method(:<<))
|
53
54
|
rescue SystemCallError, IOError
|
54
55
|
# ignore
|
55
56
|
ensure
|
@@ -57,7 +58,8 @@ module Tipi
|
|
57
58
|
end
|
58
59
|
|
59
60
|
def start_stream(stream, &block)
|
60
|
-
stream = HTTP2StreamHandler.new(stream, &block)
|
61
|
+
stream = HTTP2StreamHandler.new(stream, @conn, @first, &block)
|
62
|
+
@first = nil if @first
|
61
63
|
@streams[stream] = true
|
62
64
|
end
|
63
65
|
|
data/lib/tipi/http2_stream.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'http/2'
|
4
|
-
|
4
|
+
require 'qeweney/request'
|
5
5
|
|
6
6
|
module Tipi
|
7
7
|
# Manages an HTTP 2 stream
|
8
8
|
class HTTP2StreamHandler
|
9
9
|
attr_accessor :__next__
|
10
|
+
attr_reader :conn
|
10
11
|
|
11
|
-
def initialize(stream, &block)
|
12
|
+
def initialize(stream, conn, first, &block)
|
12
13
|
@stream = stream
|
14
|
+
@conn = conn
|
15
|
+
@first = first
|
13
16
|
@connection_fiber = Fiber.current
|
14
17
|
@stream_fiber = spin { |req| handle_request(req, &block) }
|
15
18
|
|
@@ -43,7 +46,11 @@ module Tipi
|
|
43
46
|
end
|
44
47
|
|
45
48
|
def on_headers(headers)
|
46
|
-
@request = Request.new(headers.to_h, self)
|
49
|
+
@request = Qeweney::Request.new(headers.to_h, self)
|
50
|
+
if @first
|
51
|
+
@request.headers[':first'] = true
|
52
|
+
@first = false
|
53
|
+
end
|
47
54
|
@stream_fiber.schedule @request
|
48
55
|
end
|
49
56
|
|
@@ -96,7 +103,7 @@ module Tipi
|
|
96
103
|
|
97
104
|
# response API
|
98
105
|
def respond(chunk, headers)
|
99
|
-
headers[':status'] ||=
|
106
|
+
headers[':status'] ||= Qeweney::Status::OK
|
100
107
|
@stream.headers(headers, end_stream: false)
|
101
108
|
@stream.data(chunk, end_stream: true)
|
102
109
|
@headers_sent = true
|
@@ -105,21 +112,26 @@ module Tipi
|
|
105
112
|
def send_headers(headers, empty_response = false)
|
106
113
|
return if @headers_sent
|
107
114
|
|
108
|
-
headers[':status'] ||= (empty_response ?
|
115
|
+
headers[':status'] ||= (empty_response ? Qeweney::Status::NO_CONTENT : Qeweney::Status::OK).to_s
|
109
116
|
@stream.headers(headers, end_stream: false)
|
110
117
|
@headers_sent = true
|
111
118
|
end
|
112
119
|
|
113
120
|
def send_chunk(chunk, done: false)
|
114
121
|
send_headers({}, false) unless @headers_sent
|
115
|
-
|
122
|
+
|
123
|
+
if chunk
|
124
|
+
@stream.data(chunk, end_stream: done)
|
125
|
+
elsif done
|
126
|
+
@stream.close
|
127
|
+
end
|
116
128
|
end
|
117
129
|
|
118
130
|
def finish
|
119
131
|
if @headers_sent
|
120
132
|
@stream.close
|
121
133
|
else
|
122
|
-
headers[':status'] ||=
|
134
|
+
headers[':status'] ||= Qeweney::Status::NO_CONTENT
|
123
135
|
@stream.headers(headers, end_stream: true)
|
124
136
|
end
|
125
137
|
end
|
data/lib/tipi/rack_adapter.rb
CHANGED
@@ -62,16 +62,24 @@ module Tipi
|
|
62
62
|
when 'REQUEST_METHOD' then request.method
|
63
63
|
when 'PATH_INFO' then request.path
|
64
64
|
when 'QUERY_STRING' then request.query_string || ''
|
65
|
-
when 'SERVER_NAME' then request.headers['
|
65
|
+
when 'SERVER_NAME' then request.headers['host']
|
66
66
|
when 'rack.input' then InputStream.new(request)
|
67
67
|
when HTTP_HEADER_RE then request.headers[$1.downcase]
|
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
@@ -7,13 +7,13 @@ module Tipi
|
|
7
7
|
# Websocket connection
|
8
8
|
class Websocket
|
9
9
|
def self.handler(&block)
|
10
|
-
proc { |
|
11
|
-
block.(new(
|
10
|
+
proc { |conn, headers|
|
11
|
+
block.(new(conn, headers))
|
12
12
|
}
|
13
13
|
end
|
14
14
|
|
15
|
-
def initialize(
|
16
|
-
@
|
15
|
+
def initialize(conn, headers)
|
16
|
+
@conn = conn
|
17
17
|
@headers = headers
|
18
18
|
setup(headers)
|
19
19
|
end
|
@@ -28,22 +28,38 @@ module Tipi
|
|
28
28
|
HTTP
|
29
29
|
|
30
30
|
def setup(headers)
|
31
|
-
key = headers['
|
32
|
-
@version = headers['
|
31
|
+
key = headers['sec-websocket-key']
|
32
|
+
@version = headers['sec-websocket-version'].to_i
|
33
33
|
accept = Digest::SHA1.base64digest([key, S_WS_GUID].join)
|
34
|
-
@
|
34
|
+
@conn << format(UPGRADE_RESPONSE, accept: accept)
|
35
35
|
|
36
36
|
@reader = ::WebSocket::Frame::Incoming::Server.new(version: @version)
|
37
37
|
end
|
38
38
|
|
39
39
|
def recv
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
if (msg = @reader.next)
|
41
|
+
return msg.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
@conn.recv_loop do |data|
|
44
45
|
@reader << data
|
45
46
|
if (msg = @reader.next)
|
46
|
-
|
47
|
+
return msg.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def recv_loop
|
55
|
+
if (msg = @reader.next)
|
56
|
+
yield msg.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
@conn.recv_loop do |data|
|
60
|
+
@reader << data
|
61
|
+
while (msg = @reader.next)
|
62
|
+
yield msg.to_s
|
47
63
|
end
|
48
64
|
end
|
49
65
|
end
|
@@ -52,8 +68,12 @@ module Tipi
|
|
52
68
|
frame = ::WebSocket::Frame::Outgoing::Server.new(
|
53
69
|
version: @version, data: data, type: :text
|
54
70
|
)
|
55
|
-
@
|
71
|
+
@conn << frame.to_s
|
56
72
|
end
|
57
73
|
alias_method :<<, :send
|
74
|
+
|
75
|
+
def close
|
76
|
+
@conn.close
|
77
|
+
end
|
58
78
|
end
|
59
79
|
end
|
data/test/helper.rb
CHANGED
@@ -33,8 +33,7 @@ class MiniTest::Test
|
|
33
33
|
|
34
34
|
def teardown
|
35
35
|
# puts "* teardown #{self.name.inspect} Fiber.current: #{Fiber.current.inspect}"
|
36
|
-
Fiber.current.
|
37
|
-
Fiber.current.await_all_children
|
36
|
+
Fiber.current.shutdown_all_children
|
38
37
|
rescue => e
|
39
38
|
puts e
|
40
39
|
puts e.backtrace.join("\n")
|
data/test/test_http_server.rb
CHANGED
@@ -25,7 +25,9 @@ class IO
|
|
25
25
|
eg(
|
26
26
|
:read => ->(*args) { input.read(*args) },
|
27
27
|
:read_loop => ->(*args, &block) { input.read_loop(*args, &block) },
|
28
|
+
:recv_loop => ->(*args, &block) { input.read_loop(*args, &block) },
|
28
29
|
:readpartial => ->(*args) { input.readpartial(*args) },
|
30
|
+
:recv => ->(*args) { input.readpartial(*args) },
|
29
31
|
:<< => ->(*args) { output.write(*args) },
|
30
32
|
:write => ->(*args) { output.write(*args) },
|
31
33
|
:close => -> { output.close },
|
@@ -89,7 +91,6 @@ class HTTP1ServerTest < MiniTest::Test
|
|
89
91
|
end
|
90
92
|
|
91
93
|
def test_that_server_maintains_connection_when_using_keep_alives
|
92
|
-
puts 'test_that_server_maintains_connection_when_using_keep_alives'
|
93
94
|
@server, connection = spin_server do |req|
|
94
95
|
req.respond('Hi', {})
|
95
96
|
end
|
@@ -121,7 +122,7 @@ class HTTP1ServerTest < MiniTest::Test
|
|
121
122
|
|
122
123
|
def test_pipelining_client
|
123
124
|
@server, connection = spin_server do |req|
|
124
|
-
if req.headers['
|
125
|
+
if req.headers['foo'] == 'bar'
|
125
126
|
req.respond('Hello, foobar!', {})
|
126
127
|
else
|
127
128
|
req.respond('Hello, world!', {})
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require 'tipi'
|
5
|
+
|
6
|
+
class String
|
7
|
+
def http_lines
|
8
|
+
gsub "\n", "\r\n"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class IO
|
13
|
+
# Creates two mockup sockets for simulating server-client communication
|
14
|
+
def self.server_client_mockup
|
15
|
+
server_in, client_out = IO.pipe
|
16
|
+
client_in, server_out = IO.pipe
|
17
|
+
|
18
|
+
server_connection = mockup_connection(server_in, server_out, client_out)
|
19
|
+
client_connection = mockup_connection(client_in, client_out, server_out)
|
20
|
+
|
21
|
+
[server_connection, client_connection]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.mockup_connection(input, output, output2)
|
25
|
+
eg(
|
26
|
+
:read => ->(*args) { input.read(*args) },
|
27
|
+
:read_loop => ->(*args, &block) { input.read_loop(*args, &block) },
|
28
|
+
:recv_loop => ->(*args, &block) { input.read_loop(*args, &block) },
|
29
|
+
:readpartial => ->(*args) { input.readpartial(*args) },
|
30
|
+
:recv => ->(*args) { input.readpartial(*args) },
|
31
|
+
:<< => ->(*args) { output.write(*args) },
|
32
|
+
:write => ->(*args) { output.write(*args) },
|
33
|
+
:close => -> { output.close },
|
34
|
+
:eof? => -> { output2.closed? }
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class RequestHeadersTest < MiniTest::Test
|
40
|
+
def teardown
|
41
|
+
@server&.interrupt if @server&.alive?
|
42
|
+
snooze
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
def spin_server(opts = {}, &handler)
|
47
|
+
server_connection, client_connection = IO.server_client_mockup
|
48
|
+
coproc = spin do
|
49
|
+
Tipi.client_loop(server_connection, opts, &handler)
|
50
|
+
end
|
51
|
+
[coproc, client_connection, server_connection]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_request_headers
|
55
|
+
req = nil
|
56
|
+
@server, connection = spin_server do |r|
|
57
|
+
req = r
|
58
|
+
req.respond('Hello, world!')
|
59
|
+
end
|
60
|
+
|
61
|
+
connection << "GET /titi HTTP/1.1\r\nHost: blah.com\r\nFoo: bar\r\nhi: 1\r\nHi: 2\r\nhi: 3\r\n\r\n"
|
62
|
+
|
63
|
+
snooze
|
64
|
+
|
65
|
+
assert_kind_of Qeweney::Request, req
|
66
|
+
assert_equal 'blah.com', req.headers['host']
|
67
|
+
assert_equal 'bar', req.headers['foo']
|
68
|
+
assert_equal ['1', '3', '2'], req.headers['hi']
|
69
|
+
assert_equal 'get', req.headers[':method']
|
70
|
+
assert_equal '/titi', req.headers[':path']
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_request_host
|
74
|
+
req = nil
|
75
|
+
@server, connection = spin_server do |r|
|
76
|
+
req = r
|
77
|
+
req.respond('Hello, world!')
|
78
|
+
end
|
79
|
+
|
80
|
+
connection << "GET /titi HTTP/1.1\nHost: blah.com\nFoo: bar\nhi: 1\nHi: 2\nhi: 3\n\n"
|
81
|
+
snooze
|
82
|
+
assert_equal 'blah.com', req.host
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_request_connection
|
86
|
+
req = nil
|
87
|
+
@server, connection = spin_server do |r|
|
88
|
+
req = r
|
89
|
+
req.respond('Hello, world!')
|
90
|
+
end
|
91
|
+
|
92
|
+
connection << "GET /titi HTTP/1.1\nConnection: keep-alive\nFoo: bar\nhi: 1\nHi: 2\nhi: 3\n\n"
|
93
|
+
snooze
|
94
|
+
assert_equal 'keep-alive', req.connection
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_request_upgrade_protocol
|
98
|
+
req = nil
|
99
|
+
@server, connection = spin_server do |r|
|
100
|
+
req = r
|
101
|
+
req.respond('Hello, world!')
|
102
|
+
end
|
103
|
+
|
104
|
+
connection << "GET /titi HTTP/1.1\nConnection: upgrade\nUpgrade: foobar\n\n"
|
105
|
+
snooze
|
106
|
+
assert_equal 'foobar', req.upgrade_protocol
|
107
|
+
end
|
108
|
+
end
|
data/tipi.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.licenses = ['MIT']
|
7
7
|
s.summary = 'Tipi - the All-in-one Web Server for Ruby Apps'
|
8
8
|
s.author = 'Sharon Rosner'
|
9
|
-
s.email = '
|
9
|
+
s.email = 'sharon@noteflakes.com'
|
10
10
|
s.files = `git ls-files`.split
|
11
11
|
s.homepage = 'http://github.com/digital-fabric/tipi'
|
12
12
|
s.metadata = {
|
@@ -19,13 +19,17 @@ 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.51.0'
|
23
|
+
s.add_runtime_dependency 'qeweney', '~>0.3'
|
23
24
|
|
24
25
|
s.add_runtime_dependency 'http_parser.rb', '~>0.6.0'
|
25
26
|
s.add_runtime_dependency 'http-2', '~>0.10.0'
|
26
27
|
s.add_runtime_dependency 'rack', '>=2.0.8', '<2.3.0'
|
27
28
|
s.add_runtime_dependency 'websocket', '~>1.2.8'
|
28
|
-
|
29
|
+
|
30
|
+
# for digital fabric
|
31
|
+
s.add_runtime_dependency 'msgpack', '~>1.4.2'
|
32
|
+
|
29
33
|
s.add_development_dependency 'rake', '~>12.3.3'
|
30
34
|
s.add_development_dependency 'localhost', '~>1.1.4'
|
31
35
|
s.add_development_dependency 'minitest', '~>5.11.3'
|
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.36'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: polyphony
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.51.0
|
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.51.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: qeweney
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.3'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: http_parser.rb
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +100,20 @@ dependencies:
|
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
102
|
version: 1.2.8
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: msgpack
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.4.2
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.4.2
|
89
117
|
- !ruby/object:Gem::Dependency
|
90
118
|
name: rake
|
91
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,7 +185,7 @@ dependencies:
|
|
157
185
|
- !ruby/object:Gem::Version
|
158
186
|
version: 0.17.1
|
159
187
|
description:
|
160
|
-
email:
|
188
|
+
email: sharon@noteflakes.com
|
161
189
|
executables:
|
162
190
|
- tipi
|
163
191
|
extensions: []
|
@@ -174,18 +202,32 @@ files:
|
|
174
202
|
- Rakefile
|
175
203
|
- TODO.md
|
176
204
|
- bin/tipi
|
205
|
+
- df/agent.rb
|
206
|
+
- df/etc_benchmark.rb
|
207
|
+
- df/multi_agent_supervisor.rb
|
208
|
+
- df/multi_client.rb
|
209
|
+
- df/routing_benchmark.rb
|
210
|
+
- df/sample_agent.rb
|
211
|
+
- df/server.rb
|
212
|
+
- df/sse_page.html
|
213
|
+
- df/stress.rb
|
214
|
+
- df/ws_page.html
|
177
215
|
- docs/README.md
|
178
216
|
- docs/tipi-logo.png
|
179
217
|
- examples/cuba.ru
|
180
218
|
- examples/hanami-api.ru
|
181
219
|
- examples/hello.ru
|
220
|
+
- examples/http_request_ws_server.rb
|
182
221
|
- examples/http_server.js
|
183
222
|
- examples/http_server.rb
|
184
223
|
- examples/http_server_forked.rb
|
224
|
+
- examples/http_server_form.rb
|
185
225
|
- examples/http_server_graceful.rb
|
186
226
|
- examples/http_server_simple.rb
|
187
227
|
- examples/http_server_throttled.rb
|
228
|
+
- examples/http_server_throttled_accept.rb
|
188
229
|
- examples/http_server_timeout.rb
|
230
|
+
- examples/http_unix_socket_server.rb
|
189
231
|
- examples/http_ws_server.rb
|
190
232
|
- examples/https_server.rb
|
191
233
|
- examples/https_server_forked.rb
|
@@ -193,6 +235,7 @@ files:
|
|
193
235
|
- examples/rack_server.rb
|
194
236
|
- examples/rack_server_https.rb
|
195
237
|
- examples/rack_server_https_forked.rb
|
238
|
+
- examples/routing_server.rb
|
196
239
|
- examples/websocket_client.rb
|
197
240
|
- examples/websocket_demo.rb
|
198
241
|
- examples/websocket_secure_server.rb
|
@@ -200,13 +243,21 @@ files:
|
|
200
243
|
- examples/ws_page.html
|
201
244
|
- examples/wss_page.html
|
202
245
|
- lib/tipi.rb
|
246
|
+
- lib/tipi/config_dsl.rb
|
203
247
|
- lib/tipi/configuration.rb
|
248
|
+
- lib/tipi/digital_fabric.rb
|
249
|
+
- lib/tipi/digital_fabric/agent.rb
|
250
|
+
- lib/tipi/digital_fabric/agent_proxy.rb
|
251
|
+
- lib/tipi/digital_fabric/executive.rb
|
252
|
+
- lib/tipi/digital_fabric/executive/index.html
|
253
|
+
- lib/tipi/digital_fabric/protocol.rb
|
254
|
+
- lib/tipi/digital_fabric/request_adapter.rb
|
255
|
+
- lib/tipi/digital_fabric/service.rb
|
204
256
|
- lib/tipi/handler.rb
|
205
257
|
- lib/tipi/http1_adapter.rb
|
206
258
|
- lib/tipi/http2_adapter.rb
|
207
259
|
- lib/tipi/http2_stream.rb
|
208
260
|
- lib/tipi/rack_adapter.rb
|
209
|
-
- lib/tipi/request.rb
|
210
261
|
- lib/tipi/version.rb
|
211
262
|
- lib/tipi/websocket.rb
|
212
263
|
- test/coverage.rb
|
@@ -214,6 +265,7 @@ files:
|
|
214
265
|
- test/helper.rb
|
215
266
|
- test/run.rb
|
216
267
|
- test/test_http_server.rb
|
268
|
+
- test/test_request.rb
|
217
269
|
- tipi.gemspec
|
218
270
|
homepage: http://github.com/digital-fabric/tipi
|
219
271
|
licenses:
|
@@ -239,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
291
|
- !ruby/object:Gem::Version
|
240
292
|
version: '0'
|
241
293
|
requirements: []
|
242
|
-
rubygems_version: 3.1.
|
294
|
+
rubygems_version: 3.1.4
|
243
295
|
signing_key:
|
244
296
|
specification_version: 4
|
245
297
|
summary: Tipi - the All-in-one Web Server for Ruby Apps
|