shack 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 +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
|
+
[](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
|
+

|
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