rack-easy_brotli 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 90c6a421a62be6d4257439c1f4c3b551bbd130347746aa169a32057cb0acb77c
4
+ data.tar.gz: 9d07efecfaab4ea4a1e451888d21cc711a0885dff2b69ef2ffc4ef63b6f26739
5
+ SHA512:
6
+ metadata.gz: adb6aebce3c4c444b6320104b5b1212cf437ae8c32cecd88a3cb75f409702f10c3d295cdb18a16c6382f71b713cc5e70a959320ea3fced996697299822b07e6e
7
+ data.tar.gz: a924c24565f9ce5dea893277147023622002172c10015abaf61ca6a945117ec573ac5a6d51d8dba17b21bb609e7ea0b95c783757657bb1b8a60f58334a4e6a18
data/COPYING ADDED
@@ -0,0 +1,19 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2008 The Committers
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to
6
+ deal in the Software without restriction, including without limitation the
7
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
+ sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Rack::Brotli [![Gem Version](https://badge.fury.io/rb/rack-brotli.svg)](https://badge.fury.io/rb/rack-brotli) [![Build Status](https://travis-ci.org/marcotc/rack-brotli.svg?branch=master)](https://travis-ci.org/marcotc/rack-brotli)
2
+
3
+ `Rack::Brotli` compresses `Rack` responses using [Google's Brotli](https://github.com/google/brotli) compression algorithm.
4
+
5
+ Brotli generally compresses better than `gzip` for the same CPU cost and is supported by [Chrome, Firefox, IE and Opera](http://caniuse.com/#feat=brotli).
6
+
7
+ ### Use
8
+
9
+ Install gem:
10
+
11
+ gem install rack-easy_brotli
12
+
13
+ Requiring `'rack/brotli'` will autoload `Rack::Brotli` module. The following example shows what a simple rackup
14
+ (`config.ru`) file might look like:
15
+
16
+ ```ruby
17
+ require 'rack'
18
+ require 'rack/brotli'
19
+
20
+ use Rack::Brotli
21
+
22
+ run theapp
23
+ ```
24
+
25
+ bundler
26
+ ```ruby
27
+ gem 'rack-easy_brotli'
28
+ ```
29
+
30
+ ### Testing
31
+
32
+ To run the entire test suite, run
33
+
34
+ rake test
35
+
36
+ ### Links
37
+
38
+ * rack-brotli on GitHub:: <http://github.com/marcotc/rack-brotli>
39
+ * Rack:: <http://rack.rubyforge.org/>
40
+ * Rack On GitHub:: <http://github.com/rack/rack>
@@ -0,0 +1,16 @@
1
+ require_relative 'brotli/instrument'
2
+ require_relative 'brotli/deflater'
3
+ require_relative 'brotli/version'
4
+ require_relative 'brotli/railtie' if defined?(::Rails)
5
+
6
+ module Rack
7
+ module Brotli
8
+ def self.release
9
+ Version.to_s
10
+ end
11
+
12
+ def self.new(app, options={})
13
+ Rack::Brotli::Deflater.new(app, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "brotli"
4
+ require 'rack/utils'
5
+
6
+ module Rack::Brotli
7
+ # This middleware enables compression of http responses.
8
+ #
9
+ # Currently supported compression algorithms:
10
+ #
11
+ # * br
12
+ #
13
+ # The middleware automatically detects when compression is supported
14
+ # and allowed. For example no transformation is made when a cache
15
+ # directive of 'no-transform' is present, or when the response status
16
+ # code is one that doesn't allow an entity body.
17
+ class Deflater
18
+ ##
19
+ # Creates Rack::Brotli middleware.
20
+ #
21
+ # [app] rack app instance
22
+ # [options] hash of deflater options, i.e.
23
+ # 'if' - a lambda enabling / disabling deflation based on returned boolean value
24
+ # e.g use Rack::Brotli, :if => lambda { |env, status, headers, body| body.map(&:bytesize).reduce(0, :+) > 512 }
25
+ # 'include' - a list of content types that should be compressed
26
+ # 'deflater' - Brotli compression options
27
+ def initialize(app, options = {})
28
+ @app = app
29
+
30
+ @condition = options[:if]
31
+ @compressible_types = options[:include]
32
+ if defined?(ActiveSupport::Notifications)
33
+ @notifier = ActiveSupport::Notifications
34
+ else
35
+ @notifier = Rack::Brotli::Instrument
36
+ end
37
+ @deflater_options = { quality: 5 }
38
+ @deflater_options.merge!(options[:deflater]) if options[:deflater]
39
+ @deflater_options
40
+ end
41
+
42
+ def call(env)
43
+ status, headers, body = @app.call(env)
44
+ headers = header_hash(headers)
45
+
46
+ unless should_deflate?(env, status, headers, body)
47
+ return [status, headers, body]
48
+ end
49
+
50
+ request = Rack::Request.new(env)
51
+
52
+ encoding = Rack::Utils.select_best_encoding(%w(br),
53
+ request.accept_encoding)
54
+
55
+ return [status, headers, body] unless encoding
56
+
57
+ instrument(request) do
58
+ # Set the Vary HTTP header.
59
+ vary = headers["Vary"].to_s.split(",").map(&:strip)
60
+ unless vary.include?("*") || vary.include?("Accept-Encoding")
61
+ headers["Vary"] = vary.push("Accept-Encoding").join(",")
62
+ end
63
+
64
+ case encoding
65
+ when "br"
66
+ headers['Content-Encoding'] = "br"
67
+ headers.delete('Content-Length')
68
+ [status, headers, BrotliStream.new(body, @deflater_options)]
69
+ when nil
70
+ message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found."
71
+ bp = Rack::BodyProxy.new([message]) { body.close if body.respond_to?(:close) }
72
+ [406, {'Content-Type' => "text/plain", 'Content-Length' => message.length.to_s}, bp]
73
+ end
74
+ end
75
+ end
76
+
77
+ class BrotliStream
78
+ include Rack::Utils
79
+
80
+ def initialize(body, options)
81
+ @body = body
82
+ @options = options
83
+ end
84
+
85
+ def each(&block)
86
+ @writer = block
87
+ buffer = +''
88
+ @body.each { |part|
89
+ buffer << part
90
+ }
91
+ yield ::Brotli.deflate(buffer, @options)
92
+ ensure
93
+ @writer = nil
94
+ end
95
+
96
+ def close
97
+ @body.close if @body.respond_to?(:close)
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ # instrument for performance metrics
104
+ def instrument(request, &block)
105
+ @notifier.instrument("rack.brotli", request: request) do
106
+ yield
107
+ end
108
+ end
109
+
110
+ def header_hash(headers)
111
+ if headers.is_a?(Rack::Utils::HeaderHash)
112
+ header
113
+ else
114
+ Rack::Utils::HeaderHash.new(headers) # rack < 2.2
115
+ end
116
+ end
117
+
118
+ def should_deflate?(env, status, headers, body)
119
+ # Skip compressing empty entity body responses and responses with
120
+ # no-transform set.
121
+ if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) ||
122
+ /\bno-transform\b/.match?(headers['Cache-Control'].to_s) ||
123
+ headers['Content-Encoding']&.!~(/\bidentity\b/)
124
+ return false
125
+ end
126
+
127
+ # Skip if @compressible_types are given and does not include request's content type
128
+ return false if @compressible_types && !(headers.has_key?('Content-Type') && @compressible_types.include?(headers['Content-Type'][/[^;]*/]))
129
+
130
+ # Skip if @condition lambda is given and evaluates to false
131
+ return false if @condition && !@condition.call(env, status, headers, body)
132
+
133
+ # No point in compressing empty body, also handles usage with
134
+ # Rack::Sendfile.
135
+ return false if headers['Content-Length'] == '0'
136
+
137
+ true
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,11 @@
1
+ # dummy implementation for non-rails environments
2
+
3
+ module Rack
4
+ module Brotli
5
+ class Instrument
6
+ def self.instrument(name, **args, &block)
7
+ yield
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rack
4
+ module Brotli
5
+ class Railtie < ::Rails::Railtie
6
+ initializer "rack-brotli.middleware" do |app|
7
+ app.middleware.use(Rack::Brotli)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rack
4
+ module Brotli
5
+ class Version
6
+ def self.to_s
7
+ '1.2.0'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ require 'rack/brotli'
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-easy_brotli
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Marco Costa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: brotli
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 5.14.4
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 5.14.4
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 13.0.3
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 13.0.3
83
+ - !ruby/object:Gem::Dependency
84
+ name: rdoc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 6.3.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 6.3.1
97
+ description: Rack::Brotli enables Google's Brotli compression on HTTP responses
98
+ email: marco@marcotc.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files:
102
+ - README.md
103
+ - COPYING
104
+ files:
105
+ - COPYING
106
+ - README.md
107
+ - lib/rack/brotli.rb
108
+ - lib/rack/brotli/deflater.rb
109
+ - lib/rack/brotli/instrument.rb
110
+ - lib/rack/brotli/railtie.rb
111
+ - lib/rack/brotli/version.rb
112
+ - lib/rack/easy_brotli.rb
113
+ homepage: http://github.com/marcotc/rack-brotli/
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options:
119
+ - "--line-numbers"
120
+ - "--inline-source"
121
+ - "--title"
122
+ - rack-brotli
123
+ - "--main"
124
+ - README
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.5.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.2.17
139
+ signing_key:
140
+ specification_version: 2
141
+ summary: Brotli compression for Rack responses
142
+ test_files: []