itsi 0.2.26 → 0.2.27.rc1

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +7 -3
  3. data/Rakefile +24 -3
  4. data/crates/itsi_acme/Cargo.toml +2 -1
  5. data/crates/itsi_acme/src/acceptor.rs +1 -1
  6. data/crates/itsi_acme/src/acme.rs +31 -3
  7. data/crates/itsi_acme/src/http_challenge.rs +81 -0
  8. data/crates/itsi_acme/src/https_helper.rs +3 -1
  9. data/crates/itsi_acme/src/jose.rs +6 -2
  10. data/crates/itsi_acme/src/lib.rs +2 -0
  11. data/crates/itsi_acme/src/resolver.rs +27 -4
  12. data/crates/itsi_acme/src/state.rs +183 -22
  13. data/crates/itsi_scheduler/Cargo.toml +1 -1
  14. data/crates/itsi_scheduler/src/itsi_scheduler.rs +115 -64
  15. data/crates/itsi_scheduler/src/lib.rs +2 -1
  16. data/crates/itsi_server/Cargo.toml +2 -1
  17. data/crates/itsi_server/src/lib.rs +15 -0
  18. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +9 -0
  19. data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +95 -0
  20. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +22 -1
  21. data/crates/itsi_server/src/ruby_types/itsi_server.rs +100 -0
  22. data/crates/itsi_server/src/server/binds/listener.rs +9 -24
  23. data/crates/itsi_server/src/server/binds/tls.rs +372 -67
  24. data/crates/itsi_server/src/services/itsi_http_service.rs +46 -2
  25. data/gems/scheduler/Cargo.lock +4011 -527
  26. data/gems/scheduler/Gemfile +8 -2
  27. data/gems/scheduler/Gemfile.lock +107 -0
  28. data/gems/scheduler/Rakefile +33 -9
  29. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  30. data/gems/scheduler/lib/itsi/scheduler.rb +121 -6
  31. data/gems/scheduler/test/helpers/test_helper.rb +2 -0
  32. data/gems/scheduler/test/test_address_resolve.rb +8 -2
  33. data/gems/scheduler/test/test_itsi_scheduler.rb +80 -0
  34. data/gems/scheduler/test/test_timeout_after.rb +102 -0
  35. data/gems/server/Cargo.lock +30 -1
  36. data/gems/server/Gemfile +2 -0
  37. data/gems/server/Gemfile.lock +123 -0
  38. data/gems/server/Rakefile +18 -5
  39. data/gems/server/lib/itsi/http_request.rb +10 -0
  40. data/gems/server/lib/itsi/server/rack_interface.rb +45 -2
  41. data/gems/server/lib/itsi/server/version.rb +1 -1
  42. data/gems/server/lib/itsi/server.rb +24 -0
  43. data/gems/server/test/acme/local_acme_challenges.rb +190 -0
  44. data/gems/server/test/helpers/local_acme.rb +218 -0
  45. data/gems/server/test/helpers/test_helper.rb +7 -9
  46. data/gems/server/test/middleware/endpoint.rb +9 -6
  47. data/gems/server/test/rack/test_rack_server.rb +79 -0
  48. data/lib/itsi/version.rb +1 -1
  49. metadata +12 -6
@@ -2,6 +2,8 @@
2
2
 
3
3
  ENV["ITSI_LOG"] = "off"
4
4
 
5
+ Warning[:experimental] = false if Warning.respond_to?(:[]=)
6
+
5
7
  require "minitest/reporters"
6
8
  require "rackup"
7
9
  require "itsi/server"
@@ -26,12 +28,12 @@ def free_bind(protocol = "http", unix_socket: false)
26
28
  end
27
29
 
28
30
  def server(
29
- app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, cleanup: true,
31
+ app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(protocol), binds: nil, itsi_rb: nil, cleanup: true,
30
32
  &blk)
31
33
  app ||= Rack::Lint.new(app_with_lint) if app_with_lint
32
34
 
33
35
  cli_params = {}
34
- cli_params[:binds] = [bind] if bind
36
+ cli_params[:binds] = binds || [bind] if binds || bind
35
37
 
36
38
  sync = Queue.new
37
39
  cli_params[:hooks] ||= {}
