falcon 0.22.3 → 0.23.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: 73ad61202855a3d1a3e2137b03a7aab80a77537f86b381e9c9194f98f1a834d0
4
- data.tar.gz: ee94ebd2cacdaeea91eab74dde099c82170069b29a25423a6879120287e40299
3
+ metadata.gz: e0e70db57599ceb24ef8ba959ccf4e9d7c43c774e5bafec0e08956d98362dc31
4
+ data.tar.gz: 742ea2d7f69b142c9e05cc4f9f2dca3d372c3b41f0b3e4d0733923b7e50853e8
5
5
  SHA512:
6
- metadata.gz: f51b62cd4c1b46fbeafe76347e1050e64a9a6885a39a13e21080cc412a776335d930c42a4f13a176aa92d912f5e48e1fefd8b22321bb974374be1b90337e63c2
7
- data.tar.gz: 18989ca95db8bf6f384d9c60bb9cd359302ba30b7c15c0e2f0a56480521993512ba268a8152cd14fb7d17e4f31ddfd39f502babdc1d1c0ffb495d50be39ec890
6
+ metadata.gz: f140e5df2529863dc8ad27cdd16cc6fa7d24e13db1d95f545e09b4e49255762b44cf5f497402be4461570277d6a7d76afda7d9291a397aeae99177743b74f8e7
7
+ data.tar.gz: e951345f66cfaad7e3e3d82e818cc7079f4156b60a03f1e1ee717ebffab8ac8c2585c317061836fd90346cef0d5103510e5a091209750446a6d061c5468fc799
data/.travis.yml CHANGED
@@ -27,11 +27,9 @@ matrix:
27
27
  - rvm: jruby-head
28
28
  env: JRUBY_OPTS="--debug -X+O"
29
29
  - rvm: ruby-head
30
- - rvm: rbx-3
31
30
  allow_failures:
32
31
  - rvm: truffleruby
33
32
  - rvm: ruby-head
34
33
  - rvm: jruby-head
35
34
  - rvm: truffleruby
36
- - rvm: rbx-3
37
35
  - gemfile: gems/rack3.gemfile
data/falcon.gemspec CHANGED
@@ -16,11 +16,11 @@ Gem::Specification.new do |spec|
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.require_paths = ["lib"]
18
18
 
19
- spec.add_dependency("http-protocol", "~> 0.12")
19
+ spec.add_dependency("http-protocol", "~> 0.15")
20
20
 
21
21
  spec.add_dependency("async", "~> 1.13")
22
22
  spec.add_dependency("async-io", "~> 1.18")
23
- spec.add_dependency("async-http", "~> 0.37.2")
23
+ spec.add_dependency("async-http", "~> 0.38.0")
24
24
  spec.add_dependency("async-container", "~> 0.9.0")
25
25
 
26
26
  spec.add_dependency("rack", ">= 1.0")
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
 
34
34
  spec.add_development_dependency "async-process", "~> 1.1"
35
35
 
36
- spec.add_development_dependency "covered"
36
+ spec.add_development_dependency "covered", "~> 0.10"
37
37
  spec.add_development_dependency "bundler"
38
38
  spec.add_development_dependency "rspec", "~> 3.6"
39
39
  spec.add_development_dependency "rake"
@@ -0,0 +1,59 @@
1
+ # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'async/http/middleware'
22
+
23
+ module Falcon
24
+ module Adapters
25
+ # Interprets link headers to implement server push.
26
+ # https://tools.ietf.org/html/rfc8288
27
+ class Push < Async::HTTP::Middleware
28
+ PRELOAD = /<(?<path>.*?)>;.*?rel=preload/
29
+
30
+ def self.early_hints(headers)
31
+ headers.each do |key, value|
32
+ if key.casecmp("link").zero? and match = PRELOAD.match(value)
33
+ yield match[:path]
34
+ else
35
+ Async.logger.warn(request) {"Unsure how to handle early hints header: #{key}"}
36
+ end
37
+ end
38
+ end
39
+
40
+ def call(request)
41
+ response = super
42
+
43
+ Async.logger.debug(self) {response}
44
+
45
+ if request.push?
46
+ Async.logger.debug(self) {response.headers['link']}
47
+
48
+ response.headers['link']&.each do |link|
49
+ if match = link.match(PRELOAD)
50
+ request.push(match[:path])
51
+ end
52
+ end
53
+ end
54
+
55
+ return response
56
+ end
57
+ end
58
+ end
59
+ end
@@ -55,6 +55,9 @@ module Falcon
55
55
  RACK_HIJACK = 'rack.hijack'.freeze
56
56
  RACK_IS_HIJACK = 'rack.hijack?'.freeze
57
57
  RACK_HIJACK_IO = 'rack.hijack_io'.freeze
58
+ RACK_EARLY_HINTS = "rack.early_hints".freeze
59
+
60
+ ASYNC_HTTP_REQUEST = "async.http.request".freeze
58
61
 
59
62
  # Header constants
60
63
  HTTP_X_FORWARDED_PROTO = 'HTTP_X_FORWARDED_PROTO'.freeze
