middle_squid 1.0
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
- data/.gitignore +13 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +227 -0
- data/Rakefile +7 -0
- data/bin/middle_squid +7 -0
- data/lib/middle_squid/actions.rb +77 -0
- data/lib/middle_squid/adapter.rb +54 -0
- data/lib/middle_squid/adapters/squid.rb +57 -0
- data/lib/middle_squid/backends/keyboard.rb +31 -0
- data/lib/middle_squid/backends/thin.rb +14 -0
- data/lib/middle_squid/blacklist.rb +67 -0
- data/lib/middle_squid/builder.rb +159 -0
- data/lib/middle_squid/cli.rb +119 -0
- data/lib/middle_squid/core_ext/hash.rb +29 -0
- data/lib/middle_squid/database.rb +47 -0
- data/lib/middle_squid/exceptions.rb +4 -0
- data/lib/middle_squid/helpers.rb +74 -0
- data/lib/middle_squid/indexer.rb +194 -0
- data/lib/middle_squid/runner.rb +37 -0
- data/lib/middle_squid/server.rb +84 -0
- data/lib/middle_squid/uri.rb +31 -0
- data/lib/middle_squid/version.rb +3 -0
- data/lib/middle_squid.rb +46 -0
- data/middle_squid.gemspec +37 -0
- data/middle_squid_wrapper.sh +4 -0
- data/test/helper.rb +26 -0
- data/test/resources/backslash/cat/list +1 -0
- data/test/resources/black/ads/domains +2 -0
- data/test/resources/black/ads/urls +1 -0
- data/test/resources/black/tracker/domains +2 -0
- data/test/resources/black/tracker/urls +2 -0
- data/test/resources/copy_of_duplicates/cat/copy_of_list +2 -0
- data/test/resources/copy_of_duplicates/cat/list +2 -0
- data/test/resources/copy_of_duplicates/copy_of_cat/copy_of_list +2 -0
- data/test/resources/copy_of_duplicates/copy_of_cat/list +2 -0
- data/test/resources/duplicates/cat/copy_of_list +2 -0
- data/test/resources/duplicates/cat/list +2 -0
- data/test/resources/duplicates/copy_of_cat/copy_of_list +2 -0
- data/test/resources/duplicates/copy_of_cat/list +2 -0
- data/test/resources/empty/cat/emptylist +0 -0
- data/test/resources/empty_path/cat/list +1 -0
- data/test/resources/expressions/cat/list +3 -0
- data/test/resources/gray/isp/domains +2 -0
- data/test/resources/gray/isp/urls +1 -0
- data/test/resources/gray/news/domains +2 -0
- data/test/resources/hello.rb +2 -0
- data/test/resources/invalid_byte/cat/list +1 -0
- data/test/resources/mixed/cat/list +2 -0
- data/test/resources/subdirectory/cat/ignore/.gitkeep +0 -0
- data/test/resources/trailing_space/cat/list +2 -0
- data/test/test_actions.rb +76 -0
- data/test/test_adapter.rb +61 -0
- data/test/test_blacklist.rb +189 -0
- data/test/test_builder.rb +89 -0
- data/test/test_cli.rb +105 -0
- data/test/test_database.rb +20 -0
- data/test/test_hash.rb +28 -0
- data/test/test_helper.rb +76 -0
- data/test/test_indexer.rb +457 -0
- data/test/test_keyboard.rb +79 -0
- data/test/test_runner.rb +56 -0
- data/test/test_server.rb +86 -0
- data/test/test_squid.rb +110 -0
- data/test/test_thin.rb +7 -0
- data/test/test_uri.rb +69 -0
- metadata +363 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
module MiddleSquid
|
2
|
+
# Manages the internal HTTP server.
|
3
|
+
class Server
|
4
|
+
DEFAULT_HOST = '127.0.0.1'.freeze
|
5
|
+
DEFAULT_PORT = 0
|
6
|
+
|
7
|
+
TOKEN_TIMEOUT = 10
|
8
|
+
|
9
|
+
Thin::Logging.logger = Logger.new STDERR
|
10
|
+
Thin::Logging.level = Logger::WARN
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :host
|
14
|
+
|
15
|
+
# @return [Fixnum]
|
16
|
+
attr_reader :port
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@tokens = {}
|
20
|
+
@thin = Thin::Server.new DEFAULT_HOST, DEFAULT_PORT, method(:handler),
|
21
|
+
:backend => Backends::Thin,
|
22
|
+
:signals => false
|
23
|
+
end
|
24
|
+
|
25
|
+
def start
|
26
|
+
@thin.start
|
27
|
+
|
28
|
+
sockname = EM.get_sockname @thin.backend.signature
|
29
|
+
@port, @host = Socket.unpack_sockaddr_in sockname
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
@thin.stop
|
34
|
+
@port = @host = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creates a temporary token.
|
38
|
+
#
|
39
|
+
# @param block [#call] called when the token is requested
|
40
|
+
# @return [String] random token
|
41
|
+
def token_for(block)
|
42
|
+
token = SecureRandom.uuid
|
43
|
+
@tokens[token] = block
|
44
|
+
|
45
|
+
EM.add_timer(TOKEN_TIMEOUT) {
|
46
|
+
@tokens.delete token
|
47
|
+
}
|
48
|
+
|
49
|
+
token
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def handler(env)
|
54
|
+
callback = @tokens[env['PATH_INFO'][1..-1]]
|
55
|
+
|
56
|
+
return [
|
57
|
+
404,
|
58
|
+
{'Content-Type' => 'text/plain'},
|
59
|
+
['[MiddleSquid] Invalid Token']
|
60
|
+
] unless callback
|
61
|
+
|
62
|
+
request = Rack::Request.new env
|
63
|
+
response = Thin::AsyncResponse.new env
|
64
|
+
|
65
|
+
Fiber.new {
|
66
|
+
retval = callback.call request, response
|
67
|
+
|
68
|
+
if retval.is_a?(Array) && retval.size == 3
|
69
|
+
status, headers, body = retval
|
70
|
+
|
71
|
+
headers.sanitize_headers!
|
72
|
+
|
73
|
+
response.status = status
|
74
|
+
response.headers.merge! headers
|
75
|
+
response.write body
|
76
|
+
end
|
77
|
+
|
78
|
+
response.done
|
79
|
+
}.resume
|
80
|
+
|
81
|
+
response.finish
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MiddleSquid
|
2
|
+
# Provides distinguishable host and path for the blacklists.
|
3
|
+
#
|
4
|
+
# @see http://rubydoc.info/gems/addressable/Addressable/URI
|
5
|
+
class URI < Addressable::URI
|
6
|
+
DOT = '.'.freeze
|
7
|
+
SLASH = '/'.freeze
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
def cleanhost
|
11
|
+
clean = normalized_host.force_encoding Encoding::UTF_8
|
12
|
+
clean.sub! /\Awww\./, ''
|
13
|
+
clean.sub! /\.+\z/, ''
|
14
|
+
clean.insert 0, DOT
|
15
|
+
clean
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
def cleanpath
|
20
|
+
dirty = normalized_path.force_encoding Encoding::UTF_8
|
21
|
+
p = Pathname.new(dirty).cleanpath
|
22
|
+
|
23
|
+
file = p.basename('.*').to_s.downcase
|
24
|
+
p = p.dirname if %w[index default].include? file
|
25
|
+
|
26
|
+
clean = p.to_s[1..-1]
|
27
|
+
clean << SLASH unless clean.empty?
|
28
|
+
clean
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/middle_squid.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'middle_squid/version'
|
2
|
+
|
3
|
+
require 'fiber'
|
4
|
+
require 'pathname'
|
5
|
+
require 'securerandom'
|
6
|
+
|
7
|
+
require 'addressable/uri'
|
8
|
+
require 'eventmachine'
|
9
|
+
require 'em-http-request'
|
10
|
+
require 'sqlite3'
|
11
|
+
require 'thin'
|
12
|
+
require 'thin/async'
|
13
|
+
require 'thor'
|
14
|
+
|
15
|
+
# Copyright (C) 2014 by Christian Fillion
|
16
|
+
#
|
17
|
+
# @see Builder Configuration syntax (DSL)
|
18
|
+
# @see Actions List of predefined actions
|
19
|
+
# @see Helpers List of predefined helpers
|
20
|
+
# @see Adapters Available adapters
|
21
|
+
module MiddleSquid
|
22
|
+
require 'middle_squid/actions'
|
23
|
+
require 'middle_squid/database'
|
24
|
+
require 'middle_squid/helpers'
|
25
|
+
|
26
|
+
module Adapters
|
27
|
+
require 'middle_squid/adapter'
|
28
|
+
require 'middle_squid/adapters/squid'
|
29
|
+
end
|
30
|
+
|
31
|
+
module Backends
|
32
|
+
require 'middle_squid/backends/keyboard'
|
33
|
+
require 'middle_squid/backends/thin'
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'middle_squid/blacklist'
|
37
|
+
require 'middle_squid/builder'
|
38
|
+
require 'middle_squid/cli'
|
39
|
+
require 'middle_squid/exceptions'
|
40
|
+
require 'middle_squid/indexer'
|
41
|
+
require 'middle_squid/runner'
|
42
|
+
require 'middle_squid/server'
|
43
|
+
require 'middle_squid/uri'
|
44
|
+
|
45
|
+
require 'middle_squid/core_ext/hash'
|
46
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path '../lib', __FILE__
|
3
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
|
4
|
+
|
5
|
+
require 'middle_squid/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'middle_squid'
|
9
|
+
spec.version = MiddleSquid::VERSION
|
10
|
+
spec.authors = ['Christian Fillion']
|
11
|
+
spec.email = ['middle_squid@cfillion.tk']
|
12
|
+
spec.summary = 'A redirector, url mangler and webpage interceptor for the Squid HTTP proxy'
|
13
|
+
spec.homepage = 'https://github.com/cfillion/middle_squid'
|
14
|
+
spec.license = 'GPL-3.0+'
|
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
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'coveralls', '~> 0.7'
|
23
|
+
spec.add_development_dependency 'minitest', '~> 5.4'
|
24
|
+
spec.add_development_dependency 'rack-test', '~> 0.6'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'simplecov', '~> 0.9'
|
27
|
+
spec.add_development_dependency 'thin-async-test', '~> 1.0'
|
28
|
+
spec.add_development_dependency 'webmock', '~> 1.18'
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'addressable', '~> 2.3'
|
31
|
+
spec.add_runtime_dependency 'em-http-request', '~> 1.1'
|
32
|
+
spec.add_runtime_dependency 'eventmachine', '~> 1.0'
|
33
|
+
spec.add_runtime_dependency 'sqlite3', '~> 1.3'
|
34
|
+
spec.add_runtime_dependency 'thin', '~> 1.6'
|
35
|
+
spec.add_runtime_dependency 'thin_async', '~> 0.1'
|
36
|
+
spec.add_runtime_dependency 'thor', '~> 0.19'
|
37
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'coveralls'
|
3
|
+
|
4
|
+
Coveralls::Output.silent = true
|
5
|
+
|
6
|
+
SimpleCov.formatters = [
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
8
|
+
Coveralls::SimpleCov::Formatter
|
9
|
+
]
|
10
|
+
|
11
|
+
SimpleCov.start {
|
12
|
+
project_name 'MiddleSquid'
|
13
|
+
add_filter '/test/'
|
14
|
+
|
15
|
+
add_group 'Adapters', '/adapter'
|
16
|
+
add_group 'Backends', '/backend'
|
17
|
+
}
|
18
|
+
|
19
|
+
require 'minitest/autorun'
|
20
|
+
require 'rack/test'
|
21
|
+
require 'thin/async/test'
|
22
|
+
require 'webmock/minitest'
|
23
|
+
|
24
|
+
require 'middle_squid'
|
25
|
+
|
26
|
+
MiddleSquid::Database.setup ':memory:'
|
@@ -0,0 +1 @@
|
|
1
|
+
google.com\path\to\file
|
@@ -0,0 +1 @@
|
|
1
|
+
google.com/adsense
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
host.com/
|
@@ -0,0 +1 @@
|
|
1
|
+
www.telus.com/content/internet/
|
@@ -0,0 +1 @@
|
|
1
|
+
host.com/path_with_�_invalid_byte
|
File without changes
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestActions < MiniTest::Test
|
4
|
+
FakeClass = Class.new { include MiddleSquid::Actions }
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@obj = FakeClass.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_accept
|
11
|
+
action = catch :action do
|
12
|
+
@obj.accept
|
13
|
+
end
|
14
|
+
|
15
|
+
assert_equal [:accept, {}], action
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_redirect_301
|
19
|
+
action = catch :action do
|
20
|
+
@obj.redirect_to 'url'
|
21
|
+
end
|
22
|
+
|
23
|
+
assert_equal [:redirect, {
|
24
|
+
:status => 301,
|
25
|
+
:url => 'url'
|
26
|
+
}], action
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_redirect_custom_status
|
30
|
+
action = catch :action do
|
31
|
+
@obj.redirect_to 'new url', status: 418
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_equal [:redirect, {
|
35
|
+
:status => 418,
|
36
|
+
:url => 'new url'
|
37
|
+
}], action
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_replace
|
41
|
+
action = catch :action do
|
42
|
+
@obj.replace_by 'http://duckduckgo.com/'
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_equal [:replace, {
|
46
|
+
:url => 'http://duckduckgo.com/'
|
47
|
+
}], action
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_intercept
|
51
|
+
mock = MiniTest::Mock.new
|
52
|
+
mock.expect :token_for, 'qwfpgjluy', [Proc]
|
53
|
+
mock.expect :host, '127.0.0.1'
|
54
|
+
mock.expect :port, 8901
|
55
|
+
@obj.define_singleton_method(:server) { mock }
|
56
|
+
|
57
|
+
action = catch :action do
|
58
|
+
EM.run {
|
59
|
+
@obj.intercept {}
|
60
|
+
EM.next_tick { EM.stop }
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
assert_equal [:replace, {
|
65
|
+
:url => 'http://127.0.0.1:8901/qwfpgjluy'
|
66
|
+
}], action
|
67
|
+
|
68
|
+
mock.verify
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_intercept_requires_a_block
|
72
|
+
assert_raises ArgumentError do
|
73
|
+
@obj.intercept
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestAdapter < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
@obj = MiddleSquid::Adapter.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_handler
|
9
|
+
bag = []
|
10
|
+
|
11
|
+
@obj.handler = proc {|*args| bag << args }
|
12
|
+
|
13
|
+
@obj.define_singleton_method(:output) { |*args| bag << args }
|
14
|
+
|
15
|
+
@obj.handle 'http://test.com', ['hello', 'world']
|
16
|
+
|
17
|
+
uri, extras = bag.shift
|
18
|
+
assert_instance_of MiddleSquid::URI, uri
|
19
|
+
assert_equal 'http://test.com', uri.to_s
|
20
|
+
assert_equal ['hello', 'world'], extras
|
21
|
+
|
22
|
+
assert_equal [:accept, {}], bag.shift # default action
|
23
|
+
|
24
|
+
assert_empty bag
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_output
|
28
|
+
assert_raises NotImplementedError do
|
29
|
+
@obj.output :accept, {}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_overridden_output
|
34
|
+
bag = []
|
35
|
+
|
36
|
+
@obj.handler = proc { throw :action, [:type, :options] }
|
37
|
+
|
38
|
+
@obj.define_singleton_method(:output) { |*args| bag << args }
|
39
|
+
|
40
|
+
@obj.handle 'http://test.com', []
|
41
|
+
|
42
|
+
assert_equal [:type, :options], bag.shift
|
43
|
+
assert_empty bag
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_empty_url
|
47
|
+
error = assert_raises MiddleSquid::InvalidURIError do
|
48
|
+
@obj.handle nil, []
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal "invalid URL received: ''", error.message
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_invalid_url
|
55
|
+
error = assert_raises MiddleSquid::InvalidURIError do
|
56
|
+
@obj.handle 'hello world', []
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_equal "invalid URL received: 'hello world'", error.message
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestBlackList < MiniTest::Test
|
4
|
+
include MiddleSquid::Database
|
5
|
+
|
6
|
+
DOMAINS = %w{
|
7
|
+
.cfillion.tk
|
8
|
+
.duckduckgo.com
|
9
|
+
.sub.stackoverflow.com
|
10
|
+
.analytics.google.com
|
11
|
+
.anidb.net
|
12
|
+
}
|
13
|
+
|
14
|
+
URLS = [
|
15
|
+
%w[.google.com analytics/],
|
16
|
+
%w[.youtube.com watch/],
|
17
|
+
%w[.github.com user/],
|
18
|
+
%w[.host.net file.html/],
|
19
|
+
%w[.host.net index.html/],
|
20
|
+
]
|
21
|
+
|
22
|
+
def setup
|
23
|
+
db.transaction
|
24
|
+
|
25
|
+
db.execute 'DELETE FROM domains'
|
26
|
+
db.execute 'DELETE FROM urls'
|
27
|
+
|
28
|
+
DOMAINS.each_with_index {|domain, index|
|
29
|
+
db.execute 'INSERT INTO domains (category, host) VALUES (?, ?)',
|
30
|
+
[index % 2 == 0 ? 'even' : 'odd', domain]
|
31
|
+
}
|
32
|
+
|
33
|
+
URLS.each_with_index {|url, index|
|
34
|
+
db.execute 'INSERT INTO urls (category, host, path) VALUES (?, ?, ?)',
|
35
|
+
[index % 2 == 0 ? 'even' : 'odd', *url]
|
36
|
+
}
|
37
|
+
|
38
|
+
db.commit
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_category
|
42
|
+
bl = MiddleSquid::BlackList.new 'cat_name'
|
43
|
+
assert_equal 'cat_name', bl.category
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_aliases_default
|
47
|
+
bl = MiddleSquid::BlackList.new 'cat_name'
|
48
|
+
assert_equal [], bl.aliases
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_aliases_custom
|
52
|
+
bl = MiddleSquid::BlackList.new 'cat_name', aliases: ['name_cat']
|
53
|
+
assert_equal ['name_cat'], bl.aliases
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_unmatch
|
57
|
+
uri = MiddleSquid::URI.parse('http://anidb.net/a9002')
|
58
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
59
|
+
|
60
|
+
refute odd.include_domain? uri
|
61
|
+
refute odd.include_url? uri
|
62
|
+
refute odd.include? uri
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_domain
|
66
|
+
uri = MiddleSquid::URI.parse('http://cfillion.tk/love-of-babble/')
|
67
|
+
even = MiddleSquid::BlackList.new 'even'
|
68
|
+
|
69
|
+
assert even.include_domain? uri
|
70
|
+
refute even.include_url? uri
|
71
|
+
assert even.include? uri
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_domain_trailing_dots
|
75
|
+
uri = MiddleSquid::URI.parse('http://cfillion.tk...')
|
76
|
+
even = MiddleSquid::BlackList.new 'even'
|
77
|
+
|
78
|
+
assert even.include_domain? uri
|
79
|
+
assert even.include? uri
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_domain_partial_match
|
83
|
+
uri1 = MiddleSquid::URI.parse('http://www.anidb.net/')
|
84
|
+
uri2 = MiddleSquid::URI.parse('http://abcde.anidb.net/')
|
85
|
+
uri3 = MiddleSquid::URI.parse('http://bus.sub.stackoverflow.com/')
|
86
|
+
even = MiddleSquid::BlackList.new 'even'
|
87
|
+
|
88
|
+
assert even.include_domain?(uri1), 'www'
|
89
|
+
assert even.include? uri1
|
90
|
+
|
91
|
+
assert even.include_domain?(uri2), 'any subdomain'
|
92
|
+
assert even.include? uri2
|
93
|
+
|
94
|
+
assert even.include_domain?(uri3), 'sub-sub-domain'
|
95
|
+
assert even.include? uri3
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_domain_right_match
|
99
|
+
uri = MiddleSquid::URI.parse('http://google.com')
|
100
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
101
|
+
|
102
|
+
refute odd.include_domain? uri
|
103
|
+
refute odd.include? uri
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_domain_left_match
|
107
|
+
uri = MiddleSquid::URI.parse('http://duckduckgo/')
|
108
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
109
|
+
|
110
|
+
refute odd.include_domain? uri
|
111
|
+
refute odd.include? uri
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_domain_wrong_subdomain
|
115
|
+
uri = MiddleSquid::URI.parse('http://fakeanalytics.google.com/')
|
116
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
117
|
+
|
118
|
+
refute odd.include_domain? uri
|
119
|
+
refute odd.include? uri
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_url
|
123
|
+
uri = MiddleSquid::URI.parse('http://google.com/analytics')
|
124
|
+
even = MiddleSquid::BlackList.new 'even'
|
125
|
+
|
126
|
+
assert even.include_url? uri
|
127
|
+
refute even.include_domain? uri
|
128
|
+
assert even.include? uri
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_url_wrong_extension
|
132
|
+
uri = MiddleSquid::URI.parse('http://host.net/file.php')
|
133
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
134
|
+
|
135
|
+
refute odd.include_url? uri
|
136
|
+
refute odd.include? uri
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_url_partial_path
|
140
|
+
uri = MiddleSquid::URI.parse('http://github.com/us')
|
141
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
142
|
+
|
143
|
+
refute odd.include_url? uri
|
144
|
+
refute odd.include? uri
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_url_left_match
|
148
|
+
uri = MiddleSquid::URI.parse('http://host.net/file.html_ohno')
|
149
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
150
|
+
|
151
|
+
refute odd.include_url? uri
|
152
|
+
refute odd.include? uri
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_url_longer_path
|
156
|
+
uri = MiddleSquid::URI.parse('http://github.com/user/repository')
|
157
|
+
even = MiddleSquid::BlackList.new 'even'
|
158
|
+
|
159
|
+
assert even.include_url? uri
|
160
|
+
assert even.include? uri
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_url_query_string
|
164
|
+
uri = MiddleSquid::URI.parse('http://github.com/user?tab=repositories')
|
165
|
+
even = MiddleSquid::BlackList.new 'even'
|
166
|
+
|
167
|
+
assert even.include_url? uri
|
168
|
+
assert even.include? uri
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_url_cheap_tricks
|
172
|
+
uri = MiddleSquid::URI.parse('http://google.com//maps/../analytics/./')
|
173
|
+
even = MiddleSquid::BlackList.new 'even'
|
174
|
+
|
175
|
+
assert even.include_url? uri
|
176
|
+
assert even.include? uri
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_group_demo
|
180
|
+
uri = MiddleSquid::URI.parse('http://youtube.com/watch?v=test')
|
181
|
+
|
182
|
+
even = MiddleSquid::BlackList.new 'even'
|
183
|
+
odd = MiddleSquid::BlackList.new 'odd'
|
184
|
+
|
185
|
+
group = [even, odd]
|
186
|
+
|
187
|
+
assert group.any? {|bl| bl.include? uri }
|
188
|
+
end
|
189
|
+
end
|