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
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require 'rackup/handler'
7
+
8
+ require_relative '../../falcon'
9
+
10
+ require 'kernel/sync'
11
+ require 'async/io/host_endpoint'
12
+ require 'async/io/notification'
13
+
14
+ module Rackup
15
+ module Handler
16
+ # The falcon adaptor for the `rackup` executable.
17
+ class Falcon
18
+ # The default scheme.
19
+ SCHEME = "http"
20
+
21
+ # Generate an endpoint for the given `rackup` options.
22
+ # @returns [Async::IO::Endpoint]
23
+ def self.endpoint_for(**options)
24
+ host = options[:Host] || 'localhost'
25
+ port = Integer(options[:Port] || 9292)
26
+
27
+ return Async::IO::Endpoint.tcp(host, port)
28
+ end
29
+
30
+ # Run the specified app using the given options:
31
+ # @parameter app [Object] The rack middleware.
32
+ def self.run(app, **options)
33
+ app = ::Protocol::Rack::Adapter.new(app)
34
+
35
+ Sync do |task|
36
+ endpoint = endpoint_for(**options)
37
+ server = ::Falcon::Server.new(app, endpoint, protocol: Async::HTTP::Protocol::HTTP1, scheme: SCHEME)
38
+
39
+ server_task = task.async do
40
+ server.run.each(&:wait)
41
+ end
42
+
43
+ wrapper = self.new(server, task)
44
+
45
+ yield wrapper if block_given?
46
+
47
+ server_task.wait
48
+ ensure
49
+ server_task.stop
50
+ wrapper.close
51
+ end
52
+ end
53
+
54
+ def initialize(server, task)
55
+ @server = server
56
+ @task = task
57
+
58
+ @notification = Async::IO::Notification.new
59
+
60
+ @waiter = @task.async(transient: true) do
61
+ @notification.wait
62
+
63
+ @task&.stop
64
+ @task = nil
65
+ end
66
+ end
67
+
68
+ def stop
69
+ @notification&.signal
70
+ end
71
+
72
+ def close
73
+ @notification&.close
74
+ @notification = nil
75
+
76
+ @waiter&.stop
77
+ @waiter = nil
78
+ end
79
+ end
80
+
81
+ register :falcon, Falcon
82
+ end
83
+ end
data/license.md ADDED
@@ -0,0 +1,41 @@
1
+ # MIT License
2
+
3
+ Copyright, 2017-2024, by Samuel Williams.
4
+ Copyright, 2018, by Kent Gruber.
5
+ Copyright, 2018, by Janko Marohnić.
6
+ Copyright, 2018, by Tad Thorley.
7
+ Copyright, 2018, by Mitsutaka Mimura.
8
+ Copyright, 2018, by Kyle Tam.
9
+ Copyright, 2018, by Claudiu Garba.
10
+ Copyright, 2019, by Bryan Powell.
11
+ Copyright, 2019, by Sh Lin.
12
+ Copyright, 2019, by Sho Ito.
13
+ Copyright, 2019, by Colby Swandale.
14
+ Copyright, 2020, by Daniel Evans.
15
+ Copyright, 2020, by Mikel Kew.
16
+ Copyright, 2020, by Michael Adams.
17
+ Copyright, 2020, by Tasos Latsas.
18
+ Copyright, 2021, by Olle Jonsson.
19
+ Copyright, 2023, by Nick Janetakis.
20
+ Copyright, 2024, by Peter Schrammel.
21
+ Copyright, 2024, by Santiago Bartesaghi.
22
+ Copyright, 2024, by Trevor Turk.
23
+ Copyright, 2024, by dependabot[bot].
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ of this software and associated documentation files (the "Software"), to deal
27
+ in the Software without restriction, including without limitation the rights
28
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ copies of the Software, and to permit persons to whom the Software is
30
+ furnished to do so, subject to the following conditions:
31
+
32
+ The above copyright notice and this permission notice shall be included in all
33
+ copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,60 @@
1
+ # ![Falcon](logo.svg)
2
+
3
+ Falcon is a multi-process, multi-fiber rack-compatible HTTP server built on top of [async](https://github.com/socketry/async), [async-io](https://github.com/socketry/async-io), [async-container](https://github.com/socketry/async-container) and [async-http](https://github.com/socketry/async-http). Each request is executed within a lightweight fiber and can block on up-stream requests without stalling the entire server process. Falcon supports HTTP/1 and HTTP/2 natively.
4
+
5
+ [![Development Status](https://github.com/socketry/falcon/workflows/Test/badge.svg)](https://github.com/socketry/falcon/actions?workflow=Test)
6
+
7
+ ## Motivation
8
+
9
+ Initially, when I developed [async](https://github.com/socketry/async), I saw an opportunity to implement [async-http](https://github.com/socketry/async-http): providing both client and server components. After experimenting with these ideas, I decided to build an actual web server for comparing and validating performance primarily out of interest. Falcon grew out of those experiments and permitted the ability to test existing real-world code on top of [async](https://github.com/socketry/async).
10
+
11
+ Once I had something working, I saw an opportunity to simplify my development, testing and production environments, replacing production (Nginx+Passenger) and development (Puma) with Falcon. Not only does this simplify deployment, it helps minimize environment-specific bugs.
12
+
13
+ My long term vision for Falcon is to make a web application platform which trivializes server deployment. Ideally, a web application can fully describe all its components: HTTP servers, databases, periodic jobs, background jobs, remote management, etc. Currently, it is not uncommon for all these facets to be handled independently in platform specific ways. This can make it difficult to set up new instances as well as make changes to underlying infrastructure. I hope Falcon can address some of these issues in a platform agnostic way.
14
+
15
+ As web development is something I'm passionate about, having a server like Falcon is empowering.
16
+
17
+ ## Priority Business Support
18
+
19
+ Falcon can be an important part of your business or project, both improving performance and saving money. As such, priority business support is available to make every project a success. The support agreement will give you:
20
+
21
+ - Direct support and assistance via Slack and email.
22
+ - Advance notification of bugs and security issues.
23
+ - Priority consideration of feature requests and bug reports.
24
+ - Better software by funding development and testing.
25
+
26
+ Please visit [Socketry.io](https://socketry.io) to register and subscribe.
27
+
28
+ ## Usage
29
+
30
+ Please see the [project documentation](https://socketry.github.io/falcon/) for more details.
31
+
32
+ - [Getting Started](https://socketry.github.io/falcon/guides/getting-started/index) - This guide explains how to use Falcon for Ruby web application development.
33
+
34
+ - [Rails Integration](https://socketry.github.io/falcon/guides/rails-integration/index) - This guide explains how to host Rails applications with Falcon.
35
+
36
+ - [Deployment](https://socketry.github.io/falcon/guides/deployment/index) - This guide explains how to use Falcon in production environments.
37
+
38
+ - [Extended Features](https://socketry.github.io/falcon/guides/extended-features/index) - This guide explains some of the extended features and functionality of Falcon.
39
+
40
+ - [Performance Tuning](https://socketry.github.io/falcon/guides/performance-tuning/index) - This guide explains the performance characteristics of Falcon.
41
+
42
+ - [How It Works](https://socketry.github.io/falcon/guides/how-it-works/index) - This guide gives an overview of how Falcon handles an incoming web request.
43
+
44
+ ## Contributing
45
+
46
+ We welcome contributions to this project.
47
+
48
+ 1. Fork it.
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
51
+ 4. Push to the branch (`git push origin my-new-feature`).
52
+ 5. Create new Pull Request.
53
+
54
+ ### Developer Certificate of Origin
55
+
56
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
57
+
58
+ ### Contributor Covenant
59
+
60
+ This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,27 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: falcon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.42.3
4
+ version: 0.44.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  - Janko Marohnić
9
- - dependabot[bot]
10
9
  - Bryan Powell
10
+ - Claudiu Garba
11
+ - Kyle Tam
12
+ - Mitsutaka Mimura
11
13
  - Sho Ito
12
- - claudiu
13
- - takkanm
14
- - tamkylet
14
+ - Trevor Turk
15
15
  - Colby Swandale
16
16
  - Daniel Evans
17
17
  - Kent Gruber
18
18
  - Michael Adams
19
19
  - Mikel Kew
20
+ - Nick Janetakis
20
21
  - Olle Jonsson
22
+ - Peter Schrammel
23
+ - Santiago Bartesaghi
21
24
  - Sh Lin
22
25
  - Tad Thorley
23
26
  - Tasos Latsas
24
- - deepj
27
+ - dependabot[bot]
25
28
  autorequire:
26
29
  bindir: bin
27
30
  cert_chain:
@@ -54,7 +57,7 @@ cert_chain:
54
57
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
55
58
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
56
59
  -----END CERTIFICATE-----
57
- date: 2022-08-28 00:00:00.000000000 Z
60
+ date: 2024-03-25 00:00:00.000000000 Z
58
61
  dependencies:
59
62
  - !ruby/object:Gem::Dependency
60
63
  name: async
@@ -76,14 +79,14 @@ dependencies:
76
79
  requirements:
77
80
  - - "~>"
78
81
  - !ruby/object:Gem::Version
79
- version: 0.16.0
82
+ version: '0.17'
80
83
  type: :runtime
81
84
  prerelease: false
82
85
  version_requirements: !ruby/object:Gem::Requirement
83
86
  requirements:
84
87
  - - "~>"
85
88
  - !ruby/object:Gem::Version
86
- version: 0.16.0
89
+ version: '0.17'
87
90
  - !ruby/object:Gem::Dependency
88
91
  name: async-http
89
92
  requirement: !ruby/object:Gem::Requirement
@@ -127,19 +130,19 @@ dependencies:
127
130
  - !ruby/object:Gem::Version
128
131
  version: '1.22'
129
132
  - !ruby/object:Gem::Dependency
130
- name: build-environment
133
+ name: async-service
131
134
  requirement: !ruby/object:Gem::Requirement
132
135
  requirements:
133
136
  - - "~>"
134
137
  - !ruby/object:Gem::Version
135
- version: '1.13'
138
+ version: 0.10.0
136
139
  type: :runtime
137
140
  prerelease: false
138
141
  version_requirements: !ruby/object:Gem::Requirement
139
142
  requirements:
140
143
  - - "~>"
141
144
  - !ruby/object:Gem::Version
142
- version: '1.13'
145
+ version: 0.10.0
143
146
  - !ruby/object:Gem::Dependency
144
147
  name: bundler
145
148
  requirement: !ruby/object:Gem::Requirement
@@ -224,90 +227,6 @@ dependencies:
224
227
  - - "~>"
225
228
  - !ruby/object:Gem::Version
226
229
  version: '2.1'
227
- - !ruby/object:Gem::Dependency
228
- name: async-process
229
- requirement: !ruby/object:Gem::Requirement
230
- requirements:
231
- - - "~>"
232
- - !ruby/object:Gem::Version
233
- version: '1.1'
234
- type: :development
235
- prerelease: false
236
- version_requirements: !ruby/object:Gem::Requirement
237
- requirements:
238
- - - "~>"
239
- - !ruby/object:Gem::Version
240
- version: '1.1'
241
- - !ruby/object:Gem::Dependency
242
- name: async-rspec
243
- requirement: !ruby/object:Gem::Requirement
244
- requirements:
245
- - - "~>"
246
- - !ruby/object:Gem::Version
247
- version: '1.7'
248
- type: :development
249
- prerelease: false
250
- version_requirements: !ruby/object:Gem::Requirement
251
- requirements:
252
- - - "~>"
253
- - !ruby/object:Gem::Version
254
- version: '1.7'
255
- - !ruby/object:Gem::Dependency
256
- name: async-websocket
257
- requirement: !ruby/object:Gem::Requirement
258
- requirements:
259
- - - "~>"
260
- - !ruby/object:Gem::Version
261
- version: 0.19.2
262
- type: :development
263
- prerelease: false
264
- version_requirements: !ruby/object:Gem::Requirement
265
- requirements:
266
- - - "~>"
267
- - !ruby/object:Gem::Version
268
- version: 0.19.2
269
- - !ruby/object:Gem::Dependency
270
- name: bake
271
- requirement: !ruby/object:Gem::Requirement
272
- requirements:
273
- - - ">="
274
- - !ruby/object:Gem::Version
275
- version: '0'
276
- type: :development
277
- prerelease: false
278
- version_requirements: !ruby/object:Gem::Requirement
279
- requirements:
280
- - - ">="
281
- - !ruby/object:Gem::Version
282
- version: '0'
283
- - !ruby/object:Gem::Dependency
284
- name: covered
285
- requirement: !ruby/object:Gem::Requirement
286
- requirements:
287
- - - ">="
288
- - !ruby/object:Gem::Version
289
- version: '0'
290
- type: :development
291
- prerelease: false
292
- version_requirements: !ruby/object:Gem::Requirement
293
- requirements:
294
- - - ">="
295
- - !ruby/object:Gem::Version
296
- version: '0'
297
- - !ruby/object:Gem::Dependency
298
- name: rspec
299
- requirement: !ruby/object:Gem::Requirement
300
- requirements:
301
- - - "~>"
302
- - !ruby/object:Gem::Version
303
- version: '3.6'
304
- type: :development
305
- prerelease: false
306
- version_requirements: !ruby/object:Gem::Requirement
307
- requirements:
308
- - - "~>"
309
- - !ruby/object:Gem::Version
310
- version: '3.6'
311
230
  description:
312
231
  email:
313
232
  executables:
@@ -319,7 +238,7 @@ files:
319
238
  - bake/falcon/supervisor.rb
320
239
  - bin/falcon
321
240
  - bin/falcon-host
322
- - lib/.DS_Store
241
+ - changes.md
323
242
  - lib/falcon.rb
324
243
  - lib/falcon/command.rb
325
244
  - lib/falcon/command/host.rb
@@ -331,37 +250,38 @@ files:
331
250
  - lib/falcon/command/top.rb
332
251
  - lib/falcon/command/virtual.rb
333
252
  - lib/falcon/configuration.rb
334
- - lib/falcon/controller/host.rb
335
- - lib/falcon/controller/proxy.rb
336
- - lib/falcon/controller/redirect.rb
337
- - lib/falcon/controller/serve.rb
338
- - lib/falcon/controller/virtual.rb
339
253
  - lib/falcon/endpoint.rb
340
- - lib/falcon/environments.rb
341
- - lib/falcon/environments/application.rb
342
- - lib/falcon/environments/lets_encrypt_tls.rb
343
- - lib/falcon/environments/proxy.rb
344
- - lib/falcon/environments/rack.rb
345
- - lib/falcon/environments/self_signed_tls.rb
346
- - lib/falcon/environments/supervisor.rb
347
- - lib/falcon/environments/tls.rb
254
+ - lib/falcon/environment.rb
255
+ - lib/falcon/environment/application.rb
256
+ - lib/falcon/environment/lets_encrypt_tls.rb
257
+ - lib/falcon/environment/proxy.rb
258
+ - lib/falcon/environment/rack.rb
259
+ - lib/falcon/environment/rackup.rb
260
+ - lib/falcon/environment/redirect.rb
261
+ - lib/falcon/environment/self_signed_tls.rb
262
+ - lib/falcon/environment/server.rb
263
+ - lib/falcon/environment/supervisor.rb
264
+ - lib/falcon/environment/tls.rb
348
265
  - lib/falcon/middleware/proxy.rb
349
266
  - lib/falcon/middleware/redirect.rb
350
267
  - lib/falcon/middleware/verbose.rb
351
268
  - lib/falcon/proxy_endpoint.rb
269
+ - lib/falcon/railtie.rb
352
270
  - lib/falcon/server.rb
353
- - lib/falcon/service/application.rb
354
- - lib/falcon/service/generic.rb
355
- - lib/falcon/service/proxy.rb
271
+ - lib/falcon/service/server.rb
356
272
  - lib/falcon/service/supervisor.rb
357
- - lib/falcon/services.rb
273
+ - lib/falcon/service/virtual.rb
358
274
  - lib/falcon/tls.rb
359
275
  - lib/falcon/version.rb
360
276
  - lib/rack/handler/falcon.rb
277
+ - lib/rackup/handler/falcon.rb
278
+ - license.md
279
+ - readme.md
361
280
  homepage: https://github.com/socketry/falcon
362
281
  licenses:
363
282
  - MIT
364
- metadata: {}
283
+ metadata:
284
+ documentation_uri: https://socketry.github.io/falcon/
365
285
  post_install_message:
366
286
  rdoc_options: []
367
287
  require_paths:
@@ -370,14 +290,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
370
290
  requirements:
371
291
  - - ">="
372
292
  - !ruby/object:Gem::Version
373
- version: '2.5'
293
+ version: '3.0'
374
294
  required_rubygems_version: !ruby/object:Gem::Requirement
375
295
  requirements:
376
296
  - - ">="
377
297
  - !ruby/object:Gem::Version
378
298
  version: '0'
379
299
  requirements: []
380
- rubygems_version: 3.3.7
300
+ rubygems_version: 3.5.3
381
301
  signing_key:
382
302
  specification_version: 4
383
303
  summary: A fast, asynchronous, rack-compatible web server.
metadata.gz.sig CHANGED
Binary file
data/lib/.DS_Store DELETED
Binary file
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, 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.
22
-
23
- require_relative '../services'
24
-
25
- require 'async/container/controller'
26
-
27
- module Falcon
28
- module Controller
29
- # A generic controller for serving an application.
30
- # Hosts several {Services} based on the command configuration.
31
- #
32
- # The configuration is provided by {Command::Host} and is typically loaded from a `falcon.rb` file. See {Configuration#load_file} for more details.
33
- class Host < Async::Container::Controller
34
- # Initialize the virtual controller.
35
- # @parameter command [Command::Host] The user-specified command-line options.
36
- def initialize(command, **options)
37
- @command = command
38
-
39
- @configuration = command.configuration
40
- @services = Services.new(@configuration)
41
-
42
- super(**options)
43
- end
44
-
45
- # Create the controller as specified by the command.
46
- # e.g. `Async::Container::Forked`.
47
- def create_container
48
- @command.container_class.new
49
- end
50
-
51
- # Start all specified services.
52
- def start
53
- @services.start
54
-
55
- super
56
- end
57
-
58
- # Setup all specified services into the container.
59
- # @parameter container [Async::Container::Generic]
60
- def setup(container)
61
- @services.setup(container)
62
- end
63
-
64
- # Stop all specified services.
65
- def stop(*)
66
- @services.stop
67
-
68
- super
69
- end
70
- end
71
- end
72
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
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.
22
-
23
- require 'async/container/controller'
24
-
25
- require_relative 'serve'
26
- require_relative '../middleware/proxy'
27
- require_relative '../service/proxy'
28
-
29
- require_relative '../tls'
30
-
31
- module Falcon
32
- module Controller
33
- # A controller for proxying requests.
34
- class Proxy < Serve
35
- # The default SSL session identifier.
36
- DEFAULT_SESSION_ID = "falcon"
37
-
38
- # Initialize the proxy controller.
39
- # @parameter command [Command::Proxy] The user-specified command-line options.
40
- # @parameter session_id [String] The SSL session identifier to use for the session cache.
41
- def initialize(command, session_id: DEFAULT_SESSION_ID, **options)
42
- super(command, **options)
43
-
44
- @session_id = session_id
45
- @hosts = {}
46
- end
47
-
48
- # Load the {Middleware::Proxy} application with the specified hosts.
49
- def load_app
50
- return Middleware::Proxy.new(Middleware::BadRequest, @hosts)
51
- end
52
-
53
- # The name of the controller which is used for the process title.
54
- def name
55
- "Falcon Proxy Server"
56
- end
57
-
58
- # Look up the host context for the given hostname, and update the socket hostname if necessary.
59
- # @parameter socket [OpenSSL::SSL::SSLSocket] The incoming connection.
60
- # @parameter hostname [String] The negotiated hostname.
61
- def host_context(socket, hostname)
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) {"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: 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
- @command.endpoint.with(
98
- ssl_context: self.ssl_context,
99
- reuse_address: true,
100
- )
101
- end
102
-
103
- # Builds a map of host redirections.
104
- def start
105
- configuration = @command.configuration
106
-
107
- services = Services.new(configuration)
108
-
109
- @hosts = {}
110
-
111
- services.each do |service|
112
- if service.is_a?(Service::Proxy)
113
- Console.logger.info(self) {"Proxying #{service.authority} to #{service.endpoint}"}
114
- @hosts[service.authority] = service
115
-
116
- # Pre-cache the ssl contexts:
117
- # It seems some OpenSSL objects don't like event-driven I/O.
118
- service.ssl_context
119
- end
120
- end
121
-
122
- super
123
- end
124
- end
125
- end
126
- end