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 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