@@ -40,10 +42,10 @@ def server(
40
42
  end
41
43
 
42
44
  Itsi::Server.start_in_background_thread(cli_params) do
43
- bind bind
45
+ bind bind if bind && binds.nil?
44
46
  workers 1
45
47
  threads 1
46
- log_level :warn
48
+ log_level :error
47
49
  run app if app
48
50
  instance_exec(&itsi_rb) if itsi_rb
49
51
  end
@@ -51,11 +53,6 @@ def server(
51
53
  sync.pop
52
54
  uri = URI(bind)
53
55
  RequestContext.new(uri, self).instance_exec(uri, &blk)
54
- rescue StandardError => e
55
- puts e
56
- # puts e.message
57
- # puts e.backtrace.join("\n")
58
- raise
59
56
  ensure
60
57
  Itsi::Server.stop_background_threads if cleanup
61
58
  end
@@ -157,6 +154,7 @@ class RequestContext
157
154
  @uri.host,
158
155
  @uri.port,
159
156
  use_ssl: @uri.scheme == "https",
157
+ verify_mode: (@uri.scheme == "https" ? OpenSSL::SSL::VERIFY_NONE : nil),
160
158
  **opts
161
159
  )
162
160
  end
@@ -118,14 +118,17 @@ class TestEndpoint < Minitest::Test
118
118
 
119
119
  # 8. Exceptions inside handler produce 500
120
120
  def test_internal_error_returns_500
121
- server(itsi_rb: lambda do
122
- endpoint "/boom" do |_req|
123
- raise "test crash"
121
+ response = nil
122
+ capture_subprocess_io do
123
+ server(itsi_rb: lambda do
124
+ endpoint "/boom" do |_req|
125
+ raise "test crash"
126
+ end
127
+ end) do
128
+ response = get_resp("/boom")
124
129
  end
125
- end) do
126
- res = get_resp("/boom")
127
- assert_equal "500", res.code
128
130
  end
131
+ assert_equal "500", response.code
129
132
  end
130
133
 
131
134
  # 9. Controller method dispatch via symbol
@@ -66,6 +66,85 @@ class TestRackServer < Minitest::Test
66
66
  end
67
67
  end
68
68
 
69
+ def test_partial_hijack_yields_writable_stream
70
+ stream_class = nil
71
+ stream_closed = nil
72
+ required_methods_ok = nil
73
+
74
+ server(app_with_lint: lambda do |_env|
75
+ [200, { "content-type" => "text/plain", "rack.hijack" => lambda { |stream|
76
+ stream_class = stream.class
77
+ refute stream.closed?
78
+ required_methods_ok = %i[read write << flush close close_read close_write closed?]
79
+ .all? { |method_name| stream.respond_to?(method_name) }
80
+ stream.write("Hello")
81
+ stream.write(", World!")
82
+ stream.close
83
+ stream_closed = stream.closed?
84
+ } }, []]
85
+ end) do
86
+ assert_equal "Hello, World!", get("/")
87
+ end
88
+
89
+ assert_equal Rack::Lint::Wrapper::StreamWrapper, stream_class
90
+ assert_equal true, required_methods_ok
91
+ assert_equal true, stream_closed
92
+ end
93
+
94
+ def test_partial_hijack_upgrade_supports_bidirectional_io
95
+ callback_error = Queue.new
96
+ stream_details = Queue.new
97
+
98
+ server(app: lambda do |_env|
99
+ [101, {
100
+ "connection" => "Upgrade",
101
+ "upgrade" => "test",
102
+ "rack.hijack" => lambda { |stream|
103
+ stream_details << [stream.class, stream.is_a?(IO), stream.method(:read).arity]
104
+ Thread.new do
105
+ begin
106
+ payload = stream.read(2)
107
+ stream.write("echo:#{payload}")
108
+ rescue => e
109
+ callback_error << e
110
+ ensure
111
+ stream.close rescue nil
112
+ end
113
+ end
114
+ }
115
+ }, []]
116
+ end) do |uri|
117
+ socket = TCPSocket.new(uri.host, uri.port)
118
+ socket.write(
119
+ "GET / HTTP/1.1\r\n" \
120
+ "Host: #{uri.host}:#{uri.port}\r\n" \
121
+ "Connection: Upgrade\r\n" \
122
+ "Upgrade: test\r\n" \
123
+ "\r\n"
124
+ )
125
+ socket.flush
126
+
127
+ response = +""
128
+ until response.include?("\r\n\r\n")
129
+ response << socket.readpartial(1024)
130
+ end
131
+
132
+ assert_includes response, "101"
133
+ socket.write("hi")
134
+ socket.flush
135
+ echoed = socket.readpartial(7)
136
+ assert_equal "echo:hi", echoed
137
+ ensure
138
+ socket&.close
139
+ end
140
+
141
+ raise callback_error.pop unless callback_error.empty?
142
+ stream_class, stream_is_io, read_arity = stream_details.pop
143
+ assert_equal UNIXSocket, stream_class
144
+ assert_equal true, stream_is_io
145
+ assert_operator read_arity, :!=, 0
146
+ end
147
+
69
148
  def test_enumerable_body
70
149
  server(app_with_lint: lambda do |env|
71
150
  [200, { "content-type" => "application/json" },
data/lib/itsi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Itsi
2
- VERSION = "0.2.26"
2
+ VERSION = "0.2.27.rc1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itsi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.26
4
+ version: 0.2.27.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter Coppieters
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.2.26
18
+ version: 0.2.27.rc1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.2.26
25
+ version: 0.2.27.rc1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: itsi-server
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.2.26
32
+ version: 0.2.27.rc1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.2.26
39
+ version: 0.2.27.rc1
40
40
  description: Wrapper Gem for both the Itsi server and the Itsi Fiber scheduler
41
41
  email:
42
42
  - wc@pico.net.nz
@@ -74,6 +74,7 @@ files:
74
74
  - crates/itsi_acme/src/caches/no.rs
75
75
  - crates/itsi_acme/src/caches/test.rs
76
76
  - crates/itsi_acme/src/config.rs
77
+ - crates/itsi_acme/src/http_challenge.rs
77
78
  - crates/itsi_acme/src/https_helper.rs
78
79
  - crates/itsi_acme/src/incoming.rs
79
80
  - crates/itsi_acme/src/jose.rs
@@ -768,6 +769,7 @@ files:
768
769
  - gems/scheduler/Cargo.lock
769
770
  - gems/scheduler/Cargo.toml
770
771
  - gems/scheduler/Gemfile
772
+ - gems/scheduler/Gemfile.lock
771
773
  - gems/scheduler/Rakefile
772
774
  - gems/scheduler/bin/console
773
775
  - gems/scheduler/bin/setup
@@ -787,11 +789,13 @@ files:
787
789
  - gems/scheduler/test/test_nested_fibers.rb
788
790
  - gems/scheduler/test/test_network_io.rb
789
791
  - gems/scheduler/test/test_process_wait.rb
792
+ - gems/scheduler/test/test_timeout_after.rb
790
793
  - gems/server/.gitignore
791
794
  - gems/server/.rubocop.yml
792
795
  - gems/server/Cargo.lock
793
796
  - gems/server/Cargo.toml
794
797
  - gems/server/Gemfile
798
+ - gems/server/Gemfile.lock
795
799
  - gems/server/Rakefile
796
800
  - gems/server/bin/console
797
801
  - gems/server/bin/setup
@@ -1084,6 +1088,8 @@ files:
1084
1088
  - gems/server/lib/itsi/standard_headers.rb
1085
1089
  - gems/server/lib/ruby_lsp/itsi/addon.rb
1086
1090
  - gems/server/lib/shell_completions/completions.rb
1091
+ - gems/server/test/acme/local_acme_challenges.rb
1092
+ - gems/server/test/helpers/local_acme.rb
1087
1093
  - gems/server/test/helpers/test_helper.rb
1088
1094
  - gems/server/test/middleware/allow_list.rb
1089
1095
  - gems/server/test/middleware/auth_api_key.rb
@@ -1155,7 +1161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1155
1161
  - !ruby/object:Gem::Version
1156
1162
  version: '3.2'
1157
1163
  requirements: []
1158
- rubygems_version: 4.0.3
1164
+ rubygems_version: 3.6.9
1159
1165
  specification_version: 4
1160
1166
  summary: Wrapper Gem for both the Itsi server and the Itsi Fiber scheduler
1161
1167
  test_files: []