falcon 0.37.1 → 0.39.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d83047a262d8025a52ecb7f3bf232c36f717ea646058492f93c5888c467fb6da
4
- data.tar.gz: a8bb6889126af343d5227f4994ee7d1c7498c5b8537c58a254e2fae8195592d1
3
+ metadata.gz: 5ce7e0eb1b344a280ee69a568921c091ba8aed45f8b5d1346e5b2e49ae971a14
4
+ data.tar.gz: dc90db0f936efb3ba745659a8ed0d705e6f80265ed93dcc110e0cdd5c5280548
5
5
  SHA512:
6
- metadata.gz: ec87c1b000c5a480758a265cbdd293b3baf16e02428c4c217669617462e9ac41d510b369b41609244b44248f5d86b54d164c7410312d2d962eee0df95456e4ac
7
- data.tar.gz: 4cd538e294829195e22e52828b2e1362908e3b454ec510024a5db6b9b710713346c0bce91e6653313bead8f1c6a3d6b83ab39a16df60e4dc29b6baabc48276c7
6
+ metadata.gz: 54ed9701c649a1764d030cdf3e31dca114606d53cd647b275c9b77164173406b6641fcb12c474eb57e3aa84bfe1655a53a4d844cf95f43a603065a27b437f466
7
+ data.tar.gz: 1fe32ec2dd8708014f285ef81119ce49c0d3bb0872f1a64be5e786c4c8fca365065f9e46b33ad7abb9ef76bc4d24514eb6188fc025233afa5548d9f56a4dd9e0
data/bin/falcon CHANGED
@@ -27,6 +27,6 @@ begin
27
27
  rescue Interrupt
28
28
  # Ignore.
29
29
  rescue => error
30
- Async.logger.error(Falcon::Command) {error}
30
+ Console.logger.error(Falcon::Command) {error}
31
31
  exit! 1
32
32
  end
@@ -25,7 +25,7 @@ require 'rack'
25
25
  require_relative 'input'
26
26
  require_relative 'response'
27
27
 
28
- require 'async/logger'
28
+ require 'console'
29
29
 
30
30
  module Falcon
31
31
  module Adapters
@@ -60,6 +60,10 @@ module Falcon
60
60
  RACK_IS_HIJACK = 'rack.hijack?'
61
61
  RACK_HIJACK_IO = 'rack.hijack_io'
62
62
 
63
+ # Raised back up through the middleware when the underlying connection is hijacked.
64
+ class FullHijack < StandardError
65
+ end
66
+
63
67
  # Async::HTTP specific metadata:
64
68
 
65
69
  ASYNC_HTTP_REQUEST = "async.http.request"
@@ -70,13 +74,10 @@ module Falcon
70
74
 
71
75
  # Initialize the rack adaptor middleware.
72
76
  # @parameter app [Object] The rack middleware.
73
- # @parameter logger [Console::Logger] The logger to use.
74
- def initialize(app, logger = Async.logger)
77
+ def initialize(app)
75
78
  @app = app
76
79
 
77
80
  raise ArgumentError, "App must be callable!" unless @app.respond_to?(:call)
78
-
79
- @logger = logger
80
81
  end
81
82
 
82
83
  # Unwrap raw HTTP headers into the CGI-style expected by Rack middleware.
@@ -146,7 +147,7 @@ module Falcon
146
147
 
147
148
  RACK_INPUT => Input.new(request.body),
148
149
  RACK_ERRORS => $stderr,
149
- RACK_LOGGER => Async.logger,
150
+ RACK_LOGGER => Console.logger,
150
151
 
151
152
  RACK_MULTITHREAD => true,
152
153
  RACK_MULTIPROCESS => true,
@@ -202,12 +203,12 @@ module Falcon
202
203
 
203
204
  # If there was a full hijack:
204
205
  if full_hijack
205
- return nil
206
+ raise FullHijack, "The connection was hijacked."
206
207
  else
207
208
  return Response.wrap(status, headers, body, request)
208
209
  end
209
210
  rescue => exception
210
- @logger.error(self) {exception}
211
+ Console.logger.error(self) {exception}
211
212
 
212
213
  return failure_response(exception)
213
214
  end
