shack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data/.gitignore +14 -0
- data/.travis.yml +6 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +88 -0
- data/Rakefile +26 -0
- data/certs/pjaspers.pem +19 -0
- data/checksum/shack-0.0.1.sha512 +1 -0
- data/lib/shack/middleware.rb +55 -0
- data/lib/shack/railtie.rb +37 -0
- data/lib/shack/stamp.rb +40 -0
- data/lib/shack/version.rb +3 -0
- data/lib/shack.rb +8 -0
- data/shack.gemspec +24 -0
- data/test/benchmark.rb +32 -0
- data/test/helper.rb +10 -0
- data/test/middleware_test.rb +104 -0
- data/test/shack_test.rb +7 -0
- data/test/stamp_test.rb +35 -0
- data.tar.gz.sig +0 -0
- metadata +102 -0
- metadata.gz.sig +2 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3439a99a117ab934230a8199f7c1da49af7fd4e1
|
4
|
+
data.tar.gz: 9d98564d1a5228650b947f2f54c5c01228355b0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1bbf218b69895d33c2066dd9cee1c4d568efdd199defb82683430c3d1aec8a436ac6101f2810c7cb533471042d7d3d85a77bf89d773678e9eb6f6307fb4bfa5f
|
7
|
+
data.tar.gz: e6f1d2e3784bc9b089912f908c1200953ef4e0dc08f8fe271a5798a4f440a68627e6df3145ffe40ab34c59b082626862b7420b7688cbdd2b02f5131350b061ad
|
checksums.yaml.gz.sig
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in shack.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem "pry", "~> 0.9.12.6"
|
8
|
+
gem "rack", "~> 1.5.2"
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
# Adding rake for Travis.
|
13
|
+
gem "rake"
|
14
|
+
gem "minitest", "~> 5.4.3"
|
15
|
+
gem "mocha", "~> 1.1.0"
|
16
|
+
gem "benchmark-ips", "~> 2.1.0"
|
17
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 pjaspers
|
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,88 @@
|
|
1
|
+
# Shack
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/pjaspers/shack.svg?branch=master)](https://travis-ci.org/pjaspers/shack)
|
4
|
+
|
5
|
+
A `Rack` middleware that will add a unique identifier (`sha`) to the application. It will set a custom header (`X-Shack-Sha`) containing the sha and will automagically insert a small banner in the HTML.
|
6
|
+
|
7
|
+
![Shack in action](http://cl.ly/image/2F1w1E0G2C3R/Screen%20Shot%202014-12-01%20at%2000.47.23.png)
|
8
|
+
|
9
|
+
```
|
10
|
+
❯ curl -I kkez.dev
|
11
|
+
HTTP/1.1 200 OK
|
12
|
+
Server: nginx/1.6.1
|
13
|
+
Date: Sun, 30 Nov 2014 23:49:10 GMT
|
14
|
+
Content-Type: text/html;charset=utf-8
|
15
|
+
Content-Length: 491
|
16
|
+
Connection: keep-alive
|
17
|
+
X-Shack-Sha: 39aee4f
|
18
|
+
```
|
19
|
+
|
20
|
+
This way you can always be certain which version of your app is currently running, especially handy in staging environments.
|
21
|
+
If you don't supply a `sha` nothing will happen (so for example if you use an `ENV` variable containing the sha and don't set it in production, no one will be any wiser).
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
For a rack app:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require "shack"
|
29
|
+
|
30
|
+
app = Rack::Builder.new do
|
31
|
+
use Shack::Middleware, ENV["SHA"]
|
32
|
+
run -> (env) { [200, {"Content-Type" => "text/html", ["<html><body>KAAAHN</body></html>"]]
|
33
|
+
end
|
34
|
+
|
35
|
+
Rack::Server.start app: app
|
36
|
+
```
|
37
|
+
|
38
|
+
If your rack app happens to be a Rails app:
|
39
|
+
|
40
|
+
Add `shack` to your Gemfile, and specify how to get the hash in an initializer (`config/initializers/shack.rb`)
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Shack::Middleware.configure do |shack|
|
44
|
+
shack.sha = File.open("BUILD_NUMBER").read.strip
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
And since it's Rails, it can also be done automagically if a file called `REVISION` is found in the root of your project. No initializer required. Note: by default it won't show the banner in production environments, because that just feels wrong.
|
49
|
+
|
50
|
+
## Configuration
|
51
|
+
|
52
|
+
You can either set the sha directly:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Shack::Middleware.configure do |shack|
|
56
|
+
shack.sha = File.open("REVISION").read.strip
|
57
|
+
shack.hide_stamp = true # this will hide the banner
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Or you can set the string to show in the HTML banner (with `{{sha}}` being a special variable which will be replaced with the sha):
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
Shack::Middleware.configure do |shack|
|
65
|
+
shack.sha = File.open("REVISION").read.strip
|
66
|
+
shack.content = "#{Rails.env} - <a href="https://github.com/shack/commit/{{sha}}>{{sha}}</a>"
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
## How do I set the sha?
|
71
|
+
|
72
|
+
Either write it to a `REVISION` file on deploy (Capistrano used to this by default, now you can [add a task](https://github.com/capistrano/capistrano/pull/757), in `mina` I'm waiting on this [pull request](https://github.com/mina-deploy/mina/pull/260)), or set an `ENV` variable containing the sha.
|
73
|
+
|
74
|
+
Now you can set the sha in the configure block.
|
75
|
+
|
76
|
+
## Signed gem
|
77
|
+
|
78
|
+
`shack` is cryptographically signed. To be sure the gem you install hasn’t been tampered with:
|
79
|
+
|
80
|
+
1. Download certificate https://raw.github.com/pjaspers/shack/certs/pjaspers.pem
|
81
|
+
2. Add `gem cert –add pjaspers.pem`
|
82
|
+
3. gem install shack -P HighSecurity
|
83
|
+
|
84
|
+
## Contributing
|
85
|
+
|
86
|
+
0. Fork it ( https://github.com/pjaspers/shack/fork )
|
87
|
+
1. Create a new Pull Request
|
88
|
+
2. Technology.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
task :test do
|
4
|
+
$LOAD_PATH.unshift('lib', 'test')
|
5
|
+
Dir.glob('./test/**/*_test.rb') { |f| require f }
|
6
|
+
end
|
7
|
+
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
task :console do
|
11
|
+
require 'pry'
|
12
|
+
require './lib/shack'
|
13
|
+
ARGV.clear
|
14
|
+
Pry.start Shack
|
15
|
+
end
|
16
|
+
|
17
|
+
task :checksum do
|
18
|
+
require 'digest/sha2'
|
19
|
+
abort_with_error "Set 'GEM' with name-0.x.x to calculate checksum" unless ENV["GEM"]
|
20
|
+
name = ENV["GEM"]
|
21
|
+
built_gem_path = "pkg/#{name}.gem"
|
22
|
+
checksum = Digest::SHA512.new.hexdigest(File.read(built_gem_path))
|
23
|
+
checksum_path = "checksum/#{name}.sha512"
|
24
|
+
File.open(checksum_path, 'w' ) {|f| f.write(checksum) }
|
25
|
+
puts "Wrote checksum to #{checksum_path}"
|
26
|
+
end
|
data/certs/pjaspers.pem
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDKDCCAhCgAwIBAgIBADANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARwaWV0
|
3
|
+
MRUwEwYKCZImiZPyLGQBGRYFamFzcGUxEjAQBgoJkiaJk/IsZAEZFgJyczAeFw0x
|
4
|
+
NDA0MDcyMTQyMDNaFw0xNTA0MDcyMTQyMDNaMDoxDTALBgNVBAMMBHBpZXQxFTAT
|
5
|
+
BgoJkiaJk/IsZAEZFgVqYXNwZTESMBAGCgmSJomT8ixkARkWAnJzMIIBIjANBgkq
|
6
|
+
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+SQ5IzhMaUM/jrUBAP5l0/Z5ttLQb2lT
|
7
|
+
hotS1Yraz3hclbGhBhDcQilW11GSftUbWhaiMQwNXqaEN9ctmzE5JukOdwhtNSLq
|
8
|
+
IDw+TEEXbg/VImlFhryg9vunffPeOBUlnxdY484DOushNN50H/LA+jAoFST3+oZq
|
9
|
+
CXuA3yFi8ZTPqhHrEn1bkycUfLX+TOm07ZfCPly9fAVYhOYaVaPeYkHAO83+Ic63
|
10
|
+
9YGqD1sFeZ7hfSxqfYEBxpiM0+qztqHCVNrehkzX2oUmY06eVpSu2mzLYmcCD58f
|
11
|
+
inVDRBe/3ygkACxZCA7pjIuqHOpKxSbYMrgEkrAtpA7lkIMaveMY9QIDAQABozkw
|
12
|
+
NzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSSJbKSj/62BYq/1utxyqsShRum8jALBgNV
|
13
|
+
HQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAJkG60vFt/GBuMvTdMtFCw4jJiRo
|
14
|
+
8n6dMQrL2kZdD0ZNeidLfTMzhflv+9ZrWfcFWzfqaGgKJckBd2wlfQiR78ts9zom
|
15
|
+
bX9B9n/Ad32womLnb0aeTuEHX6Vy4qs4zl+VnXy4g1NQ2lfcnksUsjBM8v8GYTjy
|
16
|
+
ssiOQnzrWxNyjR01uY5g/ON/IlRKNpihe7Qze1oGWdopZP6Lwfhir5ShbDETCKQv
|
17
|
+
CuJWUOdBRsHbSraLW8n/vc/fZGqVzDAghs26bxmwicw+4/VgO2soYka81t8pUuG6
|
18
|
+
vLWWrtmIv8+cmMgvltP5AR5j2oYHYPPA9YFXuO9t1JVqJiNHm9JNRseEoBc=
|
19
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1 @@
|
|
1
|
+
93a208b532503937bc5399e4f36432f46e2c2f3e1da84f107c8e2ff858660953ca017dda4cc22a54d5d48bec4ab2cc9d4bda1c909eb9d103dd8134df0cf14f91
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Shack
|
2
|
+
class Middleware
|
3
|
+
HEADER_NAME = "X-Shack-Sha".freeze
|
4
|
+
|
5
|
+
def initialize(app, sha = "")
|
6
|
+
@app = app
|
7
|
+
@sha = sha unless (sha || "").empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
status, headers, body = @app.call(env)
|
12
|
+
return [status, headers, body] unless sha
|
13
|
+
headers[HEADER_NAME] = sha
|
14
|
+
|
15
|
+
if result = inject_stamp(status, headers, body)
|
16
|
+
result
|
17
|
+
else
|
18
|
+
[status, headers, body]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def inject_stamp(status, headers, body)
|
23
|
+
return nil if !!self.class.hide_stamp
|
24
|
+
return nil unless Stamp.stampable?(headers)
|
25
|
+
response = Rack::Response.new([], status, headers)
|
26
|
+
|
27
|
+
if String === body
|
28
|
+
response.write stamped(body)
|
29
|
+
else
|
30
|
+
body.each do |fragment|
|
31
|
+
response.write stamped(fragment)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
body.close if body.respond_to? :close
|
35
|
+
response.finish
|
36
|
+
end
|
37
|
+
|
38
|
+
# Initialiser over class-sha.
|
39
|
+
def sha
|
40
|
+
@sha || self.class.sha
|
41
|
+
end
|
42
|
+
|
43
|
+
def stamped(body)
|
44
|
+
Stamp.new(body, sha, self.class.content).result
|
45
|
+
end
|
46
|
+
|
47
|
+
class << self
|
48
|
+
attr_accessor :sha, :content, :hide_stamp
|
49
|
+
|
50
|
+
def configure(&block)
|
51
|
+
block.call(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Shack
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "shack.configure_rails_initialization" do |app|
|
4
|
+
ShackRails.new(app).inject!
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class ShackRails
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def inject!
|
14
|
+
if Rails.env.production?
|
15
|
+
# Don't show the stamp in production, but do add it to the headers
|
16
|
+
Shack::Middleware.configure do |shack|
|
17
|
+
shack.hide_stamp = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if fetch_sha_from_file?
|
22
|
+
Shack::Middleware.configure do |shack|
|
23
|
+
shack.sha = File.open(revision_file).read.strip
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@app.middleware.use(Shack::Middleware)
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch_sha_from_file?
|
30
|
+
Shack::Middleware.sha.blank? && File.exist?(revision_file)
|
31
|
+
end
|
32
|
+
|
33
|
+
def revision_file
|
34
|
+
File.join(Rails.root, "REVISION")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/shack/stamp.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Shack
|
2
|
+
# Takes the body and adds a stamp to it, containing the supplied content.
|
3
|
+
# At the moment, it's just a red div with white text.
|
4
|
+
class Stamp
|
5
|
+
# body - original body
|
6
|
+
# content - gets added to view
|
7
|
+
def initialize(body, sha, custom_content = nil)
|
8
|
+
@body = body
|
9
|
+
@sha = sha
|
10
|
+
@custom_content = custom_content if custom_content
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.stampable?(headers)
|
14
|
+
!!(headers["Content-Type"] =~ %r{text/html})
|
15
|
+
end
|
16
|
+
|
17
|
+
def result
|
18
|
+
@body.gsub!("</body>", html + "</body>")
|
19
|
+
@body
|
20
|
+
end
|
21
|
+
|
22
|
+
def content
|
23
|
+
if @custom_content
|
24
|
+
@custom_content.gsub("{{sha}}", @sha)
|
25
|
+
else
|
26
|
+
@sha
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def html
|
31
|
+
<<HTML
|
32
|
+
<div id="sha-stamp" style="position: fixed; bottom: 0; right: 0; height: 16px; background: rgb(0, 0, 0) transparent; background-color: rgba(0, 0, 0, 0.2); padding: 0 5px; border-top-left-radius: 5px;">
|
33
|
+
<span style="text-align: center;">
|
34
|
+
<small style="color: white; font-weight: normal;font-size: 12px;">#{content}</small>
|
35
|
+
</span>
|
36
|
+
</div>
|
37
|
+
HTML
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/shack.rb
ADDED
data/shack.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'shack/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "shack"
|
8
|
+
spec.version = Shack::VERSION
|
9
|
+
spec.authors = ["pjaspers"]
|
10
|
+
spec.email = ["piet@jaspe.rs"]
|
11
|
+
spec.summary = %q{Sha + Rack = Shack }
|
12
|
+
spec.description = %q{Rack middleware to expose a potential sha}
|
13
|
+
spec.homepage = ""
|
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.cert_chain = ['certs/pjaspers.pem']
|
21
|
+
spec.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
end
|
data/test/benchmark.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "rack"
|
3
|
+
require "shack"
|
4
|
+
require "benchmark/ips"
|
5
|
+
|
6
|
+
# Idea from [here](http://www.schneems.com/2014/10/31/benchmarking-rack-middleware.html)
|
7
|
+
# Thanks @schneems
|
8
|
+
noop = -> (_env) { [200, { "Content-Type" => "text/html" }, ["hello"]] }
|
9
|
+
middleware = Shack::Middleware.new(noop, "abc123")
|
10
|
+
|
11
|
+
request = Rack::MockRequest.new(middleware)
|
12
|
+
noop_request = Rack::MockRequest.new(noop)
|
13
|
+
|
14
|
+
Benchmark.ips do |x|
|
15
|
+
x.config(time: 5, warmup: 5)
|
16
|
+
x.report("With Shack") { request.get("/") }
|
17
|
+
x.report("With noop") { noop_request.get("/") }
|
18
|
+
x.compare!
|
19
|
+
end
|
20
|
+
|
21
|
+
# Current results:
|
22
|
+
#
|
23
|
+
# Calculating -------------------------------------
|
24
|
+
# With Shack 205.000 i/100ms
|
25
|
+
# With noop 446.000 i/100ms
|
26
|
+
# -------------------------------------------------
|
27
|
+
# With Shack 2.522k (±23.8%) i/s - 10.455k
|
28
|
+
# With noop 6.528k (±21.5%) i/s - 28.098k
|
29
|
+
#
|
30
|
+
# Comparison:
|
31
|
+
# With noop: 6528.4 i/s
|
32
|
+
# With Shack: 2521.7 i/s - 2.59x slower
|
data/test/helper.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require "helper.rb"
|
2
|
+
require "rack/mock"
|
3
|
+
|
4
|
+
describe Shack::Middleware do
|
5
|
+
before do
|
6
|
+
@app = ->(env) { [200, env, "app"] }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "without a sha" do
|
10
|
+
before do
|
11
|
+
@middleware = Shack::Middleware.new(@app, "")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't break the original app" do
|
15
|
+
status, _, _ = @middleware.call(fake_env("http://something.com"))
|
16
|
+
assert_equal status, 200
|
17
|
+
end
|
18
|
+
|
19
|
+
it "doesn't set a header" do
|
20
|
+
_, headers, _ = @middleware.call(fake_env("http://something.com"))
|
21
|
+
assert_nil headers[Shack::Middleware::HEADER_NAME]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "with a sha" do
|
26
|
+
before do
|
27
|
+
@sha = "abc123def4"
|
28
|
+
@middleware = Shack::Middleware.new(@app, @sha)
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
Shack::Middleware.configure do |shack|
|
33
|
+
shack.sha = nil
|
34
|
+
shack.content = nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "doesn't break the original app" do
|
39
|
+
status, _, _ = @middleware.call(fake_env("http://something.com"))
|
40
|
+
assert_equal status, 200
|
41
|
+
end
|
42
|
+
|
43
|
+
it "sets the header to the sha" do
|
44
|
+
_, headers, _ = @middleware.call(fake_env("http://something.com"))
|
45
|
+
assert_equal @sha, headers[Shack::Middleware::HEADER_NAME]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "injecting html" do
|
50
|
+
it "adds a stamp if content-type is text/html" do
|
51
|
+
app = ->(_) { [200, { "Content-Type" => "text/html" }, fake_page] }
|
52
|
+
middleware = Shack::Middleware.new(app, "Rollo Tomassi")
|
53
|
+
_, _, response = middleware.call(fake_env("http://something.com"))
|
54
|
+
assert_match(/Rollo Tomassi/, response.body.first)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ".configure" do
|
59
|
+
after do
|
60
|
+
Shack::Middleware.configure do |shack|
|
61
|
+
shack.sha = nil
|
62
|
+
shack.content = nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "can set a sha" do
|
67
|
+
Shack::Middleware.configure { |s| s.sha = "O'Sullivan" }
|
68
|
+
assert_equal Shack::Middleware.sha, "O'Sullivan"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "favors the initialized sha over the configured one" do
|
72
|
+
Shack::Middleware.configure { |s| s.sha = "O'Sullivan" }
|
73
|
+
app = ->(_) { [200, { "Content-Type" => "text/html" }, fake_page] }
|
74
|
+
s = Shack::Middleware.new(app, "The Rocket")
|
75
|
+
assert_equal s.sha, "The Rocket"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "can set a custom content string" do
|
79
|
+
string = "O'Sullivan - http://bbc.co.uk/{{sha}}"
|
80
|
+
Shack::Middleware.configure do |s|
|
81
|
+
s.content = string
|
82
|
+
end
|
83
|
+
assert_equal Shack::Middleware.content, string
|
84
|
+
end
|
85
|
+
|
86
|
+
it "sets the stamp with the configuration" do
|
87
|
+
app = ->(_) { [200, { "Content-Type" => "text/html" }, fake_page] }
|
88
|
+
Shack::Middleware.configure do |s|
|
89
|
+
s.sha = "abc123"
|
90
|
+
s.content = "Ronnie The Rocket - {{sha}}"
|
91
|
+
end
|
92
|
+
middleware = Shack::Middleware.new(app)
|
93
|
+
_, _, response = middleware.call(fake_env("http://something.com"))
|
94
|
+
assert_match(/Ronnie The Rocket - abc123/, response.body.first)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
def fake_page
|
98
|
+
"<html><body></body></html>"
|
99
|
+
end
|
100
|
+
|
101
|
+
def fake_env(url, options = {})
|
102
|
+
Rack::MockRequest.env_for(url, options)
|
103
|
+
end
|
104
|
+
end
|
data/test/shack_test.rb
ADDED
data/test/stamp_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require "helper.rb"
|
2
|
+
require "rack/mock"
|
3
|
+
|
4
|
+
describe Shack::Stamp do
|
5
|
+
describe ".stampable?" do
|
6
|
+
{"text/html" => true, "application/json" => false, "text/plain" => false}.each do |content_type, stampable|
|
7
|
+
in_words = stampable ? "stampable" : "unstampable"
|
8
|
+
it "#{content_type} is #{in_words}" do
|
9
|
+
assert_equal stampable, Shack::Stamp.stampable?("Content-Type" => content_type)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "stamping" do
|
15
|
+
it "should do nothing if no </body> found" do
|
16
|
+
s = Shack::Stamp.new("something", "Jack Vincennes")
|
17
|
+
assert_equal "something", s.result
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should add content if </body> found" do
|
21
|
+
s = Shack::Stamp.new("<html><body></body></html>", "Jack Vincennes")
|
22
|
+
assert_match(/Jack Vincennes/, s.result)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should use custom_content if provided" do
|
26
|
+
s = Shack::Stamp.new("<html><body></body></html>", "Jack Vincennes", "Rollo Tomassi")
|
27
|
+
assert_match(/Rollo Tomassi/, s.result)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should use sha in custom_content if provided" do
|
31
|
+
s = Shack::Stamp.new("<html><body></body></html>", "Jack Vincennes", "Rollo Tomassi said {{sha}}")
|
32
|
+
assert_match(/Rollo Tomassi said Jack Vincennes/, s.result)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- pjaspers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDKDCCAhCgAwIBAgIBADANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARwaWV0
|
14
|
+
MRUwEwYKCZImiZPyLGQBGRYFamFzcGUxEjAQBgoJkiaJk/IsZAEZFgJyczAeFw0x
|
15
|
+
NDA0MDcyMTQyMDNaFw0xNTA0MDcyMTQyMDNaMDoxDTALBgNVBAMMBHBpZXQxFTAT
|
16
|
+
BgoJkiaJk/IsZAEZFgVqYXNwZTESMBAGCgmSJomT8ixkARkWAnJzMIIBIjANBgkq
|
17
|
+
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+SQ5IzhMaUM/jrUBAP5l0/Z5ttLQb2lT
|
18
|
+
hotS1Yraz3hclbGhBhDcQilW11GSftUbWhaiMQwNXqaEN9ctmzE5JukOdwhtNSLq
|
19
|
+
IDw+TEEXbg/VImlFhryg9vunffPeOBUlnxdY484DOushNN50H/LA+jAoFST3+oZq
|
20
|
+
CXuA3yFi8ZTPqhHrEn1bkycUfLX+TOm07ZfCPly9fAVYhOYaVaPeYkHAO83+Ic63
|
21
|
+
9YGqD1sFeZ7hfSxqfYEBxpiM0+qztqHCVNrehkzX2oUmY06eVpSu2mzLYmcCD58f
|
22
|
+
inVDRBe/3ygkACxZCA7pjIuqHOpKxSbYMrgEkrAtpA7lkIMaveMY9QIDAQABozkw
|
23
|
+
NzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSSJbKSj/62BYq/1utxyqsShRum8jALBgNV
|
24
|
+
HQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAJkG60vFt/GBuMvTdMtFCw4jJiRo
|
25
|
+
8n6dMQrL2kZdD0ZNeidLfTMzhflv+9ZrWfcFWzfqaGgKJckBd2wlfQiR78ts9zom
|
26
|
+
bX9B9n/Ad32womLnb0aeTuEHX6Vy4qs4zl+VnXy4g1NQ2lfcnksUsjBM8v8GYTjy
|
27
|
+
ssiOQnzrWxNyjR01uY5g/ON/IlRKNpihe7Qze1oGWdopZP6Lwfhir5ShbDETCKQv
|
28
|
+
CuJWUOdBRsHbSraLW8n/vc/fZGqVzDAghs26bxmwicw+4/VgO2soYka81t8pUuG6
|
29
|
+
vLWWrtmIv8+cmMgvltP5AR5j2oYHYPPA9YFXuO9t1JVqJiNHm9JNRseEoBc=
|
30
|
+
-----END CERTIFICATE-----
|
31
|
+
date: 2014-12-05 00:00:00.000000000 Z
|
32
|
+
dependencies:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.7'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.7'
|
47
|
+
description: Rack middleware to expose a potential sha
|
48
|
+
email:
|
49
|
+
- piet@jaspe.rs
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- ".gitignore"
|
55
|
+
- ".travis.yml"
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE.txt
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- certs/pjaspers.pem
|
61
|
+
- checksum/shack-0.0.1.sha512
|
62
|
+
- lib/shack.rb
|
63
|
+
- lib/shack/middleware.rb
|
64
|
+
- lib/shack/railtie.rb
|
65
|
+
- lib/shack/stamp.rb
|
66
|
+
- lib/shack/version.rb
|
67
|
+
- shack.gemspec
|
68
|
+
- test/benchmark.rb
|
69
|
+
- test/helper.rb
|
70
|
+
- test/middleware_test.rb
|
71
|
+
- test/shack_test.rb
|
72
|
+
- test/stamp_test.rb
|
73
|
+
homepage: ''
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.2.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Sha + Rack = Shack
|
97
|
+
test_files:
|
98
|
+
- test/benchmark.rb
|
99
|
+
- test/helper.rb
|
100
|
+
- test/middleware_test.rb
|
101
|
+
- test/shack_test.rb
|
102
|
+
- test/stamp_test.rb
|
metadata.gz.sig
ADDED