rack-a_day_without 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +8 -0
- data/lib/rack/a_day_without/version.rb +5 -0
- data/lib/rack/a_day_without.rb +73 -0
- data/rack-a_day_without.gemspec +25 -0
- data/test/fixtures/index.html +2 -0
- data/test/minitest_helper.rb +5 -0
- data/test/test_rack_a_day_without.rb +140 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjIxNDM3NmRjZDI3Yjc0ZDc1ZDJjZDAyMWFhMzE5OWYxN2ZiZTFhOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZjNjMWM0ZjI1ZDhhNmEyMTc5NDg1YzA1Njc4MjE2OTY1NWE3ZDNjZA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
N2Q4ZDkyZDA4OWJhZmI2OGMxM2RhYzc3MTMyMDVmN2FiNDU5Zjg3NmU2NWQz
|
10
|
+
ZTM0ZGY2NDQzZGRmY2M4YzZmZTc4MzE3ODBjOTI5YjBhMjMwOTM3ZTM5Yjk2
|
11
|
+
NTdlYTJiNjJkNDQyOWQ3Y2M1OTgxYzljN2JmMDc4ZmY3ZDcwOWU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTBlYzQzMjJlNmZkYTAzYjZlZjk2MjZlNTkwM2JkOGVlNjJjMDRkNTAwMTBj
|
14
|
+
ODhkNTUzNmE4MTUwOGZjNTczNzJiZmQ4ZjRiMGY2OGNmNjUxOGFlMGE5Njhk
|
15
|
+
YWNjMmNhOGViOTE3ODM1MmM0ZmQxNzBkZmM2YTdmMThmMzhhZGI=
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jack Jennings
|
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,72 @@
|
|
1
|
+
# Rack::ADayWithout
|
2
|
+
|
3
|
+
`Rack::ADayWithout` is a middleware for Rack-based web applications, originally built to display alternate content for the [Day Without Art](https://en.wikipedia.org/wiki/Day_Without_Art).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rack-a_day_without', require: 'rack/a_day_without'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rack-a_day_without
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Use `Rack::ADayWithout` as a middleware in your Rack (or Rails) application. The `on` option must be set to the date the site should serve the alternate content.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
use Rack::ADayWithout, 'Art', on: '1/12/2014'
|
25
|
+
```
|
26
|
+
|
27
|
+
You can also use the alternate syntax which uses child-classes to set the `subject` of ADayWithout. This is equivalent to the above example:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
use Rack::ADayWithout::Art, on: '1/12/2014'
|
31
|
+
```
|
32
|
+
|
33
|
+
### Writing Content
|
34
|
+
|
35
|
+
By default, the middleware will write an empty content string for all requests on the specified day. If the `content` or `file` options are set, the content string or file contents will be written instead.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
use Rack::ADayWithout, 'Art', on: '1/12/2014', content: 'A Day Without Art'
|
39
|
+
# or...
|
40
|
+
use Rack::ADayWithout, 'Art', on: '1/12/2014', file: './public/index.html'
|
41
|
+
```
|
42
|
+
|
43
|
+
### Bypass Routes
|
44
|
+
|
45
|
+
The `bypass` option allows some routes to pass through the middleware without being blocked. This can be useful if you have an admin area that should still be available during the day without. `bypass` can be set to be a `String`, a `Regexp` or an `Array` of either.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
use Rack::ADayWithout, 'Art', on: '1/12/2014',
|
49
|
+
bypass: [/^\/admin/, '/about']
|
50
|
+
```
|
51
|
+
|
52
|
+
## With Rails
|
53
|
+
|
54
|
+
Load the rack middleware inside of `config/application.rb`:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
module YourApp
|
58
|
+
class Application < Rails::Application
|
59
|
+
# ...
|
60
|
+
|
61
|
+
config.middleware.use Rack::ADayWithout, 'Art', on: '22/11/2014'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
1. Fork it
|
69
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
70
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
71
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
72
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require "date"
|
2
|
+
require "rack"
|
3
|
+
require "rack/a_day_without/version"
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
class ADayWithout
|
7
|
+
|
8
|
+
def self.const_missing const_name
|
9
|
+
const_set const_name, self.new_subject_subclass
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.new_subject_subclass
|
13
|
+
Class.new(self) do
|
14
|
+
def initialize app, options = {}
|
15
|
+
subject = self.class.name.split('::').last
|
16
|
+
super app, subject, options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize app, subject, options = {}
|
22
|
+
@app = app
|
23
|
+
@subject = subject
|
24
|
+
@content = options[:content]
|
25
|
+
@file = options[:file]
|
26
|
+
@date = parse_date options[:on]
|
27
|
+
@allowed = parse_allowed_routes options[:bypass]
|
28
|
+
end
|
29
|
+
|
30
|
+
def call env
|
31
|
+
allowed = allowed_path? env['PATH_INFO']
|
32
|
+
if @date == Date.today && !allowed
|
33
|
+
res = Response.new
|
34
|
+
res["X-Day-Without"] = @subject
|
35
|
+
res.write content
|
36
|
+
res.finish
|
37
|
+
else
|
38
|
+
@app.call env
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def content
|
45
|
+
if @file
|
46
|
+
::File.read @file
|
47
|
+
else
|
48
|
+
@content.to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_allowed_routes allowed
|
53
|
+
if allowed.nil?
|
54
|
+
[]
|
55
|
+
elsif allowed.respond_to? :to_ary
|
56
|
+
allowed.to_ary || [allowed]
|
57
|
+
else
|
58
|
+
[allowed]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_date dateish
|
63
|
+
Date.parse dateish.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
def allowed_path? path
|
67
|
+
@allowed.any? do |a|
|
68
|
+
a.is_a?(Regexp) ? a.match(path.to_s) : a == path.to_s
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rack/a_day_without/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rack-a_day_without"
|
8
|
+
spec.version = Rack::ADayWithout::VERSION
|
9
|
+
spec.authors = ["Jack Jennings"]
|
10
|
+
spec.email = ["j@ckjennin.gs"]
|
11
|
+
spec.summary = %q{Rack middleware for serving alternate content on a given day}
|
12
|
+
spec.homepage = "http://github.com/jackjennings/rack-a_day_without"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "rack", "~> 1.4"
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake", "~> 0"
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.4"
|
25
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe Rack::ADayWithout do
|
4
|
+
|
5
|
+
it 'must have a version number' do
|
6
|
+
Rack::ADayWithout::VERSION.wont_be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'when used as middleware' do
|
10
|
+
before do
|
11
|
+
@app = Proc.new do
|
12
|
+
Rack::Response.new {|r| r.write 'Downstream app'}.finish
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'blocks a request' do
|
17
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.today
|
18
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
19
|
+
status.must_equal 200
|
20
|
+
body.body.must_equal ['']
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'passes a request' do
|
24
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new
|
25
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
26
|
+
status.must_equal 200
|
27
|
+
body.body.must_equal ['Downstream app']
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'blocks with supplied content' do
|
31
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
32
|
+
on: Date.today,
|
33
|
+
content: 'foobar'
|
34
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
35
|
+
status.must_equal 200
|
36
|
+
body.body.must_equal ['foobar']
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'blocks with supplied file' do
|
40
|
+
path = 'test/fixtures/index.html'
|
41
|
+
content = File.read(path)
|
42
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
43
|
+
on: Date.today,
|
44
|
+
file: path
|
45
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
46
|
+
status.must_equal 200
|
47
|
+
body.body.must_equal [content]
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'passes allowed routes' do
|
51
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
52
|
+
on: Date.today,
|
53
|
+
bypass: '/bar'
|
54
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
55
|
+
status.must_equal 200
|
56
|
+
body.body.must_equal ['Downstream app']
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'blocks sub-path of allowed routes' do
|
60
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
61
|
+
on: Date.today,
|
62
|
+
bypass: '/bar'
|
63
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/bar'))
|
64
|
+
status.must_equal 200
|
65
|
+
body.body.must_equal ['']
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'passes allowed routes as regexp' do
|
69
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
70
|
+
on: Date.today,
|
71
|
+
bypass: %r{^/bar}
|
72
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/baz'))
|
73
|
+
status.must_equal 200
|
74
|
+
body.body.must_equal ['Downstream app']
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'passes allowed routes as array' do
|
78
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
79
|
+
on: Date.today,
|
80
|
+
bypass: ['/bar', '/baz']
|
81
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
82
|
+
status.must_equal 200
|
83
|
+
body.body.must_equal ['Downstream app']
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'passes allowed routes as array with regexps' do
|
87
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
88
|
+
on: Date.today,
|
89
|
+
bypass: [%r{^/bar}, '/baz']
|
90
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/baz'))
|
91
|
+
status.must_equal 200
|
92
|
+
body.body.must_equal ['Downstream app']
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'sets HTTP header when blocked' do
|
96
|
+
endpoint = Rack::ADayWithout.new @app, 'Art',
|
97
|
+
on: Date.today
|
98
|
+
status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
|
99
|
+
headers['X-Day-Without'].must_equal 'Art'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'when initialized' do
|
104
|
+
it 'parses a date' do
|
105
|
+
date = '20/10/2014'
|
106
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: date
|
107
|
+
endpoint.instance_variable_get('@date').must_equal Date.parse(date)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'parses a date' do
|
111
|
+
date = '20/10/2014'
|
112
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: date
|
113
|
+
endpoint.instance_variable_get('@date').must_equal Date.parse(date)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'stores a subject' do
|
117
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new
|
118
|
+
endpoint.instance_variable_get('@subject').must_equal 'Art'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'stores allowed routes in array' do
|
122
|
+
endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new, bypass: 'foo'
|
123
|
+
endpoint.instance_variable_get('@allowed').must_equal ['foo']
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'when dynamically subclassed' do
|
128
|
+
it 'creates a subclass' do
|
129
|
+
endpoint = Rack::ADayWithout::Art
|
130
|
+
endpoint.name.must_equal "Rack::ADayWithout::Art"
|
131
|
+
endpoint.ancestors.must_include Rack::ADayWithout
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'store subject by name' do
|
135
|
+
endpoint = Rack::ADayWithout::Art.new @app, on: Date.today
|
136
|
+
endpoint.instance_variable_get('@subject').must_equal 'Art'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-a_day_without
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Jennings
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
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.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
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: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.4'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- j@ckjennin.gs
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/rack/a_day_without.rb
|
83
|
+
- lib/rack/a_day_without/version.rb
|
84
|
+
- rack-a_day_without.gemspec
|
85
|
+
- test/fixtures/index.html
|
86
|
+
- test/minitest_helper.rb
|
87
|
+
- test/test_rack_a_day_without.rb
|
88
|
+
homepage: http://github.com/jackjennings/rack-a_day_without
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.4.4
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Rack middleware for serving alternate content on a given day
|
112
|
+
test_files:
|
113
|
+
- test/fixtures/index.html
|
114
|
+
- test/minitest_helper.rb
|
115
|
+
- test/test_rack_a_day_without.rb
|