@@ -78,7 +78,7 @@ module Falcon
78
78
  ignored = headers.extract(IGNORE_HEADERS)
79
79
 
80
80
  unless ignored.empty?
81
- Async.logger.warn("Ignoring protocol-level headers: #{ignored.inspect}")
81
+ Console.logger.warn("Ignoring protocol-level headers: #{ignored.inspect}")
82
82
  end
83
83
 
84
84
  body = Output.wrap(status, headers, body)
@@ -92,10 +92,10 @@ module Falcon
92
92
  protocol = meta['rack.protocol']
93
93
 
94
94
  # https://tools.ietf.org/html/rfc7231#section-7.4.2
95
- headers.add('server', "falcon/#{Falcon::VERSION}")
95
+ # headers.add('server', "falcon/#{Falcon::VERSION}")
96
96
 
97
97
  # https://tools.ietf.org/html/rfc7231#section-7.1.1.2
98
- headers.add('date', Time.now.httpdate)
98
+ # headers.add('date', Time.now.httpdate)
99
99
 
100
100
  return self.new(status, headers, body, protocol)
101
101
  end
@@ -64,7 +64,7 @@ module Falcon
64
64
 
65
65
  # Prepare the environment and run the controller.
66
66
  def call
67
- Async.logger.info(self) do |buffer|
67
+ Console.logger.info(self) do |buffer|
68
68
  buffer.puts "Falcon Host v#{VERSION} taking flight!"
69
69
  buffer.puts "- Configuration: #{@paths.join(', ')}"
70
70
  buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
@@ -66,7 +66,7 @@ module Falcon
66
66
 
67
67
  # Prepare the environment and run the controller.
68
68
  def call
69
- Async.logger.info(self) do |buffer|
69
+ Console.logger.info(self) do |buffer|
70
70
  buffer.puts "Falcon Proxy v#{VERSION} taking flight!"
71
71
  buffer.puts "- Binding to: #{@options[:bind]}"
72
72
  buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
@@ -64,7 +64,7 @@ module Falcon
64
64
 
65
65
  # Prepare the environment and run the controller.
66
66
  def call
67
- Async.logger.info(self) do |buffer|
67
+ Console.logger.info(self) do |buffer|
68
68
  buffer.puts "Falcon Redirect v#{VERSION} taking flight!"
69
69
  buffer.puts "- Binding to: #{@options[:bind]}"
70
70
  buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
@@ -133,7 +133,7 @@ module Falcon
133
133
 
134
134
  # Prepare the environment and run the controller.
135
135
  def call
136
- Async.logger.info(self) do |buffer|
136
+ Console.logger.info(self) do |buffer|
137
137
  buffer.puts "Falcon v#{VERSION} taking flight! Using #{self.container_class} #{self.container_options}."
138
138
  buffer.puts "- Binding to: #{self.endpoint}"
139
139
  buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
@@ -71,12 +71,14 @@ module Falcon
71
71
 
72
72
  # Prepare the environment and run the controller.
73
73
  def call
74
- Async.logger.info(self) do |buffer|
74
+ Console.logger.info(self) do |buffer|
75
75
  buffer.puts "Falcon Virtual v#{VERSION} taking flight!"
76
76
  buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
77
77
  buffer.puts "- To reload all sites: kill -HUP #{Process.pid}"
78
78
  end
79
79
 
80
+ ENV['CONSOLE_LEVEL'] = 'debug'
81
+
80
82
  self.controller.run
81
83
  end
82
84
 
@@ -127,11 +127,20 @@ module Falcon
127
127
  features.each do |feature|
128
128
  next if @loaded.include?(feature)
129
129
 
130
- relative_path = File.join(__dir__, "environments", "#{feature}.rb")
131
-
132
- self.instance_eval(File.read(relative_path), relative_path)
133
-
134
- @loaded[feature] = relative_path
130
+ case feature
131
+ 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
141
+ else
142
+ raise LoadError, "Unsure about how to load #{feature}!"
143
+ end
135
144
  end
136
145
  end
137
146
 
@@ -60,13 +60,13 @@ module Falcon
60
60
  # @parameter hostname [String] The negotiated hostname.
61
61
  def host_context(socket, hostname)
62
62
  if host = @hosts[hostname]
