rack-halt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rack-halt.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Chris Kraybill
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.
@@ -0,0 +1,108 @@
1
+ # Rack::Halt
2
+
3
+ A rack middleware for defining paths that halt the rack request. In
4
+ many rack-compliant applications you may find the need to prevent
5
+ certain requests from routing to the application. This is an
6
+ alternative to instances when you cannot or do not want to write
7
+ an Apache or Nginx location block and will be more performant,
8
+ than trying to allow the Rails router, for example, handle.
9
+
10
+
11
+ ## Current Version
12
+
13
+ 0.0.1
14
+
15
+
16
+ ## Requirements
17
+
18
+ * [Rack](http://rack.github.com/)
19
+
20
+
21
+ ## Installation
22
+
23
+ ### Gemfile
24
+
25
+ Add this line to your application's Gemfile.
26
+
27
+ ```ruby
28
+ gem 'rack-halt'
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ ```bash
34
+ $ bundle
35
+ ```
36
+
37
+ ### Manual
38
+
39
+ Or install it yourself.
40
+
41
+ ```bash
42
+ $ gem install rack-halt
43
+ ```
44
+
45
+
46
+ ## Usage
47
+
48
+ ### Sample rackup file
49
+
50
+ ```ruby
51
+ gem 'rack-halt', '~> 0.0.1'
52
+ require 'rack/halt'
53
+ use Rack::Halt do
54
+ halt '/application/x-shockwave-application'
55
+ halt %r{\/text\/(css|javascript)}
56
+ end
57
+ ```
58
+
59
+ ### Sample usage in a rails app
60
+ ```ruby
61
+ config.middleware.insert_after(Rack::Lock, Rack::Halt) do
62
+ halt '/application/x-shockwave-flash'
63
+ halt %r{/text/(javascript|css)}
64
+ end
65
+ ```
66
+
67
+
68
+ ## Authors
69
+
70
+ * Chris Kraybill / [@ckraybill](https://github.com/ckraybill)
71
+
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
80
+
81
+ If you find bugs, have feature requests or questions, please
82
+ [file an issue](https://github.com/ckraybill/rack-halt/issues).
83
+
84
+
85
+ ## License
86
+
87
+ Copyright (c) 2013 Chris Kraybill
88
+
89
+ MIT License
90
+
91
+ Permission is hereby granted, free of charge, to any person obtaining
92
+ a copy of this software and associated documentation files (the
93
+ "Software"), to deal in the Software without restriction, including
94
+ without limitation the rights to use, copy, modify, merge, publish,
95
+ distribute, sublicense, and/or sell copies of the Software, and to
96
+ permit persons to whom the Software is furnished to do so, subject to
97
+ the following conditions:
98
+
99
+ The above copyright notice and this permission notice shall be
100
+ included in all copies or substantial portions of the Software.
101
+
102
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
103
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
104
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
105
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
106
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
107
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
108
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push "lib"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,45 @@
1
+ require 'rack'
2
+
3
+ module Rack::Halt
4
+ autoload :Rule, 'rack/halt/rule'
5
+ autoload :RuleSet, 'rack/halt/rule_set'
6
+
7
+ class << self
8
+
9
+ def new(app, &rule_block)
10
+ @app = app
11
+ @rule_set = RuleSet.new
12
+ @rule_set.instance_eval(&rule_block) if block_given?
13
+
14
+ self
15
+ end
16
+
17
+ def call(env)
18
+ if matched_rule = find_first_matching_rule(env)
19
+ return [404, {"Content-Type" => "text/html"}, content_for(env)]
20
+ end
21
+ @app.call(env)
22
+ end
23
+
24
+ private
25
+
26
+ def find_first_matching_rule(env)
27
+ @rule_set.rules.detect { |rule| rule.matches?(env) }
28
+ end
29
+
30
+ def content_for(env)
31
+ env["REQUEST_METHOD"] == "HEAD" ? [] : content
32
+ end
33
+
34
+ def content
35
+ <<-EOS
36
+ <html>
37
+ <head><title>404 Not Found</title></head>
38
+ <body>
39
+ <h1>404 Not Found</h1>
40
+ </body>
41
+ </html>
42
+ EOS
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ module Rack::Halt
2
+ class Rule
3
+ attr_reader :rule
4
+
5
+ def initialize(rule)
6
+ @rule = rule
7
+ end
8
+
9
+ def matches?(rack_env)
10
+ path = build_path_from_env(rack_env)
11
+ string_matches?(path, self.rule)
12
+ end
13
+
14
+ private
15
+
16
+ def build_path_from_env(env)
17
+ path = env['PATH_INFO'] || ''
18
+ path += "?#{env['QUERY_STRING']}" unless env['QUERY_STRING'].nil? || env['QUERY_STRING'].empty?
19
+ path
20
+ end
21
+
22
+ def string_matches?(string, matcher)
23
+ if matcher.is_a?(Regexp)
24
+ string =~ matcher
25
+ elsif matcher.is_a?(String)
26
+ string == matcher
27
+ else
28
+ false
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ module Rack::Halt
2
+ class RuleSet
3
+ attr_reader :rules
4
+ def initialize #:nodoc:
5
+ @rules = []
6
+ end
7
+
8
+ protected
9
+ # Creates a halt rule that will stop subsequent middlewares from
10
+ # being called.
11
+ #
12
+ # halt '/application/x-shockwave-flash'
13
+ # halt '/text/css'
14
+ # halt %r{\/text\/(css|javascript)}
15
+ def halt(rule)
16
+ add_rule rule
17
+ end
18
+
19
+ private
20
+ def add_rule(rule)
21
+ @rules << Rule.new(rule)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module Halt
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'rack/halt/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "rack-halt"
9
+ gem.version = Rack::Halt::VERSION
10
+ gem.authors = ["Chris Kraybill"]
11
+ gem.email = ["ckraybill@gmail.com"]
12
+ gem.description = %q{Prevent matched paths from subsequent middleware calls}
13
+ gem.summary = %q{Stop rack requests in their tracks}
14
+ gem.homepage = %q{https://github.com/ckraybill/rack-halt}
15
+
16
+ gem.files = [
17
+ "Gemfile",
18
+ "LICENSE.txt",
19
+ "Rakefile",
20
+ "README.md",
21
+ "lib/rack/halt.rb",
22
+ "lib/rack/halt/rule.rb",
23
+ "lib/rack/halt/rule_set.rb",
24
+ "lib/rack/halt/version.rb",
25
+ "rack-halt.gemspec"
26
+ ]
27
+ gem.executables = []
28
+ gem.test_files = [
29
+ "test/halt_test.rb",
30
+ "test/rule_set_test.rb",
31
+ "test/rule_test.rb",
32
+ "test/test_helper.rb"
33
+ ]
34
+ gem.require_paths = ["lib"]
35
+
36
+ gem.add_dependency 'rack'
37
+
38
+ gem.add_development_dependency 'minitest'
39
+ gem.add_development_dependency 'rack-test'
40
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Rack::Halt do
4
+ allow_ok_requests
5
+
6
+ it "returns 404" do
7
+ get '/text/css'
8
+ assert_equal last_response.status, 404
9
+ end
10
+
11
+ it "renders not found content when request method is not HEAD" do
12
+ get '/text/javascript'
13
+ last_response.body.must_include '<h1>404 Not Found</h1>'
14
+ end
15
+
16
+ it "returns no body when request method is HEAD" do
17
+ head '/application/x-shockwave-application'
18
+ last_response.body.must_be_empty
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Rack::Halt::RuleSet do
4
+
5
+ subject { Rack::Halt::RuleSet.new }
6
+
7
+ describe '.initialize' do
8
+ it "initializes an empty array of rules" do
9
+ subject.rules.must_equal []
10
+ end
11
+ end
12
+
13
+ describe '.halt' do
14
+ before { subject.send(:halt, '/test') }
15
+
16
+ it "adds a rule" do
17
+ subject.rules.size.must_equal 1
18
+ subject.rules.first.must_be_kind_of Rack::Halt::Rule
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Rack::Halt::Rule do
4
+
5
+ subject { Rack::Halt::Rule }
6
+
7
+ describe '.initialize' do
8
+ let(:rule) { '/test' }
9
+
10
+ it "assigns the rule" do
11
+ subject.new(rule).rule.must_equal rule
12
+ end
13
+ end
14
+
15
+ describe ".matches?" do
16
+
17
+ describe "requests without query params" do
18
+ let(:env) { {'PATH_INFO' => '/test'} }
19
+
20
+ it "matches with an equivalent string" do
21
+ subject.new('/test').matches?(env).must_equal true
22
+ end
23
+
24
+ it "does not match with an unequal string" do
25
+ subject.new('/not-a-match').matches?(env).must_equal false
26
+ end
27
+
28
+ it "matches with a matching regexp" do
29
+ subject.new(%r(\/test)).matches?(env).wont_be_nil
30
+ end
31
+
32
+ it "does not match with a non-matching regexp" do
33
+ subject.new(%r(not-a-match)).matches?(env).must_be_nil
34
+ end
35
+ end
36
+
37
+ describe "requests with query params" do
38
+ let(:env) { {'PATH_INFO' => '/test', 'QUERY_STRING' => 'foo=bar'} }
39
+
40
+ it "matches with the same path and query string" do
41
+ subject.new('/test?foo=bar').matches?(env).must_equal true
42
+ end
43
+
44
+ it "does not match with a string containing the path but not the query params" do
45
+ subject.new('/test').matches?(env).must_equal false
46
+ end
47
+
48
+ it "matches with a regexp with the path and not the query params" do
49
+ subject.new(%r{\/test}).matches?(env).wont_be_nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require "minitest/autorun"
5
+ require "rack/test"
6
+
7
+ require "rack/halt"
8
+
9
+ class Minitest::Spec
10
+
11
+ include Rack::Test::Methods
12
+
13
+ def app
14
+ Rack::Builder.new {
15
+ use Rack::Halt do
16
+ halt '/application/x-shockwave-application'
17
+ halt %r{\/text\/(css|javascript)}
18
+ end
19
+
20
+ run lambda {|env| [200, {}, ['Hello World']]}
21
+ }.to_app
22
+ end
23
+
24
+ def self.allow_ok_requests
25
+ it "must allow ok requests" do
26
+ get '/'
27
+ assert_equal 'Hello World', last_response.body
28
+ assert last_response.ok?
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-halt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Kraybill
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rack-test
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Prevent matched paths from subsequent middleware calls
63
+ email:
64
+ - ckraybill@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - Gemfile
70
+ - LICENSE.txt
71
+ - Rakefile
72
+ - README.md
73
+ - lib/rack/halt.rb
74
+ - lib/rack/halt/rule.rb
75
+ - lib/rack/halt/rule_set.rb
76
+ - lib/rack/halt/version.rb
77
+ - rack-halt.gemspec
78
+ - test/halt_test.rb
79
+ - test/rule_set_test.rb
80
+ - test/rule_test.rb
81
+ - test/test_helper.rb
82
+ homepage: https://github.com/ckraybill/rack-halt
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.23
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Stop rack requests in their tracks
106
+ test_files:
107
+ - test/halt_test.rb
108
+ - test/rule_set_test.rb
109
+ - test/rule_test.rb
110
+ - test/test_helper.rb