Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

Added only_hosts and except_hosts constraints to middleware. #26

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/shrimp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
require 'shrimp/source'
require 'shrimp/phantom'
require 'shrimp/middleware'
require 'shrimp/stateless_middleware'
require 'shrimp/configuration'
46 changes: 25 additions & 21 deletions lib/shrimp/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,29 +92,33 @@ def rendering_in_progress?
end

def render_as_pdf?
request_path_is_pdf = !!@request.path.match(%r{\.pdf$})
return false unless request_path_is_pdf
return false if only_guard(:only, :path)
return false if except_guard(:except, :path)
return false if only_guard(:only_hosts, :host)
return false if except_guard(:except_hosts, :host)
true
end

if request_path_is_pdf && @conditions[:only]
rules = [@conditions[:only]].flatten
rules.any? do |pattern|
if pattern.is_a?(Regexp)
@request.path =~ pattern
else
@request.path[0, pattern.length] == pattern
end
end
elsif request_path_is_pdf && @conditions[:except]
rules = [@conditions[:except]].flatten
rules.map do |pattern|
if pattern.is_a?(Regexp)
return false if @request.path =~ pattern
else
return false if @request.path[0, pattern.length] == pattern
end
def request_path_is_pdf
!!@request.path.match(%r{\.pdf$})
end

def only_guard(guard, meth)
@conditions[guard] && !guard(guard, meth)
end

def except_guard(guard, meth)
@conditions[guard] && guard(guard, meth)
end

def guard(guard, meth)
[@conditions[guard]].flatten.any? do |pattern|
if pattern.is_a?(Regexp)
@request.send(meth) =~ pattern
else
@request.send(meth).send(:[], 0, pattern.length) == pattern
end
return true
else
request_path_is_pdf
end
end

Expand Down
56 changes: 56 additions & 0 deletions lib/shrimp/stateless_middleware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module Shrimp
class StatelessMiddleware
def initialize(app, options = { }, conditions = { })
@app = app
@options = options
@conditions = conditions
end

def call(env)
@request = Rack::Request.new(env)
if render_as_pdf?
body = Phantom.new(@request.url.sub(%r{\.pdf$}, ''), @options, @request.cookies).to_string
response = [body]
headers = { }
headers["Content-Length"] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s
headers["Content-Type"] = "application/pdf"
[200, headers, response]
else
@app.call(env)
end
end

private

def render_as_pdf?
return false unless request_path_is_pdf
return false if only_guard(:only, :path)
return false if except_guard(:except, :path)
return false if only_guard(:only_hosts, :host)
return false if except_guard(:except_hosts, :host)
true
end

def request_path_is_pdf
!!@request.path.match(%r{\.pdf$})
end

def only_guard(guard, meth)
@conditions[guard] && !guard(guard, meth)
end

def except_guard(guard, meth)
@conditions[guard] && guard(guard, meth)
end

def guard(guard, meth)
[@conditions[guard]].flatten.any? do |pattern|
if pattern.is_a?(Regexp)
@request.send(meth) =~ pattern
else
@request.send(meth).send(:[], 0, pattern.length) == pattern
end
end
end
end
end
30 changes: 28 additions & 2 deletions spec/shrimp/middleware_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ def mock_app(options = { }, conditions = { })

context "except" do
before { mock_app(options, :except => %w(/secret)) }
it "render pdf for set only option" do
it "render pdf for set except option" do
get '/invoice/test.pdf'
@middleware.send(:'render_as_pdf?').should be true
end

it "render pdf for set only option" do
it "render pdf for set except option" do
get '/public/test.pdf'
@middleware.send(:'render_as_pdf?').should be true
end
Expand All @@ -120,4 +120,30 @@ def mock_app(options = { }, conditions = { })
@middleware.send(:'render_as_pdf?').should be false
end
end

context "only_hosts" do
before { mock_app(options, :only_hosts => [%r[^test.example.org]]) }
it "render pdf for set only_hosts option" do
get '/test.pdf', {}, {'HTTP_HOST' => 'test.example.org' }
@middleware.send(:'render_as_pdf?').should be true
end

it "not render pdf for any other hosts" do
get '/test.pdf'
@middleware.send(:'render_as_pdf?').should be false
end
end

context "except_hosts" do
before { mock_app(options, :except_hosts => [%r[^test.example.org]]) }
it "render pdf for set except_hosts option" do
get '/invoice/test.pdf'
@middleware.send(:'render_as_pdf?').should be true
end

it "not render pdf for any other hosts" do
get '/secret/test.pdf', {}, {'HTTP_HOST' => 'test.example.org' }
@middleware.send(:'render_as_pdf?').should be false
end
end
end