async-http-cache 0.4.2 → 0.4.4

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: 4f2003b72015123e99c75069272771e6247c31abbd55163da86955dd462dc4d6
4
- data.tar.gz: dd9798d6736f4e73c06e1a15a6010c192a663042081ee6d92484eddd4b924256
3
+ metadata.gz: dc8d7b58e3ba4a009b05a55f06a7ffbc546b20aa9d916c3b4bbaf054a99a9f38
4
+ data.tar.gz: d6b71693a4f9272862f9e710b295a56966047411fcb903ef4029b30c2605b5a9
5
5
  SHA512:
6
- metadata.gz: 9ba0a34a15023d0e2b3b66052aa233f3180b4706e28040b08c0d8605e288230cee7461ffc8ecc3602575ae57e8b0ca7e713181aa07a83453f201c76680e0a32a
7
- data.tar.gz: 8722d2f6aa70df6e830ecd1482916b26bd42d8f18ccd070010fb6c7d5689982b503cceb3df604e14c359d4cd8cdc9b63a0612b0b8bbf7f40b52e7cb029817611
6
+ metadata.gz: 19269b3b4e941221415d4b94f9aa022ac49df8ed3f3e6b96a08f3eb48e6e224f3e68b16c56892fd69c0f4956eb6b79882abc515547a031207ab92d1b2be79c09
7
+ data.tar.gz: 20a5a417aff84525e438667966dda756e57db643fe4ab236461c934d6c7ae4d6b92d53e273f720bcb62a85b70562e24e1623c4c0dbcb97fd20b0ecf3f5d01dd3
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ �t���̻�[������4���o�O�
2
+ 2�W��CC�f$�����`�ŃB�Gp�{P W&X;Z� >!�Fa��H�.
3
+ `
@@ -1,29 +1,15 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/body/rewindable'
24
7
  require 'protocol/http/body/completable'
25
8
  require 'protocol/http/body/digestable'
26
9
 
10
+ require 'console'
11
+ require 'console/event/failure'
12
+
27
13
  module Async
28
14
  module HTTP
29
15
  module Cache
@@ -53,7 +39,7 @@ module Async
53
39
  # Wrap the response with the callback:
54
40
  ::Protocol::HTTP::Body::Completable.wrap(response) do |error|
55
41
  if error
56
- Console.logger.error(self) {error}
42
+ Console::Event::Failure.for(error).emit(self)
57
43
  else
58
44
  yield response, rewindable.buffered
59
45
  end
@@ -1,25 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
5
+ # Copyright, 2022, by Colin Kelley.
22
6
 
7
+ require 'set'
23
8
  require 'protocol/http/middleware'
24
9
 
25
10
  require_relative 'body'
@@ -29,12 +14,28 @@ require_relative 'store'
29
14
  module Async
30
15
  module HTTP
31
16
  module Cache
17
+ # Implements a general shared cache according to https://www.rfc-editor.org/rfc/rfc9111
32
18
  class General < ::Protocol::HTTP::Middleware
33
19
  CACHE_CONTROL = 'cache-control'
34
20
 
35
21
  CONTENT_TYPE = 'content-type'
36
22
  AUTHORIZATION = 'authorization'
37
23
  COOKIE = 'cookie'
24
+ SET_COOKIE = 'set-cookie'
25
+
26
+ # Status codes of responses that MAY be stored by a cache or used in reply
27
+ # to a subsequent request.
28
+ #
29
+ # http://tools.ietf.org/html/rfc2616#section-13.4
30
+ CACHEABLE_RESPONSE_CODES = {
31
+ 200 => true, # OK
32
+ 203 => true, # Non-Authoritative Information
33
+ 300 => true, # Multiple Choices
34
+ 301 => true, # Moved Permanently
35
+ 302 => true, # Found
36
+ 404 => true, # Not Found
37
+ 410 => true # Gone
38
+ }.freeze
38
39
 
39
40
  def initialize(app, store: Store.default)
40
41
  super(app)
@@ -59,8 +60,8 @@ module Async
59
60
  [request.authority, request.method, request.path]
60
61
  end
61
62
 
62
- def cacheable?(request)
63
- # We don't support caching requests which have a body:
63
+ def cacheable_request?(request)
64
+ # We don't support caching requests which have a request body:
64
65
  if request.body
65
66
  return false
66
67
  end
@@ -87,33 +88,88 @@ module Async
87
88
  return true
88
89
  end
89
90
 
90
- def wrap(key, request, response)
91
- if response.status != 200
92
- return response
91
+ def cacheable_response_headers?(headers)
92
+ if cache_control = headers[CACHE_CONTROL]
93
+ if cache_control.no_store? || cache_control.private?
94
+ Console.logger.debug(self, cache_control: cache_control) {"Cannot cache response with cache-control header!"}
95
+ return false
96
+ end
97
+ end
98
+
99
+ if set_cookie = headers[SET_COOKIE]
100
+ Console.logger.debug(self) {"Cannot cache response with set-cookie header!"}
101
+ return false
102
+ end
103
+
104
+ return true
105
+ end
106
+
107
+ def cacheable_response?(response)
108
+ # At this point, we know response.status and response.headers.
109
+ # But we don't know response.body or response.headers.trailer.
110
+ unless CACHEABLE_RESPONSE_CODES.include?(response.status)
111
+ Console.logger.debug(self, status: response.status) {"Cannot cache response with status code!"}
112
+ return false
113
+ end
114
+
115
+ unless cacheable_response_headers?(response.headers)
116
+ Console.logger.debug(self) {"Cannot cache response with uncacheable headers!"}
117
+ return false
93
118
  end
94
119
 
120
+ return true
121
+ end
122
+
123
+ # Semantically speaking, it is possible for trailers to result in an uncacheable response, so we need to check for that.
124
+ def proceed_with_response_cache?(response)
125
+ if response.headers.trailer?
126
+ unless cacheable_response_headers?(response.headers)
127
+ Console.logger.debug(self, trailer: trailer.keys) {"Cannot cache response with trailer header!"}
128
+ return false
129
+ end
130
+ end
131
+
132
+ return true
133
+ end
134
+
135
+ # Potentially wrap the response so that it updates the cache, if caching is possible.
136
+ def wrap(key, request, response)
95
137
  if request.head? and body = response.body
96
138
  unless body.empty?
97
139
  Console.logger.warn(self) {"HEAD request resulted in non-empty body!"}
98
-
140
+
99
141
  return response
100
142
  end
101
143
  end
102
144
 
145
+ unless cacheable_request?(request)
146
+ Console.logger.debug(self) {"Cannot cache request!"}
147
+ return response
148
+ end
149
+
150
+ unless cacheable_response?(response)
151
+ Console.logger.debug(self) {"Cannot cache response!"}
152
+ return response
153
+ end
154
+
103
155
  return Body.wrap(response) do |response, body|
104
- Console.logger.debug(self) {"Updating cache for #{key}..."}
105
- @store.insert(key, request, Response.new(response, body))
156
+ if proceed_with_response_cache?(response)
157
+ key ||= self.key(request)
158
+
159
+ Console.logger.debug(self, key: key) {"Updating miss!"}
160
+ @store.insert(key, request, Response.new(response, body))
161
+ end
106
162
  end
107
163
  end
108
-
164
+
109
165
  def call(request)
110
- key = self.key(request)
111
-
112
166
  cache_control = request.headers[CACHE_CONTROL]
113
167
 
114
168
  unless cache_control&.no_cache?
169
+ key = self.key(request)
170
+
115
171
  if response = @store.lookup(key, request)
116
- Console.logger.debug(self) {"Cache hit for #{key}..."}
172
+ Console.logger.debug(self, key: key) {"Cache hit!"}
117
173
  @count += 1
118
174
 
119
175
  # Return the cached response:
@@ -122,9 +178,7 @@ module Async
122
178
  end
123
179
 
124
180
  unless cache_control&.no_store?
125
- if cacheable?(request)
126
- return wrap(key, request, super)
127
- end
181
+ return wrap(key, request, super)
128
182
  end
129
183
 
130
184
  return super
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/response'
24
7
  require 'async/clock'
@@ -28,7 +11,6 @@ module Async
28
11
  module Cache
29
12
  class Response < ::Protocol::HTTP::Response
30
13
  CACHE_CONTROL = 'cache-control'
31
- SET_COOKIE = 'set-cookie'
32
14
  ETAG = 'etag'
33
15
 
34
16
  X_CACHE = 'x-cache'
@@ -56,24 +38,6 @@ module Async
56
38
  @etag ||= @headers[ETAG]
57
39
  end
58
40
 
59
- def cachable?
60
- if cache_control = @headers[CACHE_CONTROL]
61
- if cache_control.private? || !cache_control.public?
62
- return false
63
- end
64
- else
65
- # No cache control header...
66
- return false
67
- end
68
-
69
- if set_cookie = @headers[SET_COOKIE]
70
- Console.logger.warn(self) {"Cannot cache response with set-cookie header!"}
71
- return false
72
- end
73
-
74
- return true
75
- end
76
-
77
41
  def age
78
42
  Async::Clock.now - @generated_at
79
43
  end
@@ -1,33 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  module Async
24
7
  module HTTP
25
8
  module Cache
26
9
  module Store
27
10
  class Memory
28
- def initialize(limit: 1024)
11
+ def initialize(limit: 1024, maximum_size: 1024*64, prune_interval: 60)
29
12
  @index = {}
30
13
  @limit = limit
14
+ @maximum_size = maximum_size
31
15
 
32
16
  @hit = 0
33
17
  @miss = 0
@@ -35,7 +19,7 @@ module Async
35
19
 
36
20
  @gardener = Async(transient: true, annotation: self.class) do |task|
37
21
  while true
38
- task.sleep(60)
22
+ task.sleep(prune_interval)
39
23
 
40
24
  pruned = self.prune
41
25
  @pruned += pruned
@@ -96,7 +80,7 @@ module Async
96
80
  def insert(key, request, response)
97
81
  if @index.size < @limit
98
82
  length = response.body&.length
99
- if length.nil? or length < 1024*64
83
+ if length.nil? or length < @maximum_size
100
84
  @index[key] = response
101
85
  end
102
86
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  module Async
24
7
  module HTTP
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  require_relative 'store/memory'
24
7
  require_relative 'store/vary'
@@ -1,29 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  module Async
24
7
  module HTTP
25
8
  module Cache
26
- VERSION = "0.4.2"
9
+ VERSION = "0.4.4"
27
10
  end
28
11
  end
29
12
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2024, by Samuel Williams.
22
5
 
23
6
  require_relative "cache/version"
24
7
  require_relative "cache/general"
data/license.md ADDED
@@ -0,0 +1,23 @@
1
+ # MIT License
2
+
3
+ Copyright, 2020-2024, by Samuel Williams.
4
+ Copyright, 2021, by Olle Jonsson.
5
+ Copyright, 2022, by Colin Kelley.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,53 @@
1
+ # Async::HTTP::Cache
2
+
3
+ Provides a cache middleware for `Async::HTTP` clients and servers.
4
+
5
+ [![Development Status](https://github.com/socketry/async-http-cache/workflows/Test/badge.svg)](https://github.com/socketry/async-http-cache/actions?workflow=Test)
6
+
7
+ ## Usage
8
+
9
+ ### Client Side
10
+
11
+ ``` ruby
12
+ require 'async'
13
+ require 'async/http'
14
+ require 'async/http/cache'
15
+
16
+ endpoint = Async::HTTP::Endpoint.parse("https://www.oriontransfer.co.nz")
17
+ client = Async::HTTP::Client.new(endpoint)
18
+ cache = Async::HTTP::Cache::General.new(client)
19
+
20
+ Async do
21
+ 2.times do
22
+ response = cache.get("/products/index")
23
+ puts response.inspect
24
+ # <Async::HTTP::Protocol::HTTP2::Response ...>
25
+ # <Async::HTTP::Cache::Response ...>
26
+ response.finish
27
+ end
28
+ ensure
29
+ cache.close
30
+ end
31
+ ```
32
+
33
+ ## Vary
34
+
35
+ The `vary` header creates a headache for proxy implementations, because it creates a combinatorial explosion of cache keys, even if the content is the same. Try to avoid it unless absolutely necessary.
36
+
37
+ ## Contributing
38
+
39
+ We welcome contributions to this project.
40
+
41
+ 1. Fork it.
42
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
43
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
44
+ 4. Push to the branch (`git push origin my-new-feature`).
45
+ 5. Create new Pull Request.
46
+
47
+ ### Developer Certificate of Origin
48
+
49
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
50
+
51
+ ### Community Guidelines
52
+
53
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ v�1��g��p4�����[������Yɶ���' ��ASb܂澈�ŧ���`]rc+��y���R�"��o���{c��ί\K[����~7k�a_}04-��볱��\]��ƁB5�͊�?�8��z�X�:���5���X)�-�F�U'\:��p�]LR{��]ߨ��LJ��|���`e���Ч<M.rٖ3J���V�V* D�#Sϋu,��E������1O/���'�ǟpy�8����K7R eq���`��c�jp��粭pG�� ��5~p�a_�J��K;���~�؜�[r�RK��^�Gĵ4�e;{�c5*;Ok\�Z�8�=��
metadata CHANGED
@@ -1,14 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-http-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
+ - Colin Kelley
9
+ - Olle Jonsson
8
10
  autorequire:
9
11
  bindir: bin
10
- cert_chain: []
11
- date: 2021-05-13 00:00:00.000000000 Z
12
+ cert_chain:
13
+ - |
14
+ -----BEGIN CERTIFICATE-----
15
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
16
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
17
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
18
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
19
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
20
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
21
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
22
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
23
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
24
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
25
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
26
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
27
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
28
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
29
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
30
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
31
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
32
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
33
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
34
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
35
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
36
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
37
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
38
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
39
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
40
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
41
+ -----END CERTIFICATE-----
42
+ date: 2024-07-18 00:00:00.000000000 Z
12
43
  dependencies:
13
44
  - !ruby/object:Gem::Dependency
14
45
  name: async-http
@@ -24,48 +55,6 @@ dependencies:
24
55
  - - "~>"
25
56
  - !ruby/object:Gem::Version
26
57
  version: '0.56'
27
- - !ruby/object:Gem::Dependency
28
- name: async-rspec
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.10'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.10'
41
- - !ruby/object:Gem::Dependency
42
- name: covered
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: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
58
  description:
70
59
  email:
71
60
  executables: []
@@ -80,10 +69,13 @@ files:
80
69
  - lib/async/http/cache/store/memory.rb
81
70
  - lib/async/http/cache/store/vary.rb
82
71
  - lib/async/http/cache/version.rb
72
+ - license.md
73
+ - readme.md
83
74
  homepage: https://github.com/socketry/async-http-cache
84
75
  licenses:
85
76
  - MIT
86
- metadata: {}
77
+ metadata:
78
+ source_code_uri: https://github.com/socketry/async-http-cache.git
87
79
  post_install_message:
88
80
  rdoc_options: []
89
81
  require_paths:
@@ -92,14 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
84
  requirements:
93
85
  - - ">="
94
86
  - !ruby/object:Gem::Version
95
- version: 2.3.0
87
+ version: '3.1'
96
88
  required_rubygems_version: !ruby/object:Gem::Requirement
97
89
  requirements:
98
90
  - - ">="
99
91
  - !ruby/object:Gem::Version
100
92
  version: '0'
101
93
  requirements: []
102
- rubygems_version: 3.3.0.dev
94
+ rubygems_version: 3.5.11
103
95
  signing_key:
104
96
  specification_version: 4
105
97
  summary: Standard-compliant cache for async-http.
metadata.gz.sig ADDED
Binary file