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