falcon 0.42.3 → 0.44.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/bake/falcon/supervisor.rb +3 -1
  4. data/changes.md +22 -0
  5. data/lib/falcon/command/host.rb +7 -50
  6. data/lib/falcon/command/paths.rb +2 -19
  7. data/lib/falcon/command/proxy.rb +21 -33
  8. data/lib/falcon/command/redirect.rb +22 -33
  9. data/lib/falcon/command/serve.rb +44 -82
  10. data/lib/falcon/command/supervisor.rb +2 -19
  11. data/lib/falcon/command/top.rb +2 -19
  12. data/lib/falcon/command/virtual.rb +16 -41
  13. data/lib/falcon/command.rb +3 -19
  14. data/lib/falcon/configuration.rb +28 -142
  15. data/lib/falcon/endpoint.rb +2 -19
  16. data/lib/falcon/environment/application.rb +60 -0
  17. data/lib/falcon/environment/lets_encrypt_tls.rb +34 -0
  18. data/lib/falcon/environment/proxy.rb +109 -0
  19. data/lib/falcon/environment/rack.rb +20 -0
  20. data/lib/falcon/environment/rackup.rb +26 -0
  21. data/lib/falcon/environment/redirect.rb +50 -0
  22. data/lib/falcon/environment/self_signed_tls.rb +45 -0
  23. data/lib/falcon/environment/server.rb +69 -0
  24. data/lib/falcon/environment/supervisor.rb +40 -0
  25. data/lib/falcon/environment/tls.rb +97 -0
  26. data/lib/falcon/environment.rb +13 -0
  27. data/lib/falcon/middleware/proxy.rb +3 -20
  28. data/lib/falcon/middleware/redirect.rb +2 -19
  29. data/lib/falcon/middleware/verbose.rb +2 -19
  30. data/lib/falcon/proxy_endpoint.rb +2 -19
  31. data/lib/falcon/railtie.rb +10 -0
  32. data/lib/falcon/server.rb +2 -19
  33. data/lib/falcon/service/server.rb +84 -0
  34. data/lib/falcon/service/supervisor.rb +5 -21
  35. data/lib/falcon/{controller → service}/virtual.rb +72 -36
  36. data/lib/falcon/tls.rb +2 -19
  37. data/lib/falcon/version.rb +3 -20
  38. data/lib/falcon.rb +5 -19
  39. data/lib/rack/handler/falcon.rb +4 -0
  40. data/lib/rackup/handler/falcon.rb +83 -0
  41. data/license.md +41 -0
  42. data/readme.md +60 -0
  43. data.tar.gz.sig +0 -0
  44. metadata +37 -117
  45. metadata.gz.sig +0 -0
  46. data/lib/.DS_Store +0 -0
  47. data/lib/falcon/controller/host.rb +0 -72
  48. data/lib/falcon/controller/proxy.rb +0 -126
  49. data/lib/falcon/controller/redirect.rb +0 -76
  50. data/lib/falcon/controller/serve.rb +0 -126
  51. data/lib/falcon/environments/application.rb +0 -72
  52. data/lib/falcon/environments/lets_encrypt_tls.rb +0 -47
  53. data/lib/falcon/environments/proxy.rb +0 -37
  54. data/lib/falcon/environments/rack.rb +0 -50
  55. data/lib/falcon/environments/self_signed_tls.rb +0 -55
  56. data/lib/falcon/environments/supervisor.rb +0 -51
  57. data/lib/falcon/environments/tls.rb +0 -103
  58. data/lib/falcon/environments.rb +0 -31
  59. data/lib/falcon/service/application.rb +0 -115
  60. data/lib/falcon/service/generic.rb +0 -78
  61. data/lib/falcon/service/proxy.rb +0 -66
  62. data/lib/falcon/services.rb +0 -99
@@ -1,26 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+ # Copyright, 2019, by Sho Ito.
22
6
 
