falcon 0.30.0 → 0.31.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +0 -1
- data/.gitignore +1 -0
- data/README.md +1 -1
- data/examples/push/client.rb +2 -2
- data/falcon.gemspec +2 -2
- data/lib/falcon/adapters/early_hints.rb +1 -1
- data/lib/falcon/adapters/input.rb +1 -3
- data/lib/falcon/adapters/output.rb +5 -5
- data/lib/falcon/adapters/rack.rb +2 -2
- data/lib/falcon/adapters/response.rb +6 -4
- data/lib/falcon/adapters/rewindable.rb +3 -3
- data/lib/falcon/command/serve.rb +1 -1
- data/lib/falcon/configuration.rb +1 -1
- data/lib/falcon/endpoint.rb +2 -2
- data/lib/falcon/hosts.rb +4 -4
- data/lib/falcon/proxy.rb +4 -3
- data/lib/falcon/redirection.rb +3 -3
- data/lib/falcon/server.rb +4 -4
- data/lib/falcon/verbose.rb +1 -1
- data/lib/falcon/version.rb +1 -1
- data/tasks/benchmark.rake +3 -3
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f779301a15b9adf72ca83712fa1128a7ac7df69b4ec190fa5aee25e44ca23c57
|
4
|
+
data.tar.gz: 3a939860b31ae73aa9627e8d62eb1721d4d2621e4d851713788cd5b09fd5d433
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa3b215cfe77d2f14fa6e6750954246daee7dc8551770a2dd1b726e5151b844f76e6c164c78e07f761191deced2ee7056723b389ce5fbc99d7b49f4878d84ee1
|
7
|
+
data.tar.gz: a4a381b1c2f959ca30d37f20b152654cb4c77c992f3395a579e22a6fe0c03a4b0a7c081ee803991e973b8bc5d98d6ab77afca7eb00f76b5a3262825d332179c3
|
data/.editorconfig
CHANGED
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -116,7 +116,7 @@ This became the default in Rails 5 so no change is necessary unless you explicit
|
|
116
116
|
|
117
117
|
### WebSockets
|
118
118
|
|
119
|
-
Falcon supports `rack.hijack` for HTTP/1
|
119
|
+
Falcon supports (partial and full) `rack.hijack` for both for HTTP/1 and HTTP/2 connections. You can thus use [async-websocket] in any controller layer to serve WebSocket connections.
|
120
120
|
|
121
121
|
[async-websocket]: https://github.com/socketry/async-websocket
|
122
122
|
|
data/examples/push/client.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'async'
|
4
|
-
require 'async/http/
|
4
|
+
require 'async/http/endpoint'
|
5
5
|
require 'async/http/client'
|
6
6
|
|
7
7
|
Async do
|
8
|
-
endpoint = Async::HTTP::
|
8
|
+
endpoint = Async::HTTP::Endpoint.parse("https://localhost:9292")
|
9
9
|
client = Async::HTTP::Client.new(endpoint, Async::HTTP::Protocol::HTTP2::WithPush)
|
10
10
|
|
11
11
|
response = client.get("/index.html")
|
data/falcon.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency "async", "~> 1.13"
|
23
23
|
spec.add_dependency "async-io", "~> 1.22"
|
24
|
-
spec.add_dependency "async-http", "~> 0.
|
24
|
+
spec.add_dependency "async-http", "~> 0.41.0"
|
25
25
|
spec.add_dependency "async-container", "~> 0.10.0"
|
26
26
|
|
27
27
|
spec.add_dependency "rack", ">= 1.0"
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_development_dependency "trenni"
|
34
34
|
spec.add_development_dependency "async-rspec", "~> 1.7"
|
35
|
-
spec.add_development_dependency "async-websocket", "~> 0.
|
35
|
+
spec.add_development_dependency "async-websocket", "~> 0.11.0"
|
36
36
|
spec.add_development_dependency "async-process", "~> 1.1"
|
37
37
|
|
38
38
|
spec.add_development_dependency "covered", "~> 0.10"
|
@@ -18,14 +18,14 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require '
|
22
|
-
require '
|
21
|
+
require 'protocol/http/body/readable'
|
22
|
+
require 'protocol/http/body/file'
|
23
23
|
|
24
24
|
module Falcon
|
25
25
|
module Adapters
|
26
26
|
# Wraps the rack response body.
|
27
27
|
# The Body must respond to each and must only yield String values. The Body itself should not be an instance of String, as this will break in Ruby 1.9. If the Body responds to close, it will be called after iteration. If the body is replaced by a middleware after action, the original body must be closed first, if it responds to close. If the Body responds to to_path, it must return a String identifying the location of a file whose contents are identical to that produced by calling each; this may be used by the server as an alternative, possibly more efficient way to transport the response. The Body commonly is an Array of Strings, the application instance itself, or a File-like object.
|
28
|
-
class Output <
|
28
|
+
class Output < ::Protocol::HTTP::Body::Readable
|
29
29
|
CONTENT_LENGTH = 'content-length'.freeze
|
30
30
|
|
31
31
|
# Wraps an array into a buffered body.
|
@@ -36,11 +36,11 @@ module Falcon
|
|
36
36
|
length = Integer(length)
|
37
37
|
end
|
38
38
|
|
39
|
-
if body.is_a?(
|
39
|
+
if body.is_a?(::Protocol::HTTP::Body::Readable)
|
40
40
|
return body
|
41
41
|
elsif status == 200 and body.respond_to?(:to_path)
|
42
42
|
# Don't mangle partial responsese (206)
|
43
|
-
return
|
43
|
+
return ::Protocol::HTTP::Body::File.open(body.to_path)
|
44
44
|
elsif body.is_a? Array
|
45
45
|
# TODO after dropping 2.3, change to #sum
|
46
46
|
length ||= body.inject(0){|sum, chunk| sum + chunk.bytesize}
|
data/lib/falcon/adapters/rack.rb
CHANGED
@@ -29,7 +29,7 @@ require 'async/logger'
|
|
29
29
|
module Falcon
|
30
30
|
module Adapters
|
31
31
|
class Rack
|
32
|
-
# CGI
|
32
|
+
# CGI keys (https://tools.ietf.org/html/rfc3875#section-4.1)
|
33
33
|
HTTP_HOST = 'HTTP_HOST'.freeze
|
34
34
|
PATH_INFO = 'PATH_INFO'.freeze
|
35
35
|
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
@@ -193,7 +193,7 @@ module Falcon
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def failure_response(exception)
|
196
|
-
|
196
|
+
Protocol::HTTP::Response.for_exception(exception)
|
197
197
|
end
|
198
198
|
end
|
199
199
|
end
|
@@ -27,7 +27,7 @@ require 'time'
|
|
27
27
|
|
28
28
|
module Falcon
|
29
29
|
module Adapters
|
30
|
-
class Response <
|
30
|
+
class Response < ::Protocol::HTTP::Response
|
31
31
|
IGNORE_HEADERS = Proxy::HOP_HEADERS
|
32
32
|
|
33
33
|
# Append a list of newline encoded headers.
|
@@ -65,17 +65,19 @@ module Falcon
|
|
65
65
|
body = Output.wrap(status, headers, body)
|
66
66
|
end
|
67
67
|
|
68
|
+
protocol = meta['rack.protocol']
|
69
|
+
|
68
70
|
# https://tools.ietf.org/html/rfc7231#section-7.4.2
|
69
71
|
# headers.add('server', "falcon/#{Falcon::VERSION}")
|
70
72
|
|
71
73
|
# https://tools.ietf.org/html/rfc7231#section-7.1.1.2
|
72
74
|
# headers.add('date', Time.now.httpdate)
|
73
75
|
|
74
|
-
return self.new(status, headers, body)
|
76
|
+
return self.new(status, headers, body, protocol)
|
75
77
|
end
|
76
78
|
|
77
|
-
def initialize(status, headers, body)
|
78
|
-
super(nil, status, nil, headers, body)
|
79
|
+
def initialize(status, headers, body, protocol = nil)
|
80
|
+
super(nil, status, nil, headers, body, protocol)
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|
@@ -18,12 +18,12 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require '
|
21
|
+
require 'protocol/http/body/rewindable'
|
22
22
|
|
23
23
|
module Falcon
|
24
24
|
module Adapters
|
25
25
|
# Content type driven input buffering.
|
26
|
-
class Rewindable <
|
26
|
+
class Rewindable < ::Protocol::HTTP::Middleware
|
27
27
|
BUFFERED_MEDIA_TYPES = %r{
|
28
28
|
application/x-www-form-urlencoded|
|
29
29
|
multipart/form-data|
|
@@ -52,7 +52,7 @@ module Falcon
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Wrap the request body in a rewindable buffer.
|
55
|
-
# @return [
|
55
|
+
# @return [Protocol::HTTP::Response] the response.
|
56
56
|
def call(request)
|
57
57
|
if body = request.body and needs_rewind?(request)
|
58
58
|
request.body = Async::HTTP::Body::Rewindable.new(body)
|
data/lib/falcon/command/serve.rb
CHANGED
data/lib/falcon/configuration.rb
CHANGED
data/lib/falcon/endpoint.rb
CHANGED
@@ -18,11 +18,11 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require 'async/http/
|
21
|
+
require 'async/http/endpoint'
|
22
22
|
require 'localhost/authority'
|
23
23
|
|
24
24
|
module Falcon
|
25
|
-
class Endpoint < Async::HTTP::
|
25
|
+
class Endpoint < Async::HTTP::Endpoint
|
26
26
|
def ssl_context
|
27
27
|
@options[:ssl_context] || build_ssl_context
|
28
28
|
end
|
data/lib/falcon/hosts.rb
CHANGED
@@ -25,7 +25,7 @@ require_relative 'redirection'
|
|
25
25
|
|
26
26
|
require 'async/container'
|
27
27
|
require 'async/container/controller'
|
28
|
-
require 'async/http/
|
28
|
+
require 'async/http/endpoint'
|
29
29
|
|
30
30
|
module Falcon
|
31
31
|
class Host
|
@@ -111,7 +111,7 @@ module Falcon
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def endpoint
|
114
|
-
@server_endpoint ||= Async::HTTP::
|
114
|
+
@server_endpoint ||= Async::HTTP::Endpoint.parse(
|
115
115
|
'https://[::]',
|
116
116
|
ssl_context: self.ssl_context,
|
117
117
|
reuse_address: true
|
@@ -163,8 +163,8 @@ module Falcon
|
|
163
163
|
host.run(container)
|
164
164
|
end
|
165
165
|
|
166
|
-
secure_endpoint = Async::HTTP::
|
167
|
-
insecure_endpoint = Async::HTTP::
|
166
|
+
secure_endpoint = Async::HTTP::Endpoint.parse(options[:bind_secure], ssl_context: self.ssl_context)
|
167
|
+
insecure_endpoint = Async::HTTP::Endpoint.parse(options[:bind_insecure])
|
168
168
|
|
169
169
|
container.run(count: 1, name: "Falcon Proxy") do |task, instance|
|
170
170
|
proxy = self.proxy
|
data/lib/falcon/proxy.rb
CHANGED
@@ -20,18 +20,19 @@
|
|
20
20
|
|
21
21
|
require 'async/http/client'
|
22
22
|
require 'protocol/http/headers'
|
23
|
+
require 'protocol/http/middleware'
|
23
24
|
|
24
25
|
module Falcon
|
25
26
|
module BadRequest
|
26
27
|
def self.call(request)
|
27
|
-
return
|
28
|
+
return Protocol::HTTP::Response[400, {}, []]
|
28
29
|
end
|
29
30
|
|
30
31
|
def self.close
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
class Proxy <
|
35
|
+
class Proxy < Protocol::HTTP::Middleware
|
35
36
|
FORWARDED = 'forwarded'.freeze
|
36
37
|
X_FORWARDED_FOR = 'x-forwarded-for'.freeze
|
37
38
|
X_FORWARDED_PROTO = 'x-forwarded-proto'.freeze
|
@@ -133,7 +134,7 @@ module Falcon
|
|
133
134
|
end
|
134
135
|
rescue
|
135
136
|
Async.logger.error(self) {$!}
|
136
|
-
return
|
137
|
+
return Protocol::HTTP::Response[502, {'content-type' => 'text/plain'}, ["#{$!.inspect}: #{$!.backtrace.join("\n")}"]]
|
137
138
|
end
|
138
139
|
end
|
139
140
|
end
|
data/lib/falcon/redirection.rb
CHANGED
@@ -23,14 +23,14 @@ require 'async/http/client'
|
|
23
23
|
module Falcon
|
24
24
|
module NotFound
|
25
25
|
def self.call(request)
|
26
|
-
return
|
26
|
+
return Protocol::HTTP::Response[404, {}, []]
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.close
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
class Redirection <
|
33
|
+
class Redirection < Protocol::HTTP::Middleware
|
34
34
|
def initialize(app, hosts, endpoint)
|
35
35
|
super(app)
|
36
36
|
|
@@ -53,7 +53,7 @@ module Falcon
|
|
53
53
|
location = "#{@endpoint.scheme}://#{host.authority}:#{@endpoint.port}#{request.path}"
|
54
54
|
end
|
55
55
|
|
56
|
-
return
|
56
|
+
return Protocol::HTTP::Response[301, [['location', location]], []]
|
57
57
|
else
|
58
58
|
super
|
59
59
|
end
|
data/lib/falcon/server.rb
CHANGED
@@ -19,9 +19,9 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'async/http/server'
|
22
|
-
require 'async/http/middleware/builder'
|
23
22
|
|
24
|
-
require '
|
23
|
+
require 'protocol/http/middleware/builder'
|
24
|
+
require 'protocol/http/content_encoding'
|
25
25
|
|
26
26
|
require_relative 'verbose'
|
27
27
|
require_relative 'adapters/rewindable'
|
@@ -30,12 +30,12 @@ require_relative 'adapters/rack'
|
|
30
30
|
module Falcon
|
31
31
|
class Server < Async::HTTP::Server
|
32
32
|
def self.middleware(rack_app, verbose: false)
|
33
|
-
|
33
|
+
::Protocol::HTTP::Middleware.build do
|
34
34
|
if verbose
|
35
35
|
use Verbose
|
36
36
|
end
|
37
37
|
|
38
|
-
use
|
38
|
+
use ::Protocol::HTTP::ContentEncoding
|
39
39
|
use Adapters::Rewindable
|
40
40
|
use Adapters::Rack
|
41
41
|
|
data/lib/falcon/verbose.rb
CHANGED
data/lib/falcon/version.rb
CHANGED
data/tasks/benchmark.rake
CHANGED
@@ -22,7 +22,7 @@ namespace :benchmark do
|
|
22
22
|
require 'async/process'
|
23
23
|
require 'async/clock'
|
24
24
|
require 'async/io/stream'
|
25
|
-
require 'async/http/
|
25
|
+
require 'async/http/endpoint'
|
26
26
|
|
27
27
|
host = "http://127.0.0.1:9292"
|
28
28
|
|
@@ -40,7 +40,7 @@ namespace :benchmark do
|
|
40
40
|
|
41
41
|
Async.logger.info!
|
42
42
|
|
43
|
-
endpoint = Async::HTTP::
|
43
|
+
endpoint = Async::HTTP::Endpoint.parse(host)
|
44
44
|
|
45
45
|
servers.each do |command|
|
46
46
|
::Async::Reactor.run do |task|
|
@@ -62,7 +62,7 @@ namespace :benchmark do
|
|
62
62
|
|
63
63
|
socket = endpoint.connect
|
64
64
|
|
65
|
-
request =
|
65
|
+
request = Protocol::HTTP::Request.new("http", "localhost", "GET", @request_path)
|
66
66
|
stream = Async::IO::Stream.new(socket)
|
67
67
|
protocol = Async::HTTP::Protocol::HTTP1.client(stream)
|
68
68
|
|
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.
|
4
|
+
version: 0.31.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: 2019-05-
|
11
|
+
date: 2019-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.41.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
|
+
version: 0.41.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: async-container
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,14 +156,14 @@ dependencies:
|
|
156
156
|
requirements:
|
157
157
|
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0.
|
159
|
+
version: 0.11.0
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: 0.
|
166
|
+
version: 0.11.0
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: async-process
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -307,7 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
307
307
|
- !ruby/object:Gem::Version
|
308
308
|
version: '0'
|
309
309
|
requirements: []
|
310
|
-
rubygems_version: 3.0.
|
310
|
+
rubygems_version: 3.0.2
|
311
311
|
signing_key:
|
312
312
|
specification_version: 4
|
313
313
|
summary: A fast, asynchronous, rack-compatible web server.
|