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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ed6ee8b93f831a07db19a0d5417a95016249684b80e4bf4851734eafa981767
4
- data.tar.gz: 56d44e9da44fccf0ec9930b5d3c413cd40c69804b8ece3f623efe708ce648ba6
3
+ metadata.gz: 80ac1fffcb44aa2fdd40358c5d994fddfa6c5eacf70727bf46c05e4271db6ed2
4
+ data.tar.gz: 89694162bad1fd4df6827e004f82a9a8b05bd7d849eff35a586dfcc5b6259eba
5
5
  SHA512:
6
- metadata.gz: 6c4450c2b1516454768e88c3822a11c6a0ebbb586e23137d63057b567a9a848da0b9d2a23d37094ac6059b73cbd308d373f3522f892e8f2c139b9d695adbaa31
7
- data.tar.gz: b18b853f8c241626688110dd57757b7dba2b1f3b762dfd0f17c54c530782429bebea6c1b737c029d9950110352c2431ba1ba1f130a9b4a4343fa6c7459de6879
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['HTTP_HOST'].start_with?('amp') },
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
- #### headers
28
- A `Hash`, representing html headers of SXG (outer) response.
29
-
30
- By default three headers are set: `Content-Type`, `Cache-Control`, `X-Content-Type-Options`.
31
-
32
- #### expires_in
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` can handle `.sxg`-format requests by wrapping the respective HTML contents into signed exchange response. For example the route `https://my.app.com/abc.sxg` will respond with signed contents for `https://my.app.com/abc`.
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 `.sxg` requests will be wrapped into signed exchanges.
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`. Now all supplimentary `.sxg` routes will be available just out of the box.<br>
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.sxg` will spit signed http exchange, containing original `<h1>Hello world!</h1>` HTML:
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 if substitute_sxg_extension!(env['PATH_INFO'])
19
-
17
+ env[SXG_FLAG] = true
20
18
  response = @app.call(env)
21
- return response unless response[0] == 200 && env[SXG_FLAG]
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']
@@ -1,13 +1,15 @@
1
1
  module WebPackage
2
- OPTIONS = %i[headers expires_in sub_extension filter cert_url cert_path priv_path].freeze
3
- ENV_KEYS = Set.new(%w[SXG_CERT_URL SXG_CERT_PATH SXG_PRIV_PATH]).freeze
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
- sub_extension: nil, # proxy as default format (html)
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|
@@ -1,3 +1,3 @@
1
1
  module WebPackage
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
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.3.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-06-21 00:00:00.000000000 Z
12
+ date: 2019-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubocop