tipi 0.54 → 0.55

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d233f020bba51d04d83ad3bc0af0fba949a4988ed206cb3eb27c6cb66e9d581
4
- data.tar.gz: 7462a9e229e3d78dbed4ffac92029b6fa117df683b425102f6de259eab8adc2c
3
+ metadata.gz: f39c7acb6549a60cd3ca5ae50f81ecf0aa1dc9e48f4e9909ae52813c97164079
4
+ data.tar.gz: 38a9f51b362c504112d07452b3ff4e4c8f4abb78334b2714878fb272acc615df
5
5
  SHA512:
6
- metadata.gz: d0fff68a7a6848dbaf6a3b5f846ada34542b532bc42d79821c47981354214c914130fda8192ffe12bc334554264297000afe82742388713de87356e17e6dc8a6
7
- data.tar.gz: d8e9c715aace1b1dc26a78a5463016f4d0a65c552fa865a8b471ccb60955abd350304d1ae7db1ddaeebd4577ded25b048078c3e4fe39abe5e32385cbb5eddae3
6
+ metadata.gz: 5f7f1689ae93c1f1c0920baebd5f008380ad5d09a62cede06338003e169abd95848b56f5869cea0e2fc4e05a9563a07300b831baca6db234ec6dbd8189ab3dab
7
+ data.tar.gz: 4ce699f1a0d32eb39913d1bf99fb96f8302667262ae1bc29cc665464a491f6a753cb946c5c6279ffbd35b02e6948049cd706e8617dad961948cb35fc4a19b1fa
@@ -8,15 +8,15 @@ jobs:
8
8
  fail-fast: false
9
9
  matrix:
10
10
  os: [ubuntu-latest, macos-latest]
11
- ruby: ['3.0', '3.1', '3.2', 'head']
11
+ ruby: ['3.1', '3.2', 'head']
12
12
 
13
13
  name: >-
14
14
  ${{matrix.os}}, ${{matrix.ruby}}
15
15
 
16
16
  runs-on: ${{matrix.os}}
17
17
 
18
- env:
19
- POLYPHONY_LIBEV: "1"
18
+ # env:
19
+ # POLYPHONY_LIBEV: "1"
20
20
 
21
21
  steps:
