falcon 0.37.1 → 0.39.0

Sign up to get free protection for your applications and to get access to all the features.
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.