http 0.7.4 → 0.8.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.rubocop.yml +5 -2
- data/CHANGES.md +24 -7
- data/CONTRIBUTING.md +25 -0
- data/Gemfile +24 -22
- data/Guardfile +2 -2
- data/README.md +34 -4
- data/Rakefile +7 -7
- data/examples/parallel_requests_with_celluloid.rb +2 -2
- data/http.gemspec +12 -12
- data/lib/http.rb +11 -10
- data/lib/http/cache.rb +146 -0
- data/lib/http/cache/headers.rb +100 -0
- data/lib/http/cache/null_cache.rb +13 -0
- data/lib/http/chainable.rb +14 -3
- data/lib/http/client.rb +64 -80
- data/lib/http/connection.rb +139 -0
- data/lib/http/content_type.rb +2 -2
- data/lib/http/errors.rb +7 -1
- data/lib/http/headers.rb +21 -8
- data/lib/http/headers/mixin.rb +1 -1
- data/lib/http/mime_type.rb +2 -2
- data/lib/http/mime_type/adapter.rb +2 -2
- data/lib/http/mime_type/json.rb +4 -4
- data/lib/http/options.rb +65 -74
- data/lib/http/redirector.rb +3 -3
- data/lib/http/request.rb +20 -13
- data/lib/http/request/caching.rb +95 -0
- data/lib/http/request/writer.rb +5 -5
- data/lib/http/response.rb +15 -9
- data/lib/http/response/body.rb +21 -8
- data/lib/http/response/caching.rb +142 -0
- data/lib/http/response/io_body.rb +63 -0
- data/lib/http/response/parser.rb +1 -1
- data/lib/http/response/status.rb +4 -12
- data/lib/http/response/status/reasons.rb +53 -53
- data/lib/http/response/string_body.rb +53 -0
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/cache/headers_spec.rb +77 -0
- data/spec/lib/http/cache_spec.rb +182 -0
- data/spec/lib/http/client_spec.rb +123 -95
- data/spec/lib/http/content_type_spec.rb +25 -25
- data/spec/lib/http/headers/mixin_spec.rb +8 -8
- data/spec/lib/http/headers_spec.rb +213 -173
- data/spec/lib/http/options/body_spec.rb +5 -5
- data/spec/lib/http/options/form_spec.rb +3 -3
- data/spec/lib/http/options/headers_spec.rb +7 -7
- data/spec/lib/http/options/json_spec.rb +3 -3
- data/spec/lib/http/options/merge_spec.rb +26 -22
- data/spec/lib/http/options/new_spec.rb +10 -10
- data/spec/lib/http/options/proxy_spec.rb +8 -8
- data/spec/lib/http/options_spec.rb +2 -2
- data/spec/lib/http/redirector_spec.rb +32 -32
- data/spec/lib/http/request/caching_spec.rb +133 -0
- data/spec/lib/http/request/writer_spec.rb +26 -26
- data/spec/lib/http/request_spec.rb +63 -58
- data/spec/lib/http/response/body_spec.rb +13 -13
- data/spec/lib/http/response/caching_spec.rb +201 -0
- data/spec/lib/http/response/io_body_spec.rb +35 -0
- data/spec/lib/http/response/status_spec.rb +25 -25
- data/spec/lib/http/response/string_body_spec.rb +35 -0
- data/spec/lib/http/response_spec.rb +64 -45
- data/spec/lib/http_spec.rb +103 -76
- data/spec/spec_helper.rb +10 -12
- data/spec/support/connection_reuse_shared.rb +100 -0
- data/spec/support/create_certs.rb +12 -12
- data/spec/support/dummy_server.rb +11 -11
- data/spec/support/dummy_server/servlet.rb +43 -31
- data/spec/support/proxy_server.rb +31 -25
- metadata +57 -8
- data/spec/support/example_server.rb +0 -30
- data/spec/support/example_server/servlet.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a705cb32b18d35b7b100eea0ac6f6687c8e9140e
|
4
|
+
data.tar.gz: fff73981101e4bc7a80faeded4d8bde937dd0fa4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32e0571165aff841356c98fdea9135c6e746a36527f7f7db566effb2321d58dc287b26efbd9651c961cb675fc0621333a12cd0608e3b9cc5a57b0259f220d13d
|
7
|
+
data.tar.gz: 7b90b9fba3136f9732667dbae22a561b3f338a11f86e70878494d11b657d7cc64e19403ceb1a5898a844c886e384ae31752cf894527404279d3c5d6b79a4cf96
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
@@ -20,8 +20,8 @@ Metrics/ParameterLists:
|
|
20
20
|
Max: 3
|
21
21
|
CountKeywordArgs: true
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
Metrics/AbcSize:
|
24
|
+
Enabled: false
|
25
25
|
|
26
26
|
Style/CollectionMethods:
|
27
27
|
PreferredMethods:
|
@@ -57,5 +57,8 @@ Style/SingleSpaceBeforeFirstArg:
|
|
57
57
|
Style/SpaceInsideHashLiteralBraces:
|
58
58
|
EnforcedStyle: no_space
|
59
59
|
|
60
|
+
Style/StringLiterals:
|
61
|
+
EnforcedStyle: double_quotes
|
62
|
+
|
60
63
|
Style/TrivialAccessors:
|
61
64
|
Enabled: false
|
data/CHANGES.md
CHANGED
@@ -1,14 +1,20 @@
|
|
1
|
-
## 0.
|
2
|
-
|
3
|
-
*
|
1
|
+
## 0.8.0.pre (2015-03-26)
|
2
|
+
|
3
|
+
* Support for persistent HTTP connections
|
4
|
+
* Improve servers used in specs boot up. Issue was initially raised up
|
5
|
+
by @olegkovalenko. See #176.
|
6
|
+
* Reflect FormData rename changes (FormData -> HTTP::FormData). (@ixti)
|
7
|
+
* `HTTP::Headers` now raises `HTTP::InvalidHeaderNameError` in case of
|
8
|
+
(surprise) invalid HTTP header field name (e.g.`"Foo:Bar"`). See #173.
|
9
|
+
(@ixti)
|
4
10
|
|
5
11
|
|
6
12
|
## 0.7.3 (2015-03-24)
|
7
13
|
|
8
|
-
* SECURITY FIX: http.rb failed to call the
|
9
|
-
|
10
|
-
|
11
|
-
|
14
|
+
* SECURITY FIX: http.rb failed to call the `#post_connection_check` method on
|
15
|
+
SSL connections. This method implements hostname verification, and without it
|
16
|
+
`http.rb` was vulnerable to MitM attacks. The problem was corrected by calling
|
17
|
+
`#post_connection_check` (CVE-2015-1828) (@zanker)
|
12
18
|
|
13
19
|
|
14
20
|
## 0.7.2 (2015-03-02)
|
@@ -24,6 +30,9 @@
|
|
24
30
|
|
25
31
|
## 0.7.0 (2015-01-02)
|
26
32
|
|
33
|
+
* Add support of multipart form data. See #73, #167. (@ixti)
|
34
|
+
* Fix URI path normalization: `https://github.com` -> `https://github.com/`.
|
35
|
+
(@ixti)
|
27
36
|
* Fix handling of EOF which caused infinite loop. See #163, #166 and #152. (@mickm, @ixti)
|
28
37
|
* Drop Ruby 1.8.7 support. (@ixti)
|
29
38
|
* Fix default Host header value. See #150. (@ixti)
|
@@ -46,6 +55,14 @@
|
|
46
55
|
* Delegate `HTTP::Response#readpartial` to `HTTP::Response::Body` (@ixti)
|
47
56
|
|
48
57
|
|
58
|
+
## 0.6.4 (2015-03-25)
|
59
|
+
|
60
|
+
* SECURITY FIX: http.rb failed to call the `#post_connection_check` method on
|
61
|
+
SSL connections. This method implements hostname verification, and without it
|
62
|
+
`http.rb` was vulnerable to MitM attacks. The problem was corrected by calling
|
63
|
+
`#post_connection_check` (CVE-2015-1828) (@zanker, backported by @nicoolas25)
|
64
|
+
|
65
|
+
|
49
66
|
## 0.6.3 (2014-11-14)
|
50
67
|
|
51
68
|
* Backported EOF fix from master branch. See #166. (@ixti)
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Help and Discussion
|
2
|
+
|
3
|
+
If you need help or just want to talk about the http.rb,
|
4
|
+
visit the http.rb Google Group:
|
5
|
+
|
6
|
+
https://groups.google.com/forum/#!forum/httprb
|
7
|
+
|
8
|
+
You can join by email by sending a message to:
|
9
|
+
|
10
|
+
[httprb+subscribe@googlegroups.com](mailto:httprb+subscribe@googlegroups.com)
|
11
|
+
|
12
|
+
|
13
|
+
# Reporting bugs
|
14
|
+
|
15
|
+
The best way to report a bug is by providing a reproduction script. A half
|
16
|
+
working script with comments for the parts you were unable to automate is still
|
17
|
+
appreciated.
|
18
|
+
|
19
|
+
In any case, specify following info in description of your issue:
|
20
|
+
|
21
|
+
- What you're trying to accomplish
|
22
|
+
- What you expected to happen
|
23
|
+
- What actually happened
|
24
|
+
- The exception backtrace(s), if any
|
25
|
+
- Version of gem or commit ref you are using
|
data/Gemfile
CHANGED
@@ -1,37 +1,39 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gem
|
4
|
-
gem
|
3
|
+
gem "jruby-openssl" if defined? JRUBY_VERSION
|
4
|
+
gem "rake"
|
5
|
+
|
6
|
+
gem "rack-cache", "~> 1.2"
|
5
7
|
|
6
8
|
group :development do
|
7
|
-
gem
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
9
|
+
gem "celluloid-io"
|
10
|
+
gem "guard"
|
11
|
+
gem "guard-rspec", :require => false
|
12
|
+
gem "pry"
|
11
13
|
|
12
14
|
platforms :ruby_19, :ruby_20 do
|
13
|
-
gem
|
14
|
-
gem
|
15
|
+
gem "pry-debugger"
|
16
|
+
gem "pry-stack_explorer"
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
20
|
group :test do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
22
|
-
gem
|
23
|
-
gem
|
24
|
-
gem
|
25
|
-
gem
|
26
|
-
gem
|
27
|
-
gem
|
28
|
-
gem
|
29
|
-
gem
|
21
|
+
gem "backports"
|
22
|
+
gem "coveralls"
|
23
|
+
gem "simplecov", ">= 0.9"
|
24
|
+
gem "json", ">= 1.8.1"
|
25
|
+
gem "mime-types", "~> 1.25", :platforms => [:jruby]
|
26
|
+
gem "rest-client", "~> 1.6.0", :platforms => [:jruby]
|
27
|
+
gem "rspec", "~> 3.0"
|
28
|
+
gem "rspec-its"
|
29
|
+
gem "rubocop"
|
30
|
+
gem "yardstick"
|
31
|
+
gem "certificate_authority"
|
30
32
|
end
|
31
33
|
|
32
34
|
group :doc do
|
33
|
-
gem
|
34
|
-
gem
|
35
|
+
gem "redcarpet"
|
36
|
+
gem "yard"
|
35
37
|
end
|
36
38
|
|
37
39
|
# Specify your gem's dependencies in http.gemspec
|
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# More info at https://github.com/guard/guard#readme
|
2
2
|
|
3
|
-
guard :rspec, :cmd =>
|
4
|
-
require
|
3
|
+
guard :rspec, :cmd => "GUARD_RSPEC=1 bundle exec rspec --no-profile" do
|
4
|
+
require "guard/rspec/dsl"
|
5
5
|
dsl = Guard::RSpec::Dsl.new(self)
|
6
6
|
|
7
7
|
# RSpec files
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
![http.rb](https://raw.github.com/httprb/http.rb/master/logo.png)
|
2
2
|
==============
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/http.
|
4
|
-
[![Build Status](https://secure.travis-ci.org/httprb/http.rb.
|
5
|
-
[![Code Climate](https://codeclimate.com/github/httprb/http.rb.
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/httprb/http.rb/badge.
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/http.svg)](http://rubygems.org/gems/http)
|
4
|
+
[![Build Status](https://secure.travis-ci.org/httprb/http.rb.svg?branch=master)](http://travis-ci.org/httprb/http.rb)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/httprb/http.rb.svg?branch=master)](https://codeclimate.com/github/httprb/http.rb)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/httprb/http.rb/badge.svg?branch=master)](https://coveralls.io/r/httprb/http.rb)
|
7
7
|
|
8
8
|
About
|
9
9
|
-----
|
@@ -125,6 +125,15 @@ Or just a plain body?
|
|
125
125
|
HTTP.post('http://example.com/resource', :body => 'foo=42&bar=baz')
|
126
126
|
```
|
127
127
|
|
128
|
+
Posting a file?
|
129
|
+
|
130
|
+
``` ruby
|
131
|
+
HTTP.post('http://examplc.com/resource', :form => {
|
132
|
+
:username => 'ixti',
|
133
|
+
:avatar => HTTP::FormData::File.new('/home/ixit/avatar.png')
|
134
|
+
})
|
135
|
+
```
|
136
|
+
|
128
137
|
It's easy!
|
129
138
|
|
130
139
|
### Proxy Support
|
@@ -240,6 +249,27 @@ There's a little more to it, but that's the core idea!
|
|
240
249
|
* [Full parallel HTTP fetcher example](https://github.com/httprb/http.rb/wiki/Parallel-requests-with-Celluloid%3A%3AIO)
|
241
250
|
* See also: [Celluloid::IO](https://github.com/celluloid/celluloid-io)
|
242
251
|
|
252
|
+
### Caching
|
253
|
+
|
254
|
+
http.rb provides caching of HTTP request (per
|
255
|
+
[RFC 7234](https://tools.ietf.org/html/rfc7234)) when configured to do
|
256
|
+
so.
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
require 'http'
|
260
|
+
|
261
|
+
http = HTTP.with_cache(metastore: "file:/var/cache/my-app-http/meta",
|
262
|
+
entitystore: "file:/var/cache/my-app-http/entity")
|
263
|
+
|
264
|
+
http.get("http://example.com/") # makes request
|
265
|
+
http.get("http://example.com/") # skips making request and returns
|
266
|
+
# previously cached response
|
267
|
+
```
|
268
|
+
|
269
|
+
http.rb's caching is backed by
|
270
|
+
[rack-cache's excellent storage subsystem](http://rtomayko.github.io/rack-cache/storage.html). Any
|
271
|
+
storage URL supported by rack-cache is supported by http.rb's cache.
|
272
|
+
|
243
273
|
Supported Ruby Versions
|
244
274
|
-----------------------
|
245
275
|
|
data/Rakefile
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
-
require
|
2
|
+
require "bundler/gem_tasks"
|
3
3
|
|
4
|
-
require
|
4
|
+
require "rspec/core/rake_task"
|
5
5
|
RSpec::Core::RakeTask.new
|
6
6
|
|
7
7
|
task :test => :spec
|
8
8
|
|
9
9
|
begin
|
10
|
-
require
|
10
|
+
require "rubocop/rake_task"
|
11
11
|
RuboCop::RakeTask.new
|
12
12
|
rescue LoadError
|
13
13
|
task :rubocop do
|
14
|
-
$stderr.puts
|
14
|
+
$stderr.puts "RuboCop is disabled"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
require
|
18
|
+
require "yardstick/rake/measurement"
|
19
19
|
Yardstick::Rake::Measurement.new do |measurement|
|
20
|
-
measurement.output =
|
20
|
+
measurement.output = "measurement/report.txt"
|
21
21
|
end
|
22
22
|
|
23
|
-
require
|
23
|
+
require "yardstick/rake/verify"
|
24
24
|
Yardstick::Rake::Verify.new do |verify|
|
25
25
|
verify.require_exact_threshold = false
|
26
26
|
verify.threshold = 58
|
data/http.gemspec
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path(
|
2
|
+
require File.expand_path("../lib/http/version", __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = [
|
6
|
-
gem.email = [
|
5
|
+
gem.authors = ["Tony Arcieri", "Erik Michaels-Ober", "Aleksey V. Zapparov"]
|
6
|
+
gem.email = ["bascule@gmail.com"]
|
7
7
|
|
8
|
-
gem.description = <<-DESCRIPTION.strip.gsub(/\s+/,
|
8
|
+
gem.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
9
9
|
An easy-to-use client library for making requests from Ruby.
|
10
10
|
It uses a simple method chaining system for building requests,
|
11
11
|
similar to Python's Requests.
|
12
12
|
DESCRIPTION
|
13
13
|
|
14
|
-
gem.summary =
|
15
|
-
gem.homepage =
|
16
|
-
gem.licenses = [
|
14
|
+
gem.summary = "HTTP should be easy"
|
15
|
+
gem.homepage = "https://github.com/httprb/http.rb"
|
16
|
+
gem.licenses = ["MIT"]
|
17
17
|
|
18
18
|
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
19
|
gem.files = `git ls-files`.split("\n")
|
20
20
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
-
gem.name =
|
22
|
-
gem.require_paths = [
|
21
|
+
gem.name = "http"
|
22
|
+
gem.require_paths = ["lib"]
|
23
23
|
gem.version = HTTP::VERSION
|
24
24
|
|
25
|
-
gem.add_runtime_dependency
|
26
|
-
gem.add_runtime_dependency
|
25
|
+
gem.add_runtime_dependency "http_parser.rb", "~> 0.6.0"
|
26
|
+
gem.add_runtime_dependency "http-form_data", "~> 1.0.0"
|
27
27
|
|
28
|
-
gem.add_development_dependency
|
28
|
+
gem.add_development_dependency "bundler", "~> 1.0"
|
29
29
|
end
|
data/lib/http.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
require
|
1
|
+
require "http/parser"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
3
|
+
require "http/errors"
|
4
|
+
require "http/chainable"
|
5
|
+
require "http/client"
|
6
|
+
require "http/connection"
|
7
|
+
require "http/options"
|
8
|
+
require "http/request"
|
9
|
+
require "http/request/writer"
|
10
|
+
require "http/response"
|
11
|
+
require "http/response/body"
|
12
|
+
require "http/response/parser"
|
12
13
|
|
13
14
|
# HTTP should be easy
|
14
15
|
module HTTP
|
data/lib/http/cache.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require "time"
|
2
|
+
require "rack-cache"
|
3
|
+
|
4
|
+
module HTTP
|
5
|
+
class Cache
|
6
|
+
# NoOp logger.
|
7
|
+
class NullLogger
|
8
|
+
def error(_msg = nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
def debug(_msg = nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def info(_msg = nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
def warn(_msg = nil)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Response] a cached response that is valid for the request or
|
22
|
+
# the result of executing the provided block
|
23
|
+
#
|
24
|
+
# @yield [request, options] on cache miss so that an actual
|
25
|
+
# request can be made
|
26
|
+
def perform(request, options, &request_performer)
|
27
|
+
req = request.caching
|
28
|
+
|
29
|
+
invalidate_cache(req) if req.invalidates_cache?
|
30
|
+
|
31
|
+
get_response(req, options, request_performer)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
# @return [Response] the response to the request, either from the
|
37
|
+
# cache or by actually making the request
|
38
|
+
def get_response(req, options, request_performer)
|
39
|
+
cached_resp = cache_lookup(req)
|
40
|
+
return cached_resp if cached_resp && !cached_resp.stale?
|
41
|
+
|
42
|
+
# cache miss
|
43
|
+
logger.debug { "Cache miss for <#{req.uri}>, making request" }
|
44
|
+
actual_req = if cached_resp
|
45
|
+
req.conditional_on_changes_to(cached_resp)
|
46
|
+
else
|
47
|
+
req
|
48
|
+
end
|
49
|
+
actual_resp = make_request(actual_req, options, request_performer)
|
50
|
+
|
51
|
+
handle_response(cached_resp, actual_resp, req)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @returns [Response] the most useful of the responses after
|
55
|
+
# updating the cache as appropriate
|
56
|
+
def handle_response(cached_resp, actual_resp, req)
|
57
|
+
if actual_resp.status.not_modified? && cached_resp
|
58
|
+
logger.debug { "<#{req.uri}> not modified, using cached version." }
|
59
|
+
cached_resp.validated!(actual_resp)
|
60
|
+
store_in_cache(req, cached_resp)
|
61
|
+
return cached_resp
|
62
|
+
|
63
|
+
elsif req.cacheable? && actual_resp.cacheable?
|
64
|
+
store_in_cache(req, actual_resp)
|
65
|
+
return actual_resp
|
66
|
+
|
67
|
+
else
|
68
|
+
return actual_resp
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [HTTP::Response::Caching] the actual response returned
|
73
|
+
# by request_performer
|
74
|
+
def make_request(req, options, request_performer)
|
75
|
+
req.sent_at = Time.now
|
76
|
+
|
77
|
+
request_performer.call(req, options).caching.tap do |res|
|
78
|
+
res.received_at = Time.now
|
79
|
+
res.requested_at = req.sent_at
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [HTTP::Response::Caching, nil] the cached response for the request
|
84
|
+
def cache_lookup(request)
|
85
|
+
return nil if request.skips_cache?
|
86
|
+
|
87
|
+
rack_resp = metastore.lookup(request, entitystore)
|
88
|
+
return if rack_resp.nil?
|
89
|
+
|
90
|
+
HTTP::Response.new(
|
91
|
+
rack_resp.status, "1.1", rack_resp.headers, stringify(rack_resp.body)
|
92
|
+
).caching
|
93
|
+
end
|
94
|
+
|
95
|
+
# Store response in cache
|
96
|
+
#
|
97
|
+
# @return [nil]
|
98
|
+
#
|
99
|
+
# ---
|
100
|
+
#
|
101
|
+
# We have to convert the response body in to a string body so
|
102
|
+
# that the cache store reading the body will not prevent the
|
103
|
+
# original requester from doing so.
|
104
|
+
def store_in_cache(request, response)
|
105
|
+
response.body = response.body.to_s
|
106
|
+
metastore.store(request, response, entitystore)
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
# Invalidate all response from the requested resource
|
111
|
+
#
|
112
|
+
# @return [nil]
|
113
|
+
def invalidate_cache(request)
|
114
|
+
metastore.invalidate(request, entitystore)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Inits a new instance
|
118
|
+
#
|
119
|
+
# @option opts [String] :metastore URL to the metastore location
|
120
|
+
# @option opts [String] :entitystore URL to the entitystore location
|
121
|
+
# @option opts [Logger] :logger logger to use
|
122
|
+
def initialize(opts)
|
123
|
+
@metastore = storage.resolve_metastore_uri(opts.fetch(:metastore))
|
124
|
+
@entitystore = storage.resolve_entitystore_uri(opts.fetch(:entitystore))
|
125
|
+
@logger = opts.fetch(:logger) { NullLogger.new }
|
126
|
+
end
|
127
|
+
|
128
|
+
attr_reader :metastore, :entitystore, :logger
|
129
|
+
|
130
|
+
def storage
|
131
|
+
@@storage ||= Rack::Cache::Storage.new # rubocop:disable Style/ClassVars
|
132
|
+
end
|
133
|
+
|
134
|
+
def stringify(body)
|
135
|
+
if body.respond_to?(:each)
|
136
|
+
"".tap do |buf|
|
137
|
+
body.each do |part|
|
138
|
+
buf << part
|
139
|
+
end
|
140
|
+
end
|
141
|
+
else
|
142
|
+
body.to_s
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|