falcon 0.36.4 → 0.36.5

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/falcon/adapters/early_hints.rb +8 -0
  3. data/lib/falcon/adapters/input.rb +32 -11
  4. data/lib/falcon/adapters/output.rb +20 -1
  5. data/lib/falcon/adapters/rack.rb +59 -32
  6. data/lib/falcon/adapters/response.rb +23 -1
  7. data/lib/falcon/adapters/rewindable.rb +10 -3
  8. data/lib/falcon/command.rb +2 -0
  9. data/lib/falcon/command/host.rb +13 -2
  10. data/lib/falcon/command/paths.rb +4 -0
  11. data/lib/falcon/command/proxy.rb +14 -0
  12. data/lib/falcon/command/redirect.rb +12 -0
  13. data/lib/falcon/command/serve.rb +22 -15
  14. data/lib/falcon/command/supervisor.rb +15 -1
  15. data/lib/falcon/command/top.rb +16 -0
  16. data/lib/falcon/command/virtual.rb +15 -0
  17. data/lib/falcon/configuration.rb +69 -7
  18. data/lib/falcon/controller/host.rb +12 -0
  19. data/lib/falcon/controller/proxy.rb +13 -0
  20. data/lib/falcon/controller/redirect.rb +7 -0
  21. data/lib/falcon/controller/serve.rb +14 -1
  22. data/lib/falcon/controller/virtual.rb +17 -0
  23. data/lib/falcon/endpoint.rb +8 -0
  24. data/lib/falcon/{configuration/proxy.rb → environments.rb} +9 -5
  25. data/lib/falcon/environments/application.rb +68 -0
  26. data/lib/falcon/{configuration/application.rb → environments/lets_encrypt_tls.rb} +21 -20
  27. data/lib/falcon/{configuration/lets_encrypt_tls.rb → environments/proxy.rb} +13 -6
  28. data/lib/falcon/{configuration → environments}/rack.rb +14 -2
  29. data/lib/falcon/{configuration → environments}/self_signed_tls.rb +9 -1
  30. data/lib/falcon/{configuration → environments}/supervisor.rb +19 -5
  31. data/lib/falcon/{configuration → environments}/tls.rb +39 -5
  32. data/lib/falcon/extensions/openssl.rb +1 -0
  33. data/lib/falcon/middleware/proxy.rb +26 -5
  34. data/lib/falcon/middleware/redirect.rb +11 -0
  35. data/lib/falcon/{verbose.rb → middleware/verbose.rb} +34 -26
  36. data/lib/falcon/proxy_endpoint.rb +21 -0
  37. data/lib/falcon/server.rb +8 -2
  38. data/lib/falcon/service/application.rb +9 -0
  39. data/lib/falcon/service/generic.rb +18 -0
  40. data/lib/falcon/service/proxy.rb +6 -0
  41. data/lib/falcon/service/supervisor.rb +13 -1
  42. data/lib/falcon/services.rb +21 -0
  43. data/lib/falcon/tls.rb +4 -2
  44. data/lib/falcon/version.rb +1 -1
  45. data/lib/rack/handler/falcon.rb +7 -1
  46. metadata +16 -72
  47. data/.editorconfig +0 -5
  48. data/.github/FUNDING.yml +0 -3
  49. data/.github/workflows/development.yml +0 -60
  50. data/.gitignore +0 -14
  51. data/.rspec +0 -3
  52. data/Gemfile +0 -17
  53. data/README.md +0 -316
  54. data/examples/beer/config.ru +0 -57
  55. data/examples/beer/falcon.rb +0 -8
  56. data/examples/benchmark/config.ru +0 -39
  57. data/examples/benchmark/falcon.rb +0 -6
  58. data/examples/csv/config.ru +0 -31
  59. data/examples/google/falcon.rb +0 -14
  60. data/examples/hello/config.ru +0 -22
  61. data/examples/hello/falcon.rb +0 -24
  62. data/examples/hello/preload.rb +0 -7
  63. data/examples/internet/config.ru +0 -54
  64. data/examples/memory/allocations.rb +0 -39
  65. data/examples/memory/config.ru +0 -14
  66. data/examples/push/client.rb +0 -29
  67. data/examples/push/config.ru +0 -28
  68. data/examples/push/index.html +0 -14
  69. data/examples/push/script.js +0 -2
  70. data/examples/push/style.css +0 -4
  71. data/examples/redis/Gemfile +0 -9
  72. data/examples/redis/config.ru +0 -28
  73. data/examples/sequel/Gemfile +0 -4
  74. data/examples/sequel/config.ru +0 -8
  75. data/examples/sequel/data.sqlite3 +0 -0
  76. data/examples/server/standalone.rb +0 -27
  77. data/examples/sinatra/Gemfile +0 -7
  78. data/examples/sinatra/Gemfile.lock +0 -53
  79. data/examples/sinatra/config.ru +0 -16
  80. data/examples/trailers/config.ru +0 -34
  81. data/examples/trailers/falcon.rb +0 -8
  82. data/falcon.gemspec +0 -45
  83. data/gems/rack1.gemfile +0 -4
  84. data/gems/rack3.gemfile +0 -4
  85. data/logo-square.afdesign +0 -0
  86. data/logo.afdesign +0 -0
  87. data/logo.svg +0 -107
  88. data/server.rb +0 -21
  89. data/tasks/benchmark.rake +0 -103
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env -S ./bin/falcon virtual
2
- # frozen_string_literal: true
3
-
4
- load :rack, :self_signed_tls, :supervisor
5
-
6
- rack 'benchmark.local', :self_signed_tls
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env falcon --verbose serve -c
2
- # frozen_string_literal: true
3
-
4
- class MyApp
5
- def initialize(app)
6
- @app = app
7
-
8
- @words = File.readlines('/usr/share/dict/words', chomp: true).each_slice(3).to_a
9
- end
10
-
11
- def call(env)
12
- body = Async::HTTP::Body::Writable.new(queue: Async::LimitedQueue.new(8))
13
-
14
- Async do |task|
15
- @words.each do |words|
16
- Async.logger.debug("Sending #{words.inspect}")
17
- body.write(words.join(",") + "\n")
18
- task.sleep(1)
19
- end
20
- ensure
21
- body.close($!)
22
- end
23
-
24
- return [200, [], body]
25
- end
26
- end
27
-
28
- # Build the middleware stack:
29
- use MyApp
30
-
31
- run lambda {|env| [404, {}, []]}
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env falcon-host
2
- # frozen_string_literal: true
3
-
4
- load :proxy, :self_signed_tls, :supervisor
5
-
6
- supervisor
7
-
8
- proxy "google.localhost", :self_signed_tls do
9
- url 'https://www.google.com'
10
- end
11
-
12
- proxy "codeotaku.localhost", :self_signed_tls do
13
- url 'https://www.codeotaku.com'
14
- end
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env falcon --verbose serve -c
2
- # frozen_string_literal: true
3
-
4
- require 'async'
5
-
6
- class RequestLogger
7
- def initialize(app)
8
- @app = app
9
- end
10
-
11
- def call(env)
12
- logger = Async.logger.with(level: :debug)
13
-
14
- Async(logger: logger) do
15
- @app.call(env)
16
- end.wait
17
- end
18
- end
19
-
20
- # use RequestLogger
21
-
22
- run lambda {|env| [200, {'cache-control' => 'max-age=10, public'}, ["Hello World"]]}
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env falcon-host
2
- # frozen_string_literal: true
3
-
4
- load :rack, :self_signed_tls, :supervisor
5
-
6
- supervisor
7
-
8
- rack 'hello.localhost', :self_signed_tls do
9
- # scheme 'http'
10
- # protocol {Async::HTTP::Protocol::HTTP1}
11
- #
12
- # endpoint do
13
- # Async::HTTP::Endpoint.for(scheme, "localhost", port: 9292, protocol: protocol)
14
- # end
15
-
16
- append preload "preload.rb"
17
-
18
- # Process will connect to supervisor to report statistics periodically, otherwise it would be killed.
19
- # report :supervisor
20
- end
21
-
22
- # service 'jobs' do
23
- # shell ['rake', 'background:jobs:process']
24
- # end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if GC.respond_to?(:compact)
4
- Async.logger.warn(self, "Compacting the mainframe...")
5
- GC.compact
6
- Async.logger.warn(self, "Compacting done...")
7
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'async'
4
- require 'async/http/internet'
5
-
6
- # Experimental.
7
- require 'kernel/sync'
8
-
9
- class Search
10
- def initialize(app)
11
- @internet = Async::HTTP::Internet.new
12
-
13
- @app = app
14
- end
15
-
16
- # This method uses the `Async` method to create a reactor if required, and then executes the contained code without waiting for the result. So even if the search query takes a long time (e.g. 100ms), it won't hold up the request processing.
17
- def async(close: !Async::Task.current?)
18
- Async do
19
- response = @internet.get("https://google.com/search?q=async+ruby")
20
-
21
- puts response.inspect
22
- ensure
23
- response&.finish
24
- end
25
- end
26
-
27
- # This method uses the experimental `Sync` method to create a reactor if required. If the code is already running in a reactor, it runs synchronously, otherwise it's effectively the same as `Async` and a blocking operation. This allow you to write efficient non-blocking code that works in both traditional web application servers, but gains additional scalability in `Async`-aware servers like Falcon.
28
- # You can achieve a similar result by calling `Async{}.wait`, but this is less efficient as it will allocate a sub-task even thought it's not needed.
29
- def sync(close: !Async::Task.current?)
30
- Sync do
31
- response = @internet.get("https://google.com/search?q=async+ruby")
32
-
33
- puts response.inspect
34
- ensure
35
- response&.finish
36
- end
37
- end
38
-
39
- # The only point of this is to invoke one of the above two methods.
40
- def call(env)
41
- case env['PATH_INFO']
42
- when '/sync'
43
- self.sync
44
- when '/async'
45
- self.async
46
- end
47
-
48
- return @app.call(env)
49
- end
50
- end
51
-
52
- use Search
53
-
54
- run lambda{|env| [404, [], []]}
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Allocations
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def allocations
9
- counts = Hash.new{|h,k| h[k] = 0}
10
-
11
- ObjectSpace.each_object do |object|
12
- counts[object.class] += 1
13
- end
14
-
15
- return counts
16
- end
17
-
18
- def print_allocations(minimum = 100)
19
- buffer = StringIO.new
20
-
21
- total = allocations.values.sum
22
-
23
- allocations.select{|k,v| v >= minimum}.sort_by{|k,v| -v}.each do |key, value|
24
- buffer.puts "#{key}: #{value} allocations"
25
- end
26
-
27
- buffer.puts "** Total: #{total} allocations."
28
-
29
- return buffer.string
30
- end
31
-
32
- def call(env)
33
- if env["PATH_INFO"] == "/allocations"
34
- return [200, [], [print_allocations]]
35
- else
36
- return @app.call(env)
37
- end
38
- end
39
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'allocations'
4
-
5
- use Allocations
6
-
7
- run lambda{|env| [404, [], []]}
8
-
9
- # % curl --insecure https://localhost:9292/allocations
10
- # String: 32179 allocations
11
- # Array: 10228 allocations
12
- # Hash: 1299 allocations
13
- # Class: 1118 allocations
14
- # ** Total: 50162 allocations.
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'async'
5
- require 'async/http/endpoint'
6
- require 'async/http/client'
7
-
8
- Async do
9
- endpoint = Async::HTTP::Endpoint.parse("https://localhost:9292")
10
- client = Async::HTTP::Client.new(endpoint, Async::HTTP::Protocol::HTTP2::WithPush)
11
-
12
- response = client.get("/index.html")
13
-
14
- puts response.status
15
- puts response.read
16
- puts
17
-
18
- while promise = response.promises.dequeue
19
- promise.wait
20
-
21
- puts "** Promise: #{promise.request.path} **"
22
- puts promise.read
23
- puts
24
- end
25
- ensure
26
- client.close
27
- end
28
-
29
- puts "Done"
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env falcon --verbose serve --concurrency 1 --config
2
- # frozen_string_literal: true
3
-
4
- class EarlyHints
5
- def initialize(app)
6
- @app = app
7
- end
8
-
9
- def call(env)
10
- path = env['PATH_INFO']
11
- early_hints = early_hints = env['rack.early_hints']
12
-
13
- Async.logger.debug("path: #{path} #{early_hints}")
14
-
15
- if path == "/index.html" and early_hints
16
- early_hints.push("/style.css")
17
- early_hints.push("/script.js")
18
- end
19
-
20
- @app.call(env)
21
- end
22
- end
23
-
24
- use EarlyHints
25
-
26
- use Rack::Static, :urls => [""], :root => __dir__, :index => 'index.html'
27
-
28
- run lambda{|env| [404, [], ["Not Found"]]}
@@ -1,14 +0,0 @@
1
- <!doctype HTML>
2
- <html>
3
- <head>
4
- <title>Hello World</title>
5
-
6
- <link rel="stylesheet" href="/style.css" />
7
- <script type="text/javascript" src="script.js"></script>
8
- </head>
9
- <body>
10
- <h1>Early Hints</h1>
11
-
12
- <p>Check the developer tools to see if early hints worked!</p>
13
- </body>
14
- </html>
@@ -1,2 +0,0 @@
1
-
2
- console.log("Hello World")
@@ -1,4 +0,0 @@
1
-
2
- html {
3
- font-family: Helvetica;
4
- }
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # A sample Gemfile
4
- source "https://rubygems.org"
5
-
6
- gem "sinatra"
7
- gem "falcon"
8
-
9
- gem "async-redis", ">= 0.3.1"
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'sinatra/base'
4
- require 'async/redis'
5
- require 'async/clock'
6
-
7
- CLIENT = Async::Redis::Client.new(Async::Redis.local_endpoint)
8
-
9
- class MyApp < Sinatra::Base
10
- get "/" do
11
- puts "Starting BLPOP SLEEP..."
12
- duration = Async::Clock.measure do
13
- CLIENT.call "BLPOP", "SLEEP", 1
14
- end
15
- puts "Finished BLPOP SLEEP after #{duration.round(2)}s"
16
-
17
- "ok"
18
- end
19
- end
20
-
21
- use MyApp # Then, it will get to Sinatra.
22
- run lambda {|env| [404, {}, []]} # Bottom of the stack, give 404.
23
-
24
- # Start server like this:
25
- # falcon --verbose serve --threaded --count 1 --bind http://localhost:9292
26
-
27
- # Test server, e.g.:
28
- # time ab -n 64 -c 64 http://localhost:9292/
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'falcon'
4
- gem 'sequel'
@@ -1,8 +0,0 @@
1
- # config.ru
2
- require 'sequel'
3
-
4
- # Turn on single threaded mode
5
- Sequel.single_threaded = true
6
- DB = Sequel.sqlite('data.sqlite3')
7
-
8
- run(proc{|env| [200, {}, [DB[:user].get(:name)]]})
Binary file
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/http/endpoint'
5
- require 'async/websocket/adapters/rack'
6
-
7
- require 'falcon'
8
-
9
- module WebSocketApp
10
- def self.call(env)
11
- Async::WebSocket::Adapters::Rack.open(env, protocols: %w[ws]) do |connection|
12
- while (message = connection.read)
13
- pp message
14
- end
15
- end or [200, [], ["Websocket only."]]
16
- end
17
- end
18
-
19
- Async do
20
- websocket_endpoint = Async::HTTP::Endpoint.parse('http://127.0.0.1:3000')
21
-
22
- app = Falcon::Server.middleware(WebSocketApp)
23
-
24
- server = Falcon::Server.new(app, websocket_endpoint)
25
-
26
- server.run.each(&:wait)
27
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # A sample Gemfile
4
- source "https://rubygems.org"
5
-
6
- gem "sinatra"
7
- gem "falcon"
@@ -1,53 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- async (1.9.1)
5
- nio4r (~> 2.3)
6
- timers (~> 4.1)
7
- async-container (0.5.0)
8
- async (~> 1.0)
9
- async-io (~> 1.4)
10
- async-http (0.24.3)
11
- async (~> 1.6)
12
- async-io (~> 1.12)
13
- http-2 (~> 0.9.0)
14
- async-io (1.12.1)
15
- async (~> 1.3)
16
- falcon (0.15.2)
17
- async-container (~> 0.5.0)
18
- async-http (~> 0.24.0)
19
- async-io (~> 1.9)
20
- rack (>= 1.0)
21
- samovar (~> 1.3)
22
- hitimes (1.2.6)
23
- http-2 (0.9.1)
24
- mapping (1.1.1)
25
- mustermann (1.0.2)
26
- nio4r (2.3.1)
27
- rack (2.0.8)
28
- rack-protection (2.0.3)
29
- rack
30
- rainbow (2.2.2)
31
- rake
32
- rake (13.0.1)
33
- samovar (1.8.0)
34
- mapping (~> 1.0)
35
- rainbow (~> 2.0)
36
- sinatra (2.0.3)
37
- mustermann (~> 1.0)
38
- rack (~> 2.0)
39
- rack-protection (= 2.0.3)
40
- tilt (~> 2.0)
41
- tilt (2.0.8)
42
- timers (4.1.2)
43
- hitimes
44
-
45
- PLATFORMS
46
- ruby
47
-
48
- DEPENDENCIES
49
- falcon
50
- sinatra
51
-
52
- BUNDLED WITH
53
- 1.16.1