23
- require 'build/environment'
7
+ require 'async/service'
24
8
 
25
9
  module Falcon
26
10
  # Manages environments which describes how to host a specific application.
@@ -41,177 +25,79 @@ module Falcon
41
25
  # end
42
26
  # ~~~
43
27
  #
44
- class Configuration
45
- # Initialize an empty configuration.
46
- def initialize
47
- @environments = {}
48
- end
49
-
50
- # The map of named environments.
51
- # @attribute [Hash(String, Build::Environment)]
52
- attr :environments
53
-
54
- # Enumerate all environments that have the specified key.
55
- # @parameter key [Symbol] Filter environments that don't have this key.
56
- def each(key = :authority)
57
- return to_enum(key) unless block_given?
58
-
59
- @environments.each do |name, environment|
60
- environment = environment.flatten
61
-
62
- if environment.include?(key)
63
- yield environment
64
- end
65
- end
66
- end
67
-
68
- # Add the named environment to the configuration.
69
- def add(environment)
70
- name = environment.name
71
-
72
- unless name
73
- raise ArgumentError, "Environment name is nil #{environment.inspect}"
74
- end
75
-
76
- environment = environment.flatten
77
-
78
- raise KeyError.new("#{name.inspect} is already set", key: name) if @environments.key?(name)
79
-
80
- @environments[name] = environment
81
- end
82
-
28
+ class Configuration < ::Async::Service::Configuration
83
29
  # Load the specified configuration file. See {Loader#load_file} for more details.
84
30
  def load_file(path)
85
31
  Loader.load_file(self, path)
86
32
  end
87
33
 
88
34
  # The domain specific language for loading configuration files.
89
- class Loader
90
- # Initialize the loader, attached to a specific configuration instance.
91
- # Any environments generated by the loader will be added to the configuration.
92
- # @parameter configuration [Configuration]
93
- # @parameter root [String] The file-system root path for relative path computations.
94
- def initialize(configuration, root = nil)
95
- @loaded = {}
96
- @configuration = configuration
97
- @environments = {}
98
- @root = root
99
- end
100
-
101
- # The file-system root path which is injected into the environments as required.
102
- # @attribute [String]
103
- attr :root
104
-
105
- # The attached configuration instance.
106
- # @attribute [Configuration]
107
- attr :configuration
108
-
109
- # Load the specified file into the given configuration.
110
- # @parameter configuration [Configuration]
111
- # @oaram path [String] The path to the configuration file, e.g. `falcon.rb`.
112
- def self.load_file(configuration, path)
113
- path = File.realpath(path)
114
- root = File.dirname(path)
115
-
116
- loader = self.new(configuration, root)
117
-
118
- loader.instance_eval(File.read(path), path)
119
- end
120
-
35
+ class Loader < ::Async::Service::Loader
121
36
  # Load specific features into the current configuration.
122
37
  #
123
- # Falcon provides default environments for different purposes. These are included in the gem, in the `environments/` directory. This method loads the code in those files into the current configuration.
124
- #
38
+ # @deprecated Use `require` instead.
125
39
  # @parameter features [Array(Symbol)] The features to load.
126
40
  def load(*features)
127
41
  features.each do |feature|
128
- next if @loaded.include?(feature)
129
-
130
42
  case feature
131
43
  when Symbol
132
- relative_path = File.join(__dir__, "environments", "#{feature}.rb")
133
-
134
- self.instance_eval(File.read(relative_path), relative_path)
135
-
136
- @loaded[feature] = relative_path
137
- when Module
138
- feature.load(self)
139
-
140
- @loaded[feature] = feature
44
+ require File.join(__dir__, "environment", "#{feature}.rb")
141
45
  else
142
46
  raise LoadError, "Unsure about how to load #{feature}!"
143
47
  end
144
48
  end
145
49
  end
146
50
 