22
22
  - name: Setup machine
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.55 2023-07-29
2
+
3
+ - Simplify HTTP/1 exception handling
4
+ - Update H1P dependency
5
+ - Update Extralite dependency (#28)
6
+
1
7
  ## 0.54 2023-05-28
2
8
 
3
9
  - Use `H1P.send_response` for sending response
data/Gemfile.lock CHANGED
@@ -1,23 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tipi (0.54)
5
- acme-client (~> 2.0.9)
6
- ever (~> 0.1)
7
- extralite (~> 1.25)
8
- h1p (~> 0.6.1)
4
+ tipi (0.55)
5
+ acme-client (~> 2.0.14)
6
+ ever (~> 0.2)
7
+ extralite (~> 2.1)
8
+ h1p (~> 1.1)
9
9
  http-2 (~> 0.11)
10
- localhost (~> 1.1.4)
11
- msgpack (~> 1.4.2)
12
- polyphony (~> 1.0.2)
10
+ localhost (~> 1.1.10)
11
+ msgpack (~> 1.7.1)
12
+ polyphony (~> 1.4)
13
13
  qeweney (~> 0.18)
14
- rack (>= 2.0.8, < 2.3.0)
15
- websocket (~> 1.2.8)
14
+ rack (>= 2.0.8, < 3.1.0)
15
+ websocket (~> 1.2.9)
16
16
 
17
17
  GEM
18
18
  remote: https://rubygems.org/
19
19
  specs:
20
- acme-client (2.0.13)
20
+ acme-client (2.0.14)
21
21
  faraday (>= 1.0, < 3.0.0)
22
22
  faraday-retry (>= 1.0, < 3.0.0)
23
23
  cuba (3.9.3)
@@ -25,31 +25,31 @@ GEM
25
25
  docile (1.4.0)
26
26
  escape_utils (1.2.2)
27
27
  ever (0.2)
28
- extralite (1.26)
29
- faraday (2.7.5)
28
+ extralite (2.1)
29
+ faraday (2.7.10)
30
30
  faraday-net_http (>= 2.0, < 3.1)
31
31
  ruby2_keywords (>= 0.0.4)
32
32
  faraday-net_http (3.0.2)
33
- faraday-retry (2.1.0)
33
+ faraday-retry (2.2.0)
34
34
  faraday (~> 2.0)
35
- h1p (0.6.1)
35
+ h1p (1.1)
36
36
  http-2 (0.11.0)
37
- json (2.6.3)
38
37
  localhost (1.1.10)
39
38
  memory_profiler (1.0.1)
40
- minitest (5.11.3)
41
- msgpack (1.4.5)
42
- polyphony (1.0.2)
39
+ minitest (5.18.1)
40
+ msgpack (1.7.2)
41
+ polyphony (1.4)
43
42
  qeweney (0.18)
44
43
  escape_utils (~> 1.2.1)
45
- rack (2.2.7)
44
+ rack (3.0.8)
46
45
  rake (13.0.6)
47
46
  ruby2_keywords (0.0.5)
48
- simplecov (0.17.1)
47
+ simplecov (0.22.0)
49
48
  docile (~> 1.1)
50
- json (>= 1.8, < 3)
51
- simplecov-html (~> 0.10.0)
52
- simplecov-html (0.10.2)
49
+ simplecov-html (~> 0.11)
50
+ simplecov_json_formatter (~> 0.1)
51
+ simplecov-html (0.12.3)
52
+ simplecov_json_formatter (0.1.4)
53
53
  websocket (1.2.9)
54
54
 
55
55
  PLATFORMS
@@ -57,10 +57,10 @@ PLATFORMS
57
57
 
58
58
  DEPENDENCIES
59
59
  cuba (~> 3.9.3)
60
- memory_profiler (~> 1.0.0)
61
- minitest (~> 5.11.3)
60
+ memory_profiler (~> 1.0.1)
61
+ minitest (~> 5.18.1)
62
62
  rake (~> 13.0.6)
63
- simplecov (~> 0.17.1)
63
+ simplecov (~> 0.22.0)
64
64
  tipi!
65
65
 
66
66
  BUNDLED WITH
data/TODO.md CHANGED
@@ -1,52 +1,12 @@
1
- ## Add an API for reading a request body chunk into an IO (pipe)
1
+ ## Rethink design
2
2
 
3
- ```ruby
4
- # currently
5
- chunk = req.next_chunk
6
- # or
7
- req.each_chunk { |c| do_something(c) }
3
+ - Remove DF code
4
+ - Remove non-Polyphony code
8
5
 
9
- # what we'd like to do
10
- r, w = IO.pipe
11
- len = req.splice_chunk(w)
12
- sock << "Here comes a chunk of #{len} bytes\n"
13
- sock.splice(r, len)
6
+ # Miscellaneous
14
7
 
15
- # or:
16
- r, w = IO.pipe
17
- req.splice_each_chunk(w) do |len|
18
- sock << "Here comes a chunk of #{len} bytes\n"
19
- sock.splice(r, len)
20
- end
21
- ```
22
-
23
- # HTTP/1.1 parser
24
-
25
- - httparser.rb is not actively updated
26
- - the httparser.rb C parser code comes originally from https://github.com/nodejs/llhttp
27
- - there's a Ruby gem https://github.com/metabahn/llhttp, but its API is too low-level
28
- (lots of callbacks, headers need to be retained across callbacks)
29
- - the basic idea is to import the C-code, then build a parser object with the following
30
- callbacks:
31
-
32
- ```ruby
33
- on_headers_complete(headers)
34
- on_body_chunk(chunk)
35
- on_message_complete
36
- ```
37
-
38
- - The llhttp gem's C-code is here: https://github.com/metabahn/llhttp/tree/main/mri
39
-
40
- - Actually, if you do a C extension, instead of a callback-based API, we can
41
- design a blocking API:
42
-
43
- ```ruby
44
- parser = Tipi::HTTP1::Parser.new
45
- parser.each_request(socket) do |headers|
46
- request = Request.new(normalize_headers(headers))
47
- handle_request(request)
48
- end
49
- ```
8
+ - Try using `TCP_DEFER_ACCEPT` with Polyphony on io_uring - does it provide any
9
+ performance benefit?
50
10
 
51
11
  # What about HTTP/2?
52
12
 
@@ -61,26 +21,8 @@ end
61
21
  ```
62
22
 
63
23
 
64
-
65
- # DF
66
-
67
- - Add attack protection for IP-address HTTP host:
68
-
69
- ```ruby
70
- IPV4_REGEXP = /^\d+\.\d+\.\d+\.\d+$/.freeze
71
-
72
- def is_attack_request?(req)
73
- return true if req.host =~ IPV4_REGEXP && req.query[:q] != 'ping'
74
- end
75
- ```
76
-
77
- - Add attack route to Qeweney routing API
78
-
79
-
80
-
81
24
  # Roadmap
82
25
 
83
- - Update README (get rid of non-http stuff)
84
26
  - Improve Rack spec compliance, add tests
85
27
  - Homogenize HTTP 1 and HTTP 2 headers - downcase symbols
86
28
 
@@ -14,7 +14,7 @@ module Tipi
14
14
 
15
15
  def app
16
16
  return @app if @app
17
-
17
+
18
18
  raise 'No app define. The app to run should be set using `Tipi.app = ...`'
19
19
  end
20
20
 
@@ -27,13 +27,8 @@ module Tipi
27
27
  # upgraded
28
28
  break if handle_request(headers, &block)
29
29
  end
30
- rescue H1P::Error, ArgumentError
31
- # an ArgumentError might be raised in the parser if an invalid input
32
- # string is given as the HTTP method (String#upcase will raise on invalid HTTP string)
33
- #
34
- # ignore
35
- rescue SystemCallError, IOError
36
- # ignore
30
+ rescue SystemCallError, IOError, H1P::Error
31
+ # connection or parser error, ignore
37
32
  ensure
38
33
  finalize_client_loop
39
34
  end
@@ -160,7 +155,7 @@ module Tipi
160
155
  # response API
161
156
 
162
157
  CRLF = "\r\n"
163
-
158
+
164
159
  # Sends response including headers and body. Waits for the request to complete
165
160
  # if not yet completed. The body is sent using chunked transfer encoding.
166
161
  # @param request [Qeweney::Request] HTTP request
data/lib/tipi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tipi
4
- VERSION = '0.54'
4
+ VERSION = '0.55'
5
5
  end
@@ -12,7 +12,7 @@ end
12
12
  class HTTP1ServerTest < MiniTest::Test
13
13
  def teardown
14
14
  @server&.interrupt if @server&.alive?
15
- snooze
15
+ sleep 0.01
16
16
  super
17
17
  end
18
18
 
@@ -67,11 +67,13 @@ class HTTP1ServerTest < MiniTest::Test
67
67
 
68
68
  connection << "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"
69
69
  response = connection.readpartial(8192)
70
+ sleep 0.01
70
71
  assert !connection.eof?
71
72
  assert_equal("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi", response)
72
73
 
73
74
  connection << "GET / HTTP/1.1\r\n\r\n"
74
75
  response = connection.readpartial(8192)
76
+ sleep 0.01
75
77
  assert !connection.eof?
76
78
  expected = <<~HTTP.crlf_lines.chomp
77
79
  HTTP/1.1 200 OK
@@ -83,6 +85,7 @@ class HTTP1ServerTest < MiniTest::Test
83
85
 
84
86
  connection << "GET / HTTP/1.0\r\n\r\n"
85
87
  response = connection.readpartial(8192)
88
+ sleep 0.01
86
89
  assert connection.eof?
87
90
  assert_equal("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi", response)
88
91
  end
@@ -191,6 +194,7 @@ class HTTP1ServerTest < MiniTest::Test
191
194
 
192
195
  connection << "GET / HTTP/1.1\r\n\r\n"
193
196
  response = connection.readpartial(8192)
197
+ sleep 0.01
194
198
  assert !connection.eof?
195
199
  expected = <<~HTTP.crlf_lines.chomp
196
200
  HTTP/1.1 200 OK
@@ -209,6 +213,7 @@ class HTTP1ServerTest < MiniTest::Test
209
213
 
210
214
  snooze
211
215
  response = connection.readpartial(8192)
216
+ snooze
212
217
  assert !connection.eof?
213
218
  expected = <<~HTTP.crlf_lines
214
219
  HTTP/1.1 101 Switching Protocols
data/tipi.gemspec CHANGED
@@ -18,29 +18,29 @@ Gem::Specification.new do |s|
18
18
  s.rdoc_options = ["--title", "tipi", "--main", "README.md"]
19
19
  s.extra_rdoc_files = ["README.md"]
20
20
  s.require_paths = ["lib"]
21
- s.required_ruby_version = '>= 2.7'
21
+ s.required_ruby_version = '>= 3.1'
22
22
 
23
23
  s.executables = ['tipi']
24
24
 
25
- s.add_runtime_dependency 'polyphony', '~>1.0.2'
26
- s.add_runtime_dependency 'ever', '~>0.1'
25
+ s.add_runtime_dependency 'polyphony', '~>1.4'
26
+ s.add_runtime_dependency 'ever', '~>0.2'
27
27
  s.add_runtime_dependency 'qeweney', '~>0.18'
28
- s.add_runtime_dependency 'extralite', '~>1.25'
29
- s.add_runtime_dependency 'h1p', '~>0.6.1'
28
+ s.add_runtime_dependency 'extralite', '~>2.1'
29
+ s.add_runtime_dependency 'h1p', '~>1.1'
30
30
 
31
31
  s.add_runtime_dependency 'http-2', '~>0.11'
32
- s.add_runtime_dependency 'rack', '>=2.0.8', '<2.3.0'
33
- s.add_runtime_dependency 'websocket', '~>1.2.8'
34
- s.add_runtime_dependency 'acme-client', '~>2.0.9'
35
- s.add_runtime_dependency 'localhost', '~>1.1.4'
32
+ s.add_runtime_dependency 'rack', '>=2.0.8', '<3.1.0'
33
+ s.add_runtime_dependency 'websocket', '~>1.2.9'
34
+ s.add_runtime_dependency 'acme-client', '~>2.0.14'
35
+ s.add_runtime_dependency 'localhost', '~>1.1.10'
36
36
 
37
37
  # for digital fabric
38
- s.add_runtime_dependency 'msgpack', '~>1.4.2'
38
+ s.add_runtime_dependency 'msgpack', '~>1.7.1'
39
39
 
40
40
  s.add_development_dependency 'rake', '~>13.0.6'
41
- s.add_development_dependency 'minitest', '~>5.11.3'
42
- s.add_development_dependency 'simplecov', '~>0.17.1'
43
- s.add_development_dependency 'memory_profiler', '~>1.0.0'
41
+ s.add_development_dependency 'minitest', '~>5.18.1'
42
+ s.add_development_dependency 'simplecov', '~>0.22.0'
43
+ s.add_development_dependency 'memory_profiler', '~>1.0.1'
44
44
 
45
45
  s.add_development_dependency 'cuba', '~>3.9.3'
46
46
  end
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.54'
4
+ version: '0.55'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-28 00:00:00.000000000 Z
11
+ date: 2023-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: polyphony
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.2
19
+ version: '1.4'
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: 1.0.2
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ever
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.1'
33
+ version: '0.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.1'
40
+ version: '0.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: qeweney
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.25'
61
+ version: '2.1'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.25'
68
+ version: '2.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: h1p
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.1
75
+ version: '1.1'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.1
82
+ version: '1.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: http-2
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +103,7 @@ dependencies:
103
103
  version: 2.0.8
104
104
  - - "<"
105
105
  - !ruby/object:Gem::Version
106
- version: 2.3.0
106
+ version: 3.1.0
107
107
  type: :runtime
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
@@ -113,63 +113,63 @@ dependencies:
113
113
  version: 2.0.8
114
114
  - - "<"
115
115
  - !ruby/object:Gem::Version
116
- version: 2.3.0
116
+ version: 3.1.0
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: websocket
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: 1.2.8
123
+ version: 1.2.9
124
124
  type: :runtime
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: 1.2.8
130
+ version: 1.2.9
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: acme-client
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: 2.0.9
137
+ version: 2.0.14
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: 2.0.9
144
+ version: 2.0.14
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: localhost
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: 1.1.4
151
+ version: 1.1.10
152
152
  type: :runtime
153
153
  prerelease: false
154
154
  version_requirements: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
- version: 1.1.4
158
+ version: 1.1.10
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: msgpack
161
161
  requirement: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: 1.4.2
165
+ version: 1.7.1
166
166
  type: :runtime
167
167
  prerelease: false
168
168
  version_requirements: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: 1.4.2
172
+ version: 1.7.1
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: rake
175
175
  requirement: !ruby/object:Gem::Requirement
@@ -190,42 +190,42 @@ dependencies:
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: 5.11.3
193
+ version: 5.18.1
194
194
  type: :development
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: 5.11.3
200
+ version: 5.18.1
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: simplecov
203
203
  requirement: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
- version: 0.17.1
207
+ version: 0.22.0
208
208
  type: :development
209
209
  prerelease: false
210
210
  version_requirements: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - "~>"
213
213
  - !ruby/object:Gem::Version
214
- version: 0.17.1
214
+ version: 0.22.0
215
215
  - !ruby/object:Gem::Dependency
216
216
  name: memory_profiler
217
217
  requirement: !ruby/object:Gem::Requirement
218
218
  requirements:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
- version: 1.0.0
221
+ version: 1.0.1
222
222
  type: :development
223
223
  prerelease: false
224
224
  version_requirements: !ruby/object:Gem::Requirement
225
225
  requirements:
226
226
  - - "~>"
227
227
  - !ruby/object:Gem::Version
228
- version: 1.0.0
228
+ version: 1.0.1
229
229
  - !ruby/object:Gem::Dependency
230
230
  name: cuba
231
231
  requirement: !ruby/object:Gem::Requirement
@@ -240,7 +240,7 @@ dependencies:
240
240
  - - "~>"
241
241
  - !ruby/object:Gem::Version
242
242
  version: 3.9.3
243
- description:
243
+ description:
244
244
  email: sharon@noteflakes.com
245
245
  executables:
246
246
  - tipi
@@ -358,7 +358,7 @@ metadata:
358
358
  documentation_uri: https://www.rubydoc.info/gems/tipi
359
359
  homepage_uri: https://github.com/digital-fabric/tipi
360
360
  changelog_uri: https://github.com/digital-fabric/tipi/blob/master/CHANGELOG.md
361
- post_install_message:
361
+ post_install_message:
362
362
  rdoc_options:
363
363
  - "--title"
364
364
  - tipi
@@ -370,7 +370,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
370
370
  requirements:
371
371
  - - ">="
372
372
  - !ruby/object:Gem::Version
373
- version: '2.7'
373
+ version: '3.1'
374
374
  required_rubygems_version: !ruby/object:Gem::Requirement
375
375
  requirements:
376
376
  - - ">="
@@ -378,7 +378,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
378
378
  version: '0'
379
379
  requirements: []
380
380
  rubygems_version: 3.4.1
381
- signing_key:
381
+ signing_key:
382
382
  specification_version: 4
383
383
  summary: Tipi - the All-in-one Web Server for Ruby Apps
384
384
  test_files: []