grape-cache_control 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ca6c5f044f7d2eea1ce13fcc06dced1d6439228b
4
+ data.tar.gz: fa6ef23c416140e45ef17c408470623340615045
5
+ SHA512:
6
+ metadata.gz: 95d528dd48d44fd98ca2108d0aa3de25c4a6dab206307db951e4bbdcf27424f326f0ac06c1288299e9f36c43a6e8883cd64d7a4b15a06e08f6df981622530185
7
+ data.tar.gz: 93e0af1de79521d38773f4aa9a6baf938a13680951cb509bc1fcd71c6e4a04a5a8bae4d94379a6c35161c2bbfef6f85808b031b875adba0fac14175fd502ee15
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ bin
data/.rubocop.yml ADDED
@@ -0,0 +1,24 @@
1
+ AllCops:
2
+ Includes:
3
+ - Rakefile
4
+ - Gemfile
5
+ Excludes:
6
+ - script/**
7
+ - vendor/**
8
+ - bin/**
9
+ LineLength:
10
+ Enabled: false
11
+ MethodLength:
12
+ Enabled: false
13
+ ClassLength:
14
+ Enabled: false
15
+ Documentation:
16
+ Enabled: false
17
+ Encoding:
18
+ Enabled: false
19
+ Blocks:
20
+ Enabled: false
21
+ AlignParameters:
22
+ Enabled: false
23
+ HashSyntax:
24
+ EnforcedStyle: ruby19
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - ruby-head
5
+ - jruby-head
6
+ - 2.1.0
7
+ - 2.0.0
8
+ - 1.9.3
9
+ - jruby-19mode
10
+ matrix:
11
+ fast_finish: true
12
+ allow_failures:
13
+ - rvm: ruby-head
14
+ - rvm: jruby-head
15
+ - rvm: jruby-19mode
16
+ notifications:
17
+ email: false
data/CHANGELOG.md ADDED
File without changes
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,44 @@
1
+ ## Contributing
2
+ In the spirit of [free software][free-sw], **everyone** is encouraged to help
3
+ improve this project.
4
+
5
+ [free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
6
+
7
+ Here are some ways *you* can contribute:
8
+
9
+ * by using alpha, beta, and prerelease versions
10
+ * by reporting bugs
11
+ * by suggesting new features
12
+ * by writing or editing documentation
13
+ * by writing specifications
14
+ * by writing code (**no patch is too small**: fix typos, add comments, clean up
15
+ inconsistent whitespace)
16
+ * by refactoring code
17
+ * by closing [issues][]
18
+ * by reviewing patches
19
+
20
+ [issues]: https://github.com/karlfreeman/grape-cache_control/issues
21
+
22
+ ## Submitting an Issue
23
+ We use the [GitHub issue tracker][issues] to track bugs and features. Before
24
+ submitting a bug report or feature request, check to make sure it hasn't
25
+ already been submitted. When submitting a bug report, please include a [Gist][]
26
+ that includes a stack trace and any details that may be necessary to reproduce
27
+ the bug, including your gem version, Ruby version, and operating system.
28
+ Ideally, a bug report should include a pull request with failing specs.
29
+
30
+ [gist]: https://gist.github.com/
31
+
32
+ ## Submitting a Pull Request
33
+ 1. [Fork the repository.][fork]
34
+ 2. [Create a topic branch.][branch]
35
+ 3. Add specs for your unimplemented feature or bug fix.
36
+ 4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
37
+ 5. Implement your feature or bug fix.
38
+ 6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
39
+ 7. Add, commit, and push your changes.
40
+ 8. [Submit a pull request.][pr]
41
+
42
+ [fork]: http://help.github.com/fork-a-repo/
43
+ [branch]: http://learn.github.com/p/branching.html
44
+ [pr]: http://help.github.com/send-pull-requests/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Karl Freeman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # Grape::CacheControl
2
+
3
+ `Cache-Control` and `Expires` helpers for [Grape][grape]
4
+
5
+ ## Installation
6
+
7
+ ```ruby
8
+ gem 'grape-cache_control', '~> 0.0.1'
9
+ ```
10
+
11
+ ```ruby
12
+ require 'grape/cache_control'
13
+ ```
14
+
15
+ ## Features / Usage Examples
16
+
17
+ ```ruby
18
+ # Cache-Control:public,max-age=900
19
+ cache_control :public, max_age: 900
20
+
21
+ # Cache-Control:public,no-store,max-age=900,s-maxage=86400
22
+ cache_control :public, :no_store, max_age: 900, s_maxage:86400
23
+
24
+ # Cache-Control:public,no-store,max-age=900,s-maxage=86400
25
+ cache_control :public, :no_store, max_age: (Time.now + 900), s_maxage: (Time.now + 86400)
26
+
27
+ # Cache-Control:private,must-revalidate,max=age=0
28
+ cache_control :private, :must_revalidate, max_age: 0
29
+
30
+ # Cache-Control:public,max-age=900
31
+ # Expires:Tue, 25 Feb 2014 12:00:00 GMT
32
+ expires 900, :public
33
+
34
+ # Cache-Control:private,no-cache,no-store,max-age=900
35
+ # Expires:Tue, 25 Feb 2014 12:00:00 GMT
36
+ expires (Time.now + 900), :private, :no_store
37
+ ```
38
+
39
+ ```ruby
40
+ class API < Grape::API
41
+
42
+ desc 'A completely random endpoint'
43
+ get '/very-random' do
44
+ # ensure proxy cache does not cache this
45
+ cache_control :no_cache
46
+ { very_random: Random.rand(100) }
47
+ end
48
+
49
+ desc 'An endpoint which rounds to the nearest 15 minutes'
50
+ get '/fairly-static' do
51
+ # cache for 15 minutes, publicly
52
+ cache_control :public, max_age: 900
53
+ { fairly_static: Time.at(Time.now.to_i - (Time.now.to_i % 900)) }
54
+ end
55
+
56
+ desc 'An endpoint which rounds to the nearest day'
57
+ get '/reasonably-static' do
58
+ # cache for 15 minutes, however allow the proxy cache to hold on to it a day
59
+ cache_control :public, max_age: 900, s_maxage 86400
60
+ { reasonably_static: Time.at(Time.now.to_i - (Time.now.to_i % 86400)) }
61
+ end
62
+
63
+ desc 'A very secure endpoint'
64
+ get '/your-bank-account-details' do
65
+ # explicitly don't store or cache this response and assume its immediately stale
66
+ cache_control :private, :must_revalidate, max_age: 0
67
+ { your_bank_account_details: '0000-0000-0000-0000' }
68
+ end
69
+
70
+ desc 'An endpoint which is sometimes private'
71
+ get '/sometimes-private' do
72
+ # cache for a minute but don't allow it to be stored
73
+ cache_control :no_store, max_age: 60
74
+ is_private = [true, false].sample
75
+ # then add its privacy status
76
+ cache_control is_private ? :public : :private
77
+ { sometimes_private: is_private }
78
+ end
79
+
80
+ desc 'An endpoint which expires based on some business logic'
81
+ get '/randomly-expiring' do
82
+ # publicy cache this
83
+ cache_control :public
84
+ random_future_expiry = Random.rand(60 * 60) + 60
85
+ is_expired = Time.now + random_future_expiry
86
+ # then merge add it's expiration later on
87
+ cache_control max_age: is_expired
88
+ { randomly_expiring: is_expired }
89
+ end
90
+
91
+ end
92
+ ```
93
+
94
+ Additional to the `cache_control` helper there is also an `expires` one too which augments cache_control as well as setting the `Expires` header
95
+
96
+ ```ruby
97
+ class API < Grape::API
98
+
99
+ desc 'An endpoint which rounds to the nearest 15 minutes'
100
+ get '/fairly-static' do
101
+ # cache for 15 minutes, publicly
102
+ expires 900, :public
103
+ { fairly_static: Time.at(Time.now.to_i - (Time.now.to_i % 900)) }
104
+ end
105
+
106
+ desc 'An endpoint which expires based on some business logic'
107
+ get '/randomly-expiring' do
108
+ is_expired = Time.now + Random.rand(60 * 60) + 60
109
+ # expire in some random future, publicly
110
+ expires is_expired, :public
111
+ { randomly_expiring: is_expired }
112
+ end
113
+
114
+ end
115
+ ```
116
+
117
+ ## Build & Dependency Status
118
+
119
+ [![Gem Version](https://badge.fury.io/rb/grape-cache_control.png)][gem]
120
+ [![Build Status](https://travis-ci.org/karlfreeman/grape-cache_control.png)][travis]
121
+ [![Code Quality](https://codeclimate.com/github/karlfreeman/grape-cache_control.png)][codeclimate]
122
+ [![Gittip](http://img.shields.io/gittip/karlfreeman.png)][gittip]
123
+
124
+ ## Supported Ruby Versions
125
+
126
+ This library aims to support and is [tested against][travis] the following Ruby
127
+ implementations:
128
+
129
+ * Ruby 2.1.0
130
+ * Ruby 2.0.0
131
+ * Ruby 1.9.3
132
+ * [JRuby][jruby]
133
+
134
+ # Credits
135
+
136
+ Inspiration:
137
+
138
+ - [Sinatra's Cache-Control / Expires](https://github.com/sinatra/sinatra/blob/faf2efc670bf4c6076c26d5234c577950c19b699/lib/sinatra/base.rb#L439-L492)
139
+
140
+ Cribbed:
141
+
142
+ - [Grape-Pagination](https://github.com/remind101/grape-pagination)
143
+
144
+ [gem]: https://rubygems.org/gems/grape-cache_control
145
+ [travis]: http://travis-ci.org/karlfreeman/grape-cache_control
146
+ [codeclimate]: https://codeclimate.com/github/karlfreeman/grape-cache_control
147
+ [gittip]: https://www.gittip.com/karlfreeman
148
+ [jruby]: http://www.jruby.org
149
+
150
+ [grape]: http://intridea.github.io/grape
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'yard'
6
+ YARD::Rake::YardocTask.new
7
+
8
+ require 'rspec/core/rake_task'
9
+ desc 'Run all examples'
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ require 'rubocop/rake_task'
13
+ desc 'Run rubocop'
14
+ Rubocop::RakeTask.new(:rubocop)
15
+
16
+ task default: :spec
17
+ task test: :spec
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'grape/cache_control/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'grape-cache_control'
8
+ spec.version = Grape::CacheControl::VERSION
9
+ spec.authors = ['Karl Freeman']
10
+ spec.email = ['karlfreeman@gmail.com']
11
+ spec.summary = %q{Cache-Control and Expires helpers for Grape}
12
+ spec.description = %q{Cache-Control and Expires helpers for Grape}
13
+ spec.homepage = 'https://github.com/karlfreeman/grape-cache_control'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+ spec.required_ruby_version = '>= 2.0.0'
21
+
22
+ spec.add_dependency 'grape', '~> 0.3'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.5'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rack-test'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'rubocop'
29
+ spec.add_development_dependency 'timecop'
30
+ spec.add_development_dependency 'pry'
31
+ spec.add_development_dependency 'yard'
32
+
33
+ end
34
+
35
+
@@ -0,0 +1 @@
1
+ require 'grape/cache_control'
@@ -0,0 +1,82 @@
1
+ require 'grape'
2
+ require 'grape/cache_control/version'
3
+
4
+ module Grape
5
+ module CacheControl
6
+ autoload :Helpers, 'grape/cache_control/helpers'
7
+ Grape::Endpoint.send :include, Grape::CacheControl::Helpers
8
+
9
+ CACHE_CONTROL = 'Cache-Control'.freeze
10
+ EXPIRES = 'Expires'.freeze
11
+ TRUE = 'true'.freeze
12
+ SETTABLE_DIRECTIVES = [:max_age, :s_maxage].freeze
13
+ TRUTHY_DIRECTIVES = [:public, :private, :no_cache, :no_store, :no_transform, :must_revalidate, :proxy_revalidate].freeze
14
+ ALL_DIRECTIVES = (TRUTHY_DIRECTIVES | SETTABLE_DIRECTIVES).freeze
15
+
16
+ ALL_DIRECTIVES.each do |d|
17
+ const_set(d.upcase, d.to_s.tr('_', '-'))
18
+ end
19
+
20
+ class << self
21
+ def cache_control(request, *values)
22
+ cc_directives = {}
23
+
24
+ (cache_control_segments(request.header(CACHE_CONTROL)) | cache_control_values(*values)).each do |segment|
25
+ directive, argument = segment.split('=', 2)
26
+ cc_directives[directive.tr('-', '_').to_sym] = argument || true
27
+ end
28
+
29
+ if !cc_directives.empty?
30
+ cc_header = []
31
+ cc_directives.delete(:public) if cc_directives.key? :private
32
+ cc_directives.delete(:private) if cc_directives.key? :public
33
+ cc_directives.each do |k, v|
34
+ if SETTABLE_DIRECTIVES.include?(k)
35
+ cc_header << "#{Grape::CacheControl.const_get(k.upcase)}=#{v.to_i}"
36
+ elsif TRUTHY_DIRECTIVES.include?(k) && v == TRUE
37
+ cc_header << Grape::CacheControl.const_get(k.upcase)
38
+ end
39
+ end
40
+ request.header(CACHE_CONTROL, cc_header.join(', '))
41
+ end
42
+ end
43
+
44
+ def expires(request, amount, *values)
45
+ if amount.is_a? Integer
46
+ time = Time.now + amount.to_i
47
+ max_age = amount
48
+ else
49
+ time = amount
50
+ max_age = time - Time.now
51
+ end
52
+
53
+ values << { max_age: max_age }
54
+ request.header(EXPIRES, time.httpdate)
55
+ cache_control(request, *values)
56
+ end
57
+
58
+ private
59
+
60
+ def cache_control_values(*values)
61
+ cache_control_values = []
62
+ values.each do |value|
63
+ if value.is_a? Hash
64
+ cache_control_values.concat value.map { |k, v|
65
+ argument = v.is_a?(Time) ? v - Time.now : v
66
+ "#{Grape::CacheControl.const_get(k.upcase)}=#{argument}"
67
+ }
68
+ elsif value.is_a? Symbol
69
+ cache_control_values << "#{value}=#{TRUE}"
70
+ end
71
+ end
72
+ cache_control_values
73
+ end
74
+
75
+ def cache_control_segments(header = nil)
76
+ segments = []
77
+ segments.concat header.delete(' ').split(',') unless header.nil?
78
+ segments
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,13 @@
1
+ module Grape
2
+ module CacheControl
3
+ module Helpers
4
+ def cache_control(*args)
5
+ Grape::CacheControl.cache_control(self, *args)
6
+ end
7
+
8
+ def expires(amount, *values)
9
+ Grape::CacheControl.expires(self, amount, *values)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Grape
2
+ module CacheControl
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'bundler'
4
+ Bundler.setup
5
+
6
+ %w(support).each do |dir|
7
+ Dir.glob(File.expand_path("../#{dir}/**/*.rb", __FILE__), &method(:require))
8
+ end
9
+
10
+ require 'grape-cache_control'
11
+
12
+ RSpec.configure do |config|
13
+ config.expect_with :rspec do |c|
14
+ c.syntax = :expect
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby'
2
+ require 'pry' unless ENV['CI']
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'rack/test'
2
+ RSpec.configure do |config|
3
+ config.include Rack::Test::Methods
4
+ end
@@ -0,0 +1,9 @@
1
+ require 'timecop'
2
+ RSpec.configure do |config|
3
+ config.before(:each) do
4
+ Timecop.freeze
5
+ end
6
+ config.after(:each) do
7
+ Timecop.return
8
+ end
9
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe Grape::CacheControl do
4
+ subject { Class.new(Grape::API) }
5
+
6
+ def app
7
+ subject
8
+ end
9
+
10
+ context 'helpers' do
11
+
12
+ describe 'cache_control' do
13
+ it 'sets headers' do
14
+ subject.get('/apples') do
15
+ cache_control :public, max_age: 60.0
16
+ end
17
+
18
+ get 'apples'
19
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('public', 'max-age=60')
20
+ end
21
+
22
+ it 'treats symbols as true and hash keys with true values the same' do
23
+ subject.get('/pears') do
24
+ cache_control :public, no_cache: true
25
+ end
26
+
27
+ get 'pears'
28
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('public', 'no-cache')
29
+ end
30
+
31
+ it 'merges previous cache_control headers' do
32
+ subject.get('/grapes') do
33
+ cache_control :public, max_age: 60, s_maxage: 30
34
+ cache_control :private
35
+ end
36
+
37
+ get 'grapes'
38
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('private', 'max-age=60', 's-maxage=30')
39
+ end
40
+
41
+ it 'allows removal of previous headers by setting a hash keys value as false' do
42
+ subject.get('/pears') do
43
+ cache_control :public, no_cache: true
44
+ cache_control :private, no_cache: false
45
+ end
46
+
47
+ get 'pears'
48
+ expect(last_response.headers['Cache-Control'].split(', ')).to_not include('no-cache')
49
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('private')
50
+ end
51
+
52
+ it 'ignores unsettable directives' do
53
+ subject.get('/cherrys') do
54
+ cache_control public: 60, max_age: 60
55
+ end
56
+
57
+ get 'cherrys'
58
+ expect(last_response.headers['Cache-Control'].split(', ')).to_not include('public')
59
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('max-age=60')
60
+ end
61
+
62
+ it 'converts Time based values to Integers' do
63
+ subject.get('/blueberries') do
64
+ cache_control :public, max_age: (Time.now + 60)
65
+ end
66
+
67
+ get 'blueberries'
68
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('public', 'max-age=60')
69
+ end
70
+
71
+ end
72
+
73
+ describe 'expires' do
74
+ it 'sets Expires header and passes along Cache-Control values' do
75
+ subject.get('/grapefruits') do
76
+ expires 60, :public, :no_cache
77
+ end
78
+
79
+ get 'grapefruits'
80
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('max-age=60', 'public', 'no-cache')
81
+ expect(last_response.headers['Expires']).to eq((Time.now + 60).httpdate)
82
+ end
83
+
84
+ it 'allows Time to be specified as the expiry' do
85
+ subject.get('/grapefruits') do
86
+ expires((Time.now + 60), :public, :no_cache)
87
+ end
88
+
89
+ get 'grapefruits'
90
+ expect(last_response.headers['Cache-Control'].split(', ')).to include('max-age=60', 'public', 'no-cache')
91
+ expect(last_response.headers['Expires']).to eq((Time.now + 60).httpdate)
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grape-cache_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Karl Freeman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: grape
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
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
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Cache-Control and Expires helpers for Grape
140
+ email:
141
+ - karlfreeman@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - .gitignore
147
+ - .rubocop.yml
148
+ - .travis.yml
149
+ - CHANGELOG.md
150
+ - CONTRIBUTING.md
151
+ - Gemfile
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - grape-cache_control.gemspec
156
+ - lib/grape-cache_control.rb
157
+ - lib/grape/cache_control.rb
158
+ - lib/grape/cache_control/helpers.rb
159
+ - lib/grape/cache_control/version.rb
160
+ - spec/spec_helper.rb
161
+ - spec/support/pry.rb
162
+ - spec/support/rack-test.rb
163
+ - spec/support/timecop.rb
164
+ - spec/unit/grape/cache_control_spec.rb
165
+ homepage: https://github.com/karlfreeman/grape-cache_control
166
+ licenses:
167
+ - MIT
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - '>='
176
+ - !ruby/object:Gem::Version
177
+ version: 2.0.0
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 2.0.14
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: Cache-Control and Expires helpers for Grape
189
+ test_files:
190
+ - spec/spec_helper.rb
191
+ - spec/support/pry.rb
192
+ - spec/support/rack-test.rb
193
+ - spec/support/timecop.rb
194
+ - spec/unit/grape/cache_control_spec.rb
195
+ has_rdoc: