web_package 0.3.0 → 0.4.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 +4 -4
- data/README.md +11 -33
- data/lib/web_package/middleware.rb +2 -14
- data/lib/web_package/settings.rb +6 -4
- data/lib/web_package/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80ac1fffcb44aa2fdd40358c5d994fddfa6c5eacf70727bf46c05e4271db6ed2
|
|
4
|
+
data.tar.gz: 89694162bad1fd4df6827e004f82a9a8b05bd7d849eff35a586dfcc5b6259eba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6dd25a2fee108b1394acfe0a322ab27eb8864bbe29d1b59926be70f555a0a636c26f5a4a55928c3c31c7100c96c23cf831491f76d2f3e47883d5cc48e0f888ed
|
|
7
|
+
data.tar.gz: 0a87488d00d511656f2a815b4de505986f213fb0963de52ae33e3c4619b8773fcbe5a538f7d5481046665c9f0987f54586b2ece994863ce6945ad448f46cba90
|
data/README.md
CHANGED
|
@@ -18,39 +18,17 @@ E.g.
|
|
|
18
18
|
```ruby
|
|
19
19
|
# variables can be set all at once:
|
|
20
20
|
WebPackage::Settings.merge! expires_in: ->(uri) { uri.path.start_with?('/news') ? 7.days : 1.day },
|
|
21
|
-
filter: ->(env) { env['
|
|
22
|
-
sub_extension: '.html'
|
|
21
|
+
filter: ->(env) { env['HTTP_ACCEPT'].include?('application/signed-exchange;v=b3') }
|
|
23
22
|
# or individually via dot-methods:
|
|
24
23
|
WebPackage::Settings.cert_url = 'https://my.cdn.com/cert.cbor'
|
|
25
24
|
```
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
An `Integer` or a `Proc` evaluating to an `Integer` or an object responding to `to_i`. It sets the lifetime of signed exchange, in seconds.
|
|
34
|
-
|
|
35
|
-
Default value is 7 days (604800 seconds), which is the maximum allowed by the standard. Please mind it when supplying your `Proc`.
|
|
36
|
-
|
|
37
|
-
#### sub_extension
|
|
38
|
-
A `String` or `nil`, representing an extension to use for proxying `.sxg` requests.
|
|
39
|
-
|
|
40
|
-
Default value is `nil`, which means that `.sxg` extension is just removed from the path for the rest of Rack middlewares.
|
|
41
|
-
|
|
42
|
-
#### filter
|
|
43
|
-
A `Proc`, accepting a single argument of environment and returning boolean value. The filter determines for which requests `.sxg` formatted routes should be added.
|
|
44
|
-
|
|
45
|
-
Default value is `->(env) { true }`, which means that all requests are permitted and hence can be processed in SXG format using `.sxg` extension.
|
|
46
|
-
|
|
47
|
-
#### cert_url, cert_path, priv_path
|
|
48
|
-
|
|
49
|
-
All three are `String`, pointing to a certificate with which all pages are to be signed:
|
|
50
|
-
- `cert_url` is the url of a certificate in `application/cert-chain+cbor` format
|
|
51
|
-
- `cert_path` and `priv_path` are two paths pointing at `pem` file and private key file respectively.
|
|
52
|
-
|
|
53
|
-
These are the only parameters which do not have default values. An exception is raised if they are not set beforehand. Please refer below to the section of _Required variables_ on the ways to set them.
|
|
26
|
+
| Parameter | Description | Default value |
|
|
27
|
+
|-----------|--------------|---------------|
|
|
28
|
+
| *headers* | A `Hash`, representing html headers of SXG (outer) response. | `{ 'Content-Type' => 'application/signed-exchange;v=b3', 'Cache-Control' => 'no-transform', 'X-Content-Type-Options' => 'nosniff' }`|
|
|
29
|
+
| *expires_in* | An `Integer` or a `Proc` evaluating to an `Integer` or an object responding to `to_i`. It sets the lifetime of signed exchange, in seconds.| `604800` (7 days), which is the maximum allowed by the standard. Please mind it when supplying your `Proc`.|
|
|
30
|
+
| *filter* | A `Proc`, accepting a single argument of environment and returning boolean value. The filter determines for which requests an SXG format should be served. | `->(env) { env['HTTP_ACCEPT'].include?('application/signed-exchange') }`|
|
|
31
|
+
| *cert_url, cert_path, priv_path* | All three are of `String` class, pointing to a certificate with which all pages are to be signed: <br>- `cert_url` is the url of a certificate in `application/cert-chain+cbor` format <br>- `cert_path` and `priv_path` are two paths pointing at `pem` file and private key file respectively. | These are the only parameters which do not have default values. An exception is raised if they are not set beforehand. Please refer below to the section of _Required variables_ on the ways to set them.|
|
|
54
32
|
|
|
55
33
|
### Required variables
|
|
56
34
|
|
|
@@ -74,7 +52,7 @@ WebPackage::Settings.cert_url = 'https://my.cdn.com/cert.cbor'
|
|
|
74
52
|
|
|
75
53
|
### Use it as a middleware
|
|
76
54
|
|
|
77
|
-
`WebPackage::Middleware`
|
|
55
|
+
`WebPackage::Middleware` wraps HTML responses for desired requests into signed exchange format.
|
|
78
56
|
|
|
79
57
|
If you already have a Rack-based application (like Rails or Sinatra), than it is easy to incorporate an SXG proxy into its middleware stack.
|
|
80
58
|
|
|
@@ -89,7 +67,7 @@ And then plug the middleware in:
|
|
|
89
67
|
config.middleware.insert 0, 'WebPackage::Middleware'
|
|
90
68
|
```
|
|
91
69
|
|
|
92
|
-
That is it. Now all successful
|
|
70
|
+
That is it. Now all successful requests with `Accept: application/signed-exchange` header will be wrapped into signed exchanges.
|
|
93
71
|
|
|
94
72
|
#### Pure Rack app
|
|
95
73
|
Imagine we have a simple web app:
|
|
@@ -106,12 +84,12 @@ gem 'web_package'
|
|
|
106
84
|
use WebPackage::Middleware
|
|
107
85
|
```
|
|
108
86
|
|
|
109
|
-
We are done. Start your app by running a command `rackup config.ru
|
|
87
|
+
We are done. Start your app by running a command `rackup config.ru`.<br>
|
|
110
88
|
As expected, visiting `http://localhost:9292/hello` will produce:
|
|
111
89
|
```html
|
|
112
90
|
<h1>Hello world!</h1>
|
|
113
91
|
```
|
|
114
|
-
What's more, visiting `http://localhost:9292/hello
|
|
92
|
+
What's more, visiting `http://localhost:9292/hello` with `Accept: application/signed-exchange` header will spit signed http exchange, containing original `<h1>Hello world!</h1>` HTML:
|
|
115
93
|
```text
|
|
116
94
|
sxg1-b3\x00\x00\x1Chttps://localhost:9292/hello\x00\x019\x00\x00?label;cert-sha256=*+DoXYlCX+bFRyW65R3bFA2ICIz8Tyu54MLFUFo5tziA=*;cert-url=\"https://my.cdn.com/cert.cbor\";date=1557657274;expires=1558262074;integrity=\"digest/mi-sha256-03\";sig=*MEUCIAKKz+KSuhlzywfU12h3SkEq5ZuYYMxDZIgEDGYMd9sAAiEAj66Il48eb0CXFAnuZhnS+j6dqZVLJ6IwUVGWShhQu9g=*;validity-url=\"https://localhost/hello\"?FdigestX9mi-sha256-03=4QeUScOpSoJl7KJ47F11rSDHUTHZhDVwLiSLOWMcvqg=G:statusC200Pcontent-encodingLmi-sha256-03Vx-content-type-optionsGnosniff\x00\x00\x00\x00\x00\x00@\x00<h1>Hello world!</h1>
|
|
117
95
|
```
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
module WebPackage
|
|
2
|
-
SXG_EXT = '.sxg'.freeze
|
|
3
2
|
SXG_FLAG = 'web_package.sxg'.freeze
|
|
4
3
|
|
|
5
4
|
# A Rack-compatible middleware.
|
|
@@ -15,10 +14,9 @@ module WebPackage
|
|
|
15
14
|
private
|
|
16
15
|
|
|
17
16
|
def process(env)
|
|
18
|
-
env[SXG_FLAG] = true
|
|
19
|
-
|
|
17
|
+
env[SXG_FLAG] = true
|
|
20
18
|
response = @app.call(env)
|
|
21
|
-
return response
|
|
19
|
+
return response if response[0] != 200
|
|
22
20
|
|
|
23
21
|
# the original body must be closed first
|
|
24
22
|
response[2].close if response[2].respond_to? :close
|
|
@@ -27,16 +25,6 @@ module WebPackage
|
|
|
27
25
|
SignedHttpExchange.new(uri(env), response).to_rack_response
|
|
28
26
|
end
|
|
29
27
|
|
|
30
|
-
def substitute_sxg_extension!(path)
|
|
31
|
-
return unless path.is_a?(String) && (i = path.rindex(SXG_EXT))
|
|
32
|
-
|
|
33
|
-
# check that extension is either the last char or followed by a slash
|
|
34
|
-
ch = path[i + SXG_EXT.size]
|
|
35
|
-
return if ch && ch != ?/
|
|
36
|
-
|
|
37
|
-
path[i, SXG_EXT.size] = Settings.sub_extension.to_s
|
|
38
|
-
end
|
|
39
|
-
|
|
40
28
|
def uri(env)
|
|
41
29
|
URI("https://#{env['HTTP_HOST'] || env['SERVER_NAME']}").tap do |u|
|
|
42
30
|
path = env['PATH_INFO']
|
data/lib/web_package/settings.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
module WebPackage
|
|
2
|
-
OPTIONS
|
|
3
|
-
ENV_KEYS
|
|
2
|
+
OPTIONS = %i[headers expires_in filter cert_url cert_path priv_path].freeze
|
|
3
|
+
ENV_KEYS = Set.new(%w[SXG_CERT_URL SXG_CERT_PATH SXG_PRIV_PATH]).freeze
|
|
4
|
+
SXG_MIME_TYPE = 'application/signed-exchange'.freeze
|
|
5
|
+
ACCEPT_HEADER = 'HTTP_ACCEPT'.freeze
|
|
6
|
+
|
|
4
7
|
DEFAULTS = {
|
|
5
8
|
headers: { 'Content-Type' => 'application/signed-exchange;v=b3',
|
|
6
9
|
'Cache-Control' => 'no-transform',
|
|
7
10
|
'X-Content-Type-Options' => 'nosniff' },
|
|
8
11
|
expires_in: 60 * 60 * 24 * 7, # 7.days
|
|
9
|
-
|
|
10
|
-
filter: ->(_env) { true } # all requests are permitted
|
|
12
|
+
filter: ->(env) { env[ACCEPT_HEADER].include?(SXG_MIME_TYPE) }
|
|
11
13
|
}.freeze
|
|
12
14
|
|
|
13
15
|
Settings = ConfigurationHash.new(OPTIONS) do |config, key|
|
data/lib/web_package/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: web_package
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oleg Afanasyev
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2019-
|
|
12
|
+
date: 2019-07-16 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rubocop
|