63
- Async.logger.debug(self) {"Resolving #{hostname} -> #{host}"}
63
+ Console.logger.debug(self) {"Resolving #{hostname} -> #{host}"}
64
64
 
65
65
  socket.hostname = hostname
66
66
 
67
67
  return host.ssl_context
68
68
  else
69
- Async.logger.warn(self) {"Unable to resolve #{hostname}!"}
69
+ Console.logger.warn(self) {"Unable to resolve #{hostname}!"}
70
70
 
71
71
  return nil
72
72
  end
@@ -110,8 +110,12 @@ module Falcon
110
110
 
111
111
  services.each do |service|
112
112
  if service.is_a?(Service::Proxy)
113
- Async.logger.info(self) {"Proxying #{service.authority} to #{service.endpoint}"}
113
+ Console.logger.info(self) {"Proxying #{service.authority} to #{service.endpoint}"}
114
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
115
119
  end
116
120
  end
117
121
 
@@ -68,7 +68,7 @@ module Falcon
68
68
  Async::IO::SharedEndpoint.bound(@endpoint)
69
69
  end.wait
70
70
 
71
- Async.logger.info(self) { "Starting #{name} on #{@endpoint.to_url}" }
71
+ Console.logger.info(self) { "Starting #{name} on #{@endpoint.to_url}" }
72
72
 
73
73
  @debug_trap.ignore!
74
74
 
@@ -90,13 +90,13 @@ module Falcon
90
90
 
91
91
  task.async do
92
92
  if @debug_trap.install!
93
- Async.logger.info(instance) do
93
+ Console.logger.info(instance) do
94
94
  "- Per-process status: kill -USR1 #{Process.pid}"
95
95
  end
96
96
  end
97
97
 
98
98
  @debug_trap.trap do
99
- Async.logger.info(self) do |buffer|
99
+ Console.logger.info(self) do |buffer|
100
100
  task.reactor.print_hierarchy(buffer)
101
101
  end
102
102
  end
@@ -0,0 +1,29 @@
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
+ load(:application)
24
+
25
+ # Inherits directly from {application}.
26
+ #
27
+ # @scope Falcon Environments
28
+ # @name host
29
+ environment(:host, :application)
@@ -112,7 +112,7 @@ module Falcon
112
112
  def prepare_request(request, host)
113
113
  forwarded = []
114
114
 
115
- Async.logger.debug(self) do |buffer|
115
+ Console.logger.debug(self) do |buffer|
116
116
  buffer.puts "Request authority: #{request.authority}"
117
117
  buffer.puts "Host authority: #{host.authority}"
118
118
  buffer.puts "Request: #{request.method} #{request.path} #{request.version}"
@@ -158,7 +158,7 @@ module Falcon
158
158
  super
159
159
  end
160
160
  rescue
161
- Async.logger.error(self) {$!}
161
+ Console.logger.error(self) {$!}
162
162
  return Protocol::HTTP::Response[502, {'content-type' => 'text/plain'}, ["#{$!.inspect}: #{$!.backtrace.join("\n")}"]]
163
163
  end
164
164
  end
@@ -20,7 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
- require 'async/logger'
23
+ require 'console'
24
24
  require 'async/http/statistics'
25
25
 
26
26
  module Falcon
@@ -30,7 +30,7 @@ module Falcon
30
30
  # Initialize the verbose middleware.
31
31
  # @parameter app [Protocol::HTTP::Middleware] The middleware to wrap.
32
32
  # @parameter logger [Console::Logger] The logger to use.
33
- def initialize(app, logger = Async.logger)
33
+ def initialize(app, logger = Console.logger)
34
34
  super(app)
35
35
 
36
36
  @logger = logger
@@ -52,7 +52,7 @@ module Falcon
52
52
  def preload!
53
53
  if scripts = @evaluator.preload
54
54
  scripts.each do |path|
55
- Async.logger.info(self) {"Preloading #{path}..."}
55
+ Console.logger.info(self) {"Preloading #{path}..."}
56
56
  full_path = File.expand_path(path, self.root)
57
57
  load(full_path)
58
58
  end
@@ -62,7 +62,7 @@ module Falcon
62
62
  # Prepare the bound endpoint for the application instances.
63
63
  # Invoke {preload!} to load shared resources into the parent process.