@@ -120,6 +123,8 @@ module Falcon
120
123
  env = {
121
124
  RACK_VERSION => [2, 0, 0],
122
125
 
126
+ ASYNC_HTTP_REQUEST => request,
127
+
123
128
  RACK_INPUT => Input.new(request.body),
124
129
  RACK_ERRORS => $stderr,
125
130
  RACK_LOGGER => Async.logger,
@@ -155,6 +160,14 @@ module Falcon
155
160
 
156
161
  self.unwrap_request(request, env)
157
162
 
163
+ if request.push?
164
+ env[RACK_EARLY_HINTS] = lambda do |headers|
165
+ Falcon::Adapters::Push.early_hints(headers) do |path|
166
+ request.push(path)
167
+ end
168
+ end
169
+ end
170
+
158
171
  if request.hijack?
159
172
  env[RACK_IS_HIJACK] = true
160
173
 
data/lib/falcon/server.rb CHANGED
@@ -26,6 +26,7 @@ require 'async/http/content_encoding'
26
26
  require_relative 'verbose'
27
27
  require_relative 'adapters/rewindable'
28
28
  require_relative 'adapters/rack'
29
+ require_relative 'adapters/push'
29
30
 
30
31
  module Falcon
31
32
  class Server < Async::HTTP::Server
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Falcon
22
- VERSION = "0.22.3"
22
+ VERSION = "0.23.0"
23
23
  end
data/tasks/benchmark.rake CHANGED
@@ -1,6 +1,21 @@
1
1
 
2
2
  namespace :benchmark do
3
- task :compare do
3
+ task :hello do
4
+ @config_path = File.expand_path("../examples/hello/config.ru", __dir__)
5
+ @request_path = "/"
6
+ end
7
+
8
+ task :small do
9
+ @config_path = File.expand_path("../examples/benchmark/config.ru", __dir__)
10
+ @request_path = "/small"
11
+ end
12
+
13
+ task :big do
14
+ @config_path ||= File.expand_path("../examples/benchmark/config.ru", __dir__)
15
+ @request_path ||= "/big"
16
+ end
17
+
18
+ task :compare => :big do
4
19
  require 'etc'
5
20
 
6
21
  require 'async/reactor'
@@ -10,8 +25,7 @@ namespace :benchmark do
10
25
  require 'async/http/url_endpoint'
11
26
 
12
27
  host = "http://127.0.0.1:9292"
13
- config_path = File.expand_path("../examples/benchmark/config.ru", __dir__)
14
-
28
+
15
29
  threads = Etc.nprocessors
16
30
 
17
31
  perf = ["perf", "record", "-F", "max", "-a", "--"]
@@ -20,7 +34,8 @@ namespace :benchmark do
20
34
  # ["puma", "--bind", host.gsub("http", "tcp")],
21
35
  ["puma", "--workers", threads.to_s, "--bind", host.gsub("http", "tcp")],
22
36
  # ["rbspy", "record", "--", "falcon", "serve", "--threaded", "--bind", host, "--config"]
23
- ["falcon", "serve", "--bind", host, "--config"]
37
+ ["falcon", "serve", "--bind", host, "--config"],
38
+ # ["falcon", "serve", "--reuse-port", "--bind", host, "--config"],
24
39
  ]
25
40
 
26
41
  Async.logger.info!
@@ -37,7 +52,7 @@ namespace :benchmark do
37
52
 
38
53
  server_task = task.async do
39
54
  $stderr.puts "Starting #{command.first}"
40
- server_status = Async::Process.spawn(*command, config_path)
55
+ server_status = Async::Process.spawn(*command, @config_path)
41
56
  end
42
57
 
43
58
  begin
@@ -47,7 +62,7 @@ namespace :benchmark do
47
62
 
48
63
  socket = endpoint.connect
49
64
 
50
- request = Async::HTTP::Request.new("http", "localhost", "GET", "/big")
65
+ request = Async::HTTP::Request.new("http", "localhost", "GET", @request_path)
51
66
  stream = Async::IO::Stream.new(socket)
52
67
  protocol = Async::HTTP::Protocol::HTTP1.client(stream)
53
68
 
@@ -76,7 +91,7 @@ namespace :benchmark do
76
91
 
77
92
  # Async::Process.spawn("ab", "-n", "2000", "#{host}/small")
78
93
 
79
- Async::Process.spawn("wrk", "-c", c.to_s, "-t", (n+1).to_s, "-d", "2", "#{host}/big")
94
+ Async::Process.spawn("wrk", "-c", c.to_s, "-t", (n+1).to_s, "-d", "2", "#{host}#{@request_path}")
80
95
  end
81
96
  ensure
82
97
  server_task.stop
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.22.3
4
+ version: 0.23.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-02-08 00:00:00.000000000 Z
11
+ date: 2019-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-protocol
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.12'
19
+ version: '0.15'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.12'
26
+ version: '0.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: async
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.37.2
61
+ version: 0.38.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.37.2
68
+ version: 0.38.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: async-container
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -168,16 +168,16 @@ dependencies:
168
168
  name: covered
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - ">="
171
+ - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '0'
173
+ version: '0.10'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ">="
178
+ - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '0'
180
+ version: '0.10'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: bundler
183
183
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +250,7 @@ files:
250
250
  - lib/falcon.rb
251
251
  - lib/falcon/adapters/input.rb
252
252
  - lib/falcon/adapters/output.rb
253
+ - lib/falcon/adapters/push.rb
253
254
  - lib/falcon/adapters/rack.rb
254
255
  - lib/falcon/adapters/response.rb
255
256
  - lib/falcon/adapters/rewindable.rb