147
- # Add the named environment, with zero or more parent environments, defined using the specified `block`.
148
- # @parameter name [String] The name of the environment.
149
- # @parameter parents [Array(Symbol)] The names of the parent environments to inherit.
150
- # @yields {...} The block that will generate the environment.
151
- def environment(name, *parents, &block)
152
- raise KeyError.new("#{name} is already set", key: name) if @environments.key?(name)
153
- @environments[name] = merge(name, *parents, &block)
154
- end
155
-
156
51
  # Define a host with the specified name.
157
52
  # Adds `root` and `authority` keys.
53
+ # @deprecated Use `service` and `include Falcon::Environment::Server` instead.
158
54
  # @parameter name [String] The name of the environment, usually a hostname.
159
55
  def host(name, *parents, &block)
160
- environment = merge(name, *parents, &block)
161
-
162
- environment[:root] = @root
163
- environment[:authority] = name
164
-
165
- @configuration.add(environment.flatten)
56
+ @configuration.add(
57
+ merge(*parents, name: name, root: @root, authority: name, &block)
58
+ )
166
59
  end
167
60
 
168
61
  # Define a proxy with the specified name.
169
62
  # Adds `root` and `authority` keys.
63
+ # @deprecated Use `service` and `include Falcon::Environment::Proxy` instead.
170
64
  # @parameter name [String] The name of the environment, usually a hostname.
171
65
  def proxy(name, *parents, &block)
172
- environment = merge(name, :proxy, *parents, &block)
173
-
174
- environment[:root] = @root
175
- environment[:authority] = name
176
-
177
- @configuration.add(environment.flatten)
66
+ @configuration.add(
67
+ merge(:proxy, *parents, name: name, root: @root, authority: name, &block)
68
+ )
178
69
  end
179
70
 
180
71
  # Define a rack application with the specified name.
181
72
  # Adds `root` and `authority` keys.
73
+ # @deprecated Use `service` and `include Falcon::Environment::Rack` instead.
182
74
  # @parameter name [String] The name of the environment, usually a hostname.
183
75
  def rack(name, *parents, &block)
184
- environment = merge(name, :rack, *parents, &block)
185
-
186
- environment[:root] = @root
187
- environment[:authority] = name
188
-
189
- @configuration.add(environment.flatten)
76
+ @configuration.add(
77
+ merge(:rack, *parents, name: name, root: @root, authority: name, &block)
78
+ )
190
79
  end
191
80
 
192
81
  # Define a supervisor instance
193
- # Adds `root` key.
82
+ # @deprecated Use `service` and `include Falcon::Environment::Supervisor` instead.
194
83
  def supervisor(&block)
195
84
  name = File.join(@root, "supervisor")
196
- environment = merge(name, :supervisor, &block)
197
85
 
198
- environment[:root] = @root
199
-
200
- @configuration.add(environment.flatten)
86
+ @configuration.add(
87
+ merge(:supervisor, name: name, root: @root, &block)
88
+ )
201
89
  end
202
90
 
203
91
  private
204
92
 
205
93
  # Build a new environment with the specified name and the given parents.
206
94
  # @parameter name [String]
207
- # @parameter parents [Array(Build::Environment)]
95
+ # @parameter parents [Array(Symbol)]
208
96
  # @yields {...} The block that will generate the environment.
209
- def merge(name, *parents, &block)
210
- environments = parents.map{|name| @environments.fetch(name)}
211
-
212
- parent = Build::Environment.combine(*environments)
97
+ def merge(*parents, **initial, &block)
98
+ facets = parents.map{|parent| Environment::LEGACY_ENVIRONMENTS.fetch(parent)}
213
99
 
214
- Build::Environment.new(parent, name: name, &block)
100
+ ::Async::Service::Environment.build(*facets, **initial, &block)
215
101
  end
216
102
  end
217
103
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2023, by Samuel Williams.
22
5
 
23
6
  require 'async/http/endpoint'