64
64
  def start
65
- Async.logger.info(self) {"Binding to #{self.endpoint}..."}
65
+ Console.logger.info(self) {"Binding to #{self.endpoint}..."}
66
66
 
67
67
  @bound_endpoint = Async::Reactor.run do
68
68
  Async::IO::SharedEndpoint.bound(self.endpoint)
@@ -87,8 +87,8 @@ module Falcon
87
87
  run_options[:count] = count unless count.nil?
88
88
 
89
89
  container.run(**run_options) do |instance|
90
- Async(logger: logger) do |task|
91
- Async.logger.info(self) {"Starting application server for #{self.root}..."}
90
+ Async do |task|
91
+ Console.logger.info(self) {"Starting application server for #{self.root}..."}
92
92
 
93
93
  server = Server.new(self.middleware, @bound_endpoint, protocol: protocol, scheme: scheme)
94
94
 
@@ -58,7 +58,7 @@ module Falcon
58
58
  # The logger to use for this service.
59
59
  # @returns [Console::Logger]
60
60
  def logger
61
- return Async.logger # .with(name: name)
61
+ return Console.logger # .with(name: name)
62
62
  end
63
63
 
64
64
  # Start the service.
@@ -74,7 +74,7 @@ module Falcon
74
74
 
75
75
  # Bind the supervisor to the specified endpoint.
76
76
  def start
77
- Async.logger.info(self) {"Binding to #{self.endpoint}..."}
77
+ Console.logger.info(self) {"Binding to #{self.endpoint}..."}
78
78
 
79
79
  @bound_endpoint = Async::Reactor.run do
80
80
  Async::IO::SharedEndpoint.bound(self.endpoint)
@@ -61,7 +61,7 @@ module Falcon
61
61
  # Start all named services.
62
62
  def start
63
63
  @named.each do |name, service|
64
- Async.logger.debug(self) {"Starting #{name}..."}
64
+ Console.logger.debug(self) {"Starting #{name}..."}
65
65
  service.start
66
66
  end
67
67
  end
@@ -71,7 +71,7 @@ module Falcon
71
71
  # @parameter container [Async::Container::Generic]
72
72
  def setup(container)
73
73
  @named.each do |name, service|
74
- Async.logger.debug(self) {"Setup #{name} into #{container}..."}
74
+ Console.logger.debug(self) {"Setup #{name} into #{container}..."}
75
75
  service.setup(container)
76
76
  end
77
77
 
@@ -83,13 +83,13 @@ module Falcon
83
83
  failed = false
84
84
 
85
85
  @named.each do |name, service|
86
- Async.logger.debug(self) {"Stopping #{name}..."}
86
+ Console.logger.debug(self) {"Stopping #{name}..."}
87
87
 
88
88
  begin
89
89
  service.stop
90
90
  rescue
91
91
  failed = true
92
- Async.logger.error(self, $!)
92
+ Console.logger.error(self, $!)
93
93
  end
94
94
  end
95
95
 
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Falcon
24
- VERSION = "0.37.1"
24
+ VERSION = "0.39.0"
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: falcon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.37.1
4
+ version: 0.39.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-30 00:00:00.000000000 Z
11
+ date: 2021-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -44,28 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.54.0
47
+ version: 0.56.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.54.0
54
+ version: 0.56.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: async-http-cache
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.0
61
+ version: 0.4.0
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: 0.3.0
68
+ version: 0.4.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: async-io
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -283,6 +283,7 @@ files:
283
283
  - lib/falcon/endpoint.rb
284
284
  - lib/falcon/environments.rb
285
285
  - lib/falcon/environments/application.rb
286
+ - lib/falcon/environments/host.rb
286
287
  - lib/falcon/environments/lets_encrypt_tls.rb
287
288
  - lib/falcon/environments/proxy.rb
288
289
  - lib/falcon/environments/rack.rb
@@ -322,7 +323,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
322
323
  - !ruby/object:Gem::Version
323
324
  version: '0'
324
325
  requirements: []
325
- rubygems_version: 3.1.2
326
+ rubygems_version: 3.2.15
326
327
  signing_key:
327
328
  specification_version: 4
328
329
  summary: A fast, asynchronous, rack-compatible web server.