24
7
  require 'localhost/authority'
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+ # Copyright, 2020, by Daniel Evans.
6
+
7
+ require_relative 'server'
8
+ require_relative '../proxy_endpoint'
9
+
10
+ module Falcon
11
+ module Environment
12
+ # Provides an environment for hosting a web application that uses TLS.
13
+ module Application
14
+ include Server
15
+
16
+ # The middleware stack for the application.
17
+ # @returns [Protocol::HTTP::Middleware]
18
+ def middleware
19
+ ::Protocol::HTTP::Middleware::HelloWorld
20
+ end
21
+
22
+ # The scheme to use to communicate with the application.
23
+ # @returns [String]
24
+ def scheme
25
+ 'https'
26
+ end
27
+
28
+ # The protocol to use to communicate with the application.
29
+ #
30
+ # Typically one of {Async::HTTP::Protocol::HTTP1} or {Async::HTTP::Protocl::HTTP2}.
31
+ #
32
+ # @returns [Async::HTTP::Protocol]
33
+ def protocol
34
+ Async::HTTP::Protocol::HTTP2
35
+ end
36
+
37
+ # The IPC path to use for communication with the application.
38
+ # @returns [String]
39
+ def ipc_path
40
+ ::File.expand_path("application.ipc", root)
41
+ end
42
+
43
+ # The endpoint that will be used for communicating with the application server.
44
+ # @returns [Async::IO::Endpoint]
45
+ def endpoint
46
+ ::Falcon::ProxyEndpoint.unix(ipc_path,
47
+ protocol: protocol,
48
+ scheme: scheme,
49
+ authority: authority
50
+ )
51
+ end
52
+
53
+ # Number of instances to start.
54
+ # @returns [Integer | nil]
55
+ def count
56
+ nil
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
5
+
6
+ require_relative 'tls'
7
+ require_relative '../environment'
8
+
9
+ module Falcon
10
+ module Environment
11
+ # Provides an environment that uses "Lets Encrypt" for TLS.
12
+ module LetsEncryptTLS
13
+ # The Lets Encrypt certificate store path.
14
+ # @parameter [String]
15
+ def lets_encrypt_root
16
+ '/etc/letsencrypt/live'
17
+ end
18
+
19
+ # The public certificate path.
20
+ # @attribute [String]
21
+ def ssl_certificate_path
22
+ File.join(lets_encrypt_root, authority, "fullchain.pem")
23
+ end
24
+
25
+ # The private key path.
26
+ # @attribute [String]
27
+ def ssl_private_key_path
28
+ File.join(lets_encrypt_root, authority, "privkey.pem")
29
+ end
30
+ end
31
+
32
+ LEGACY_ENVIRONMENTS[:tls] = TLS
33
+ end
34
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+
6
+ require_relative 'server'
7
+ require_relative '../tls'
8
+ require_relative '../middleware/proxy'
9
+ require_relative '../environment'
10
+
11
+ module Falcon
12
+ module Environment
13
+ # Provides an environment for hosting a TLS-capable reverse proxy using SNI.
14
+ module Proxy
15
+ include Server
16
+
17
+ # The host that this proxy will receive connections for.
18
+ def url
19
+ "https://[::]:443"
20
+ end
21
+
22
+ # The default SSL session identifier.
23
+ def tls_session_id
24
+ "falcon"
25
+ end
26
+
27
+ # The services we will proxy to.
28
+ # @returns [Array(Async::Service::Environment)]
29
+ def environments
30
+ []
31
+ end
32
+
33
+ # The hosts we will proxy to. This is a hash of SNI authority -> evaluator.
34
+ # @returns [Hash(String, Async::Service::Environment::Evaluator)]
35
+ def hosts
36
+ hosts = {}
37
+
38
+ environments.each do |environment|
39
+ evaluator = environment.evaluator
40
+
41
+ # next unless environment.implements?(Falcon::Environment::Application)
42
+ if evaluator.key?(:authority) and evaluator.key?(:ssl_context) and evaluator.key?(:endpoint)
43
+ Console.info(self) {"Proxying #{self.url} to #{evaluator.authority} using #{evaluator.endpoint}"}
44
+ hosts[evaluator.authority] = evaluator
45
+
46
+ if RUBY_VERSION < '3.1'
47
+ # Ensure the SSL context is set up before forking - it's buggy on Ruby < 3.1:
48
+ evaluator.ssl_context
49
+ end
50
+ end
51
+ end
52
+
53
+ return hosts
54
+ end
55
+
56
+ # Look up the host context for the given hostname, and update the socket hostname if necessary.
57
+ # @parameter socket [OpenSSL::SSL::SSLSocket] The incoming connection.
58
+ # @parameter hostname [String] The negotiated hostname.
59
+ def host_context(socket, hostname)
60
+ hosts = self.hosts
61
+
62
+ if host = hosts[hostname]
63
+ Console.logger.debug(self) {"Resolving #{hostname} -> #{host}"}
64
+
65
+ socket.hostname = hostname
66
+
67
+ return host.ssl_context
68
+ else
69
+ Console.logger.warn(self, hosts: hosts.keys) {"Unable to resolve #{hostname}!"}
70
+
71
+ return nil
72
+ end
73
+ end
74
+
75
+ # Generate an SSL context which delegates to {host_context} to multiplex based on hostname.
76
+ def ssl_context
77
+ @server_context ||= OpenSSL::SSL::SSLContext.new.tap do |context|
78
+ context.servername_cb = Proc.new do |socket, hostname|
79
+ self.host_context(socket, hostname)
80
+ end
81
+
82
+ context.session_id_context = @session_id
83
+
84
+ context.ssl_version = :TLSv1_2_server
85
+
86
+ context.set_params(
87
+ ciphers: ::Falcon::TLS::SERVER_CIPHERS,
88
+ verify_mode: ::OpenSSL::SSL::VERIFY_NONE,
89
+ )
90
+
91
+ context.setup
92
+ end
93
+ end
94
+
95
+ # The endpoint the server will bind to.
96
+ def endpoint
97
+ super.with(
98
+ ssl_context: self.ssl_context,
99
+ )
100
+ end
101
+
102
+ def middleware
103
+ return Middleware::Proxy.new(Middleware::BadRequest, self.hosts)
104
+ end
105
+ end
106
+
107
+ LEGACY_ENVIRONMENTS[:proxy] = Proxy
108
+ end
109
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+
6
+ require_relative 'application'
7
+ require_relative 'rackup'
8
+ require_relative '../environment'
9
+
10
+ module Falcon
11
+ module Environment
12
+ # Provides an environment for hosting a web application that use a Rackup `config.ru` file.
13
+ module Rack
14
+ include Application
15
+ include Rackup
16
+ end
17
+
18
+ LEGACY_ENVIRONMENTS[:rack] = Rack
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require 'rack/builder'
7
+ require_relative '../server'
8
+
9
+ module Falcon
10
+ module Environment
11
+ # Provides an environment for hosting loading a Rackup `config.ru` file.
12
+ module Rackup
13
+ def rackup_path
14
+ 'config.ru'
15
+ end
16
+
17
+ def rack_app
18
+ ::Rack::Builder.parse_file(rackup_path)
19
+ end
20
+
21
+ def middleware
22
+ ::Falcon::Server.middleware(rack_app, verbose: verbose, cache: cache)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
5
+
6
+ require_relative 'server'
7
+ require_relative '../middleware/redirect'
8
+
9
+ module Falcon
10
+ module Environment
11
+ # Provides an environment for redirecting insecure web traffic to a secure endpoint.
12
+ module Redirect
13
+ include Server
14
+
15
+ def redirect_url
16
+ "https://[::]:443"
17
+ end
18
+
19
+ def redirect_endpoint
20
+ Async::HTTP::Endpoint.parse(redirect_url)
21
+ end
22
+
23
+ # The services we will redirect to.
24
+ # @returns [Array(Async::Service::Environment)]
25
+ def environments
26
+ []
27
+ end
28
+
29
+ def hosts
30
+ hosts = {}
31
+
32
+ environments.each do |environment|
33
+ evaluator = environment.evaluator
34
+
35
+ if environment.implements?(Falcon::Environment::Application)
36
+ Console.info(self) {"Redirecting #{self.url} to #{evaluator.authority}"}
37
+ hosts[evaluator.authority] = evaluator
38
+ end
39
+ end
40
+
41
+ return hosts
42
+ end
43
+
44
+ # Load the {Middleware::Redirect} application with the specified hosts.
45
+ def middleware
46
+ Middleware::Redirect.new(Middleware::NotFound, hosts, redirect_endpoint)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+
6
+ require 'localhost/authority'
7
+ require_relative 'tls'
8
+ require_relative '../environment'
9
+
10
+ module Falcon
11
+ module Environment
12
+ # Provides an environment that exposes a self-signed TLS certificate using the `localhost` gem.
13
+ module SelfSignedTLS
14
+ # The default session identifier for the session cache.
15
+ # @returns [String]
16
+ def ssl_session_id
17
+ "falcon"
18
+ end
19
+
20
+ # The SSL context to use for incoming connections.
21
+ # @returns [OpenSSL::SSL::SSLContext]
22
+ def ssl_context
23
+ contexts = Localhost::Authority.fetch(authority)
24
+
25
+ contexts.server_context.tap do |context|
26
+ context.alpn_select_cb = lambda do |protocols|
27
+ if protocols.include? "h2"
28
+ return "h2"
29
+ elsif protocols.include? "http/1.1"
30
+ return "http/1.1"
31
+ elsif protocols.include? "http/1.0"
32
+ return "http/1.0"
33
+ else
34
+ return nil
35
+ end
36
+ end
37
+
38
+ context.session_id_context = ssl_session_id
39
+ end
40
+ end
41
+ end
42
+
43
+ LEGACY_ENVIRONMENTS[:self_signed_tls] = SelfSignedTLS
44
+ end
45
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require 'async/service/generic'
7
+ require 'async/http/endpoint'
8
+
9
+ require_relative '../service/server'
10
+ require_relative '../server'
11
+
12
+ module Falcon
13
+ module Environment
14
+ # Provides an environment for hosting a web application that uses a Falcon server.
15
+ module Server
16
+ # The service class to use for the proxy.
17
+ # @returns [Class]
18
+ def service_class
19
+ Service::Server
20
+ end
21
+
22
+ # The server authority. Defaults to the server name.
23
+ # @returns [String]
24
+ def authority
25
+ self.name
26
+ end
27
+
28
+ # Options to use when creating the container.
29
+ def container_options
30
+ {restart: true}
31
+ end
32
+
33
+ # The host that this server will receive connections for.
34
+ def url
35
+ "http://[::]:9292"
36
+ end
37
+
38
+ def timeout
39
+ nil
40
+ end
41
+
42
+ # The upstream endpoint that will handle incoming requests.
43
+ # @returns [Async::HTTP::Endpoint]
44
+ def endpoint
45
+ ::Async::HTTP::Endpoint.parse(url).with(
46
+ reuse_address: true,
47
+ timeout: timeout,
48
+ )
49
+ end
50
+
51
+ def verbose
52
+ false
53
+ end
54
+
55
+ def cache
56
+ false
57
+ end
58
+
59
+ def client_endpoint
60
+ ::Async::HTTP::Endpoint.parse(url)
61
+ end
62
+
63
+ # Any scripts to preload before starting the server.
64
+ def preload
65
+ []
66
+ end
67
+ end
68
+ end
69
+ end