middle_squid 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +674 -0
  6. data/README.md +227 -0
  7. data/Rakefile +7 -0
  8. data/bin/middle_squid +7 -0
  9. data/lib/middle_squid/actions.rb +77 -0
  10. data/lib/middle_squid/adapter.rb +54 -0
  11. data/lib/middle_squid/adapters/squid.rb +57 -0
  12. data/lib/middle_squid/backends/keyboard.rb +31 -0
  13. data/lib/middle_squid/backends/thin.rb +14 -0
  14. data/lib/middle_squid/blacklist.rb +67 -0
  15. data/lib/middle_squid/builder.rb +159 -0
  16. data/lib/middle_squid/cli.rb +119 -0
  17. data/lib/middle_squid/core_ext/hash.rb +29 -0
  18. data/lib/middle_squid/database.rb +47 -0
  19. data/lib/middle_squid/exceptions.rb +4 -0
  20. data/lib/middle_squid/helpers.rb +74 -0
  21. data/lib/middle_squid/indexer.rb +194 -0
  22. data/lib/middle_squid/runner.rb +37 -0
  23. data/lib/middle_squid/server.rb +84 -0
  24. data/lib/middle_squid/uri.rb +31 -0
  25. data/lib/middle_squid/version.rb +3 -0
  26. data/lib/middle_squid.rb +46 -0
  27. data/middle_squid.gemspec +37 -0
  28. data/middle_squid_wrapper.sh +4 -0
  29. data/test/helper.rb +26 -0
  30. data/test/resources/backslash/cat/list +1 -0
  31. data/test/resources/black/ads/domains +2 -0
  32. data/test/resources/black/ads/urls +1 -0
  33. data/test/resources/black/tracker/domains +2 -0
  34. data/test/resources/black/tracker/urls +2 -0
  35. data/test/resources/copy_of_duplicates/cat/copy_of_list +2 -0
  36. data/test/resources/copy_of_duplicates/cat/list +2 -0
  37. data/test/resources/copy_of_duplicates/copy_of_cat/copy_of_list +2 -0
  38. data/test/resources/copy_of_duplicates/copy_of_cat/list +2 -0
  39. data/test/resources/duplicates/cat/copy_of_list +2 -0
  40. data/test/resources/duplicates/cat/list +2 -0
  41. data/test/resources/duplicates/copy_of_cat/copy_of_list +2 -0
  42. data/test/resources/duplicates/copy_of_cat/list +2 -0
  43. data/test/resources/empty/cat/emptylist +0 -0
  44. data/test/resources/empty_path/cat/list +1 -0
  45. data/test/resources/expressions/cat/list +3 -0
  46. data/test/resources/gray/isp/domains +2 -0
  47. data/test/resources/gray/isp/urls +1 -0
  48. data/test/resources/gray/news/domains +2 -0
  49. data/test/resources/hello.rb +2 -0
  50. data/test/resources/invalid_byte/cat/list +1 -0
  51. data/test/resources/mixed/cat/list +2 -0
  52. data/test/resources/subdirectory/cat/ignore/.gitkeep +0 -0
  53. data/test/resources/trailing_space/cat/list +2 -0
  54. data/test/test_actions.rb +76 -0
  55. data/test/test_adapter.rb +61 -0
  56. data/test/test_blacklist.rb +189 -0
  57. data/test/test_builder.rb +89 -0
  58. data/test/test_cli.rb +105 -0
  59. data/test/test_database.rb +20 -0
  60. data/test/test_hash.rb +28 -0
  61. data/test/test_helper.rb +76 -0
  62. data/test/test_indexer.rb +457 -0
  63. data/test/test_keyboard.rb +79 -0
  64. data/test/test_runner.rb +56 -0
  65. data/test/test_server.rb +86 -0
  66. data/test/test_squid.rb +110 -0
  67. data/test/test_thin.rb +7 -0
  68. data/test/test_uri.rb +69 -0
  69. metadata +363 -0
@@ -0,0 +1,89 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class TestBuilder < MiniTest::Test
4
+ class FakeAdapter < MiddleSquid::Adapter
5
+ def say_hello
6
+ @options[:hello]
7
+ end
8
+ end
9
+
10
+ def setup
11
+ @obj = MiddleSquid::Builder.new
12
+ end
13
+
14
+ def test_from_file
15
+ path = File.expand_path '../resources', __FILE__
16
+ file = path + '/hello.rb'
17
+
18
+ stdout, stderr = capture_io do
19
+ @obj = MiddleSquid::Builder.from_file file
20
+ end
21
+
22
+ assert_equal "hello #{@obj}\n", stdout
23
+ end
24
+
25
+ def test_default_adapter
26
+ assert_equal MiddleSquid::Adapters::Squid, @obj.adapter.class
27
+ assert_same @obj.adapter, @obj.adapter
28
+ end
29
+
30
+ def test_custom_adapter
31
+ @obj.use FakeAdapter, hello: 'world'
32
+ assert_equal FakeAdapter, @obj.adapter.class
33
+ assert_equal 'world', @obj.adapter.say_hello
34
+ end
35
+
36
+ def test_database
37
+ @obj.database ':memory:'
38
+ end
39
+
40
+ def test_blacklist
41
+ assert_empty @obj.blacklists
42
+
43
+ bl = @obj.blacklist 'hello'
44
+ assert_instance_of MiddleSquid::BlackList, bl
45
+ assert_equal 'hello', bl.category
46
+
47
+ assert_equal [bl], @obj.blacklists
48
+ end
49
+
50
+ def test_define_action
51
+ assert_empty @obj.custom_actions
52
+
53
+ world = proc { :world }
54
+ @obj.define_action :hello, &world
55
+
56
+ assert_equal({:hello => world}, @obj.custom_actions)
57
+ end
58
+
59
+ def test_define_helper
60
+ assert_equal @obj.method(:define_helper), @obj.method(:define_action)
61
+ end
62
+
63
+ def test_define_action_noblock
64
+ error = assert_raises ArgumentError do
65
+ @obj.define_action :hello
66
+ end
67
+
68
+ assert_equal 'no block given', error.message
69
+ assert_empty @obj.custom_actions
70
+ end
71
+
72
+ def test_handler
73
+ assert_nil @obj.handler
74
+
75
+ handler = lambda {}
76
+ @obj.run handler
77
+
78
+ assert_equal handler, @obj.handler
79
+ end
80
+
81
+ def test_handler_nocall
82
+ error = assert_raises ArgumentError do
83
+ @obj.run 1
84
+ end
85
+
86
+ assert_equal 'the handler must respond to #call', error.message
87
+ assert_nil @obj.handler
88
+ end
89
+ end
data/test/test_cli.rb ADDED
@@ -0,0 +1,105 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class TestCLI < MiniTest::Test
4
+ def test_start
5
+ path = File.expand_path '../resources', __FILE__
6
+ conf = File.join path, 'hello.rb'
7
+
8
+ stdout, stderr = capture_io do
9
+ EM.run {
10
+ MiddleSquid::CLI.start(%W[start -C #{conf}])
11
+ EM.next_tick { EM.stop }
12
+ }
13
+ end
14
+
15
+ assert_match /\Ahello #<MiddleSquid:.+>\Z/, stdout
16
+ end
17
+
18
+ def test_start_relative
19
+ absolute = File.expand_path '../resources', __FILE__
20
+ path = Pathname.new(absolute).relative_path_from(Pathname.new(Dir.home))
21
+
22
+ conf = File.join '~', path, 'hello.rb'
23
+
24
+ capture_io do
25
+ EM.run {
26
+ MiddleSquid::CLI.start(%W[start -C #{conf}])
27
+ EM.next_tick { EM.stop }
28
+ }
29
+ end
30
+ end
31
+
32
+ def test_default_config
33
+ default = File.join Dir.home, 'middle_squid.rb'
34
+
35
+ error = assert_raises Errno::ENOENT do
36
+ MiddleSquid::CLI.start %W[start]
37
+ end
38
+
39
+ assert_equal "No such file or directory @ rb_sysopen - #{default}", error.message
40
+ end
41
+
42
+ def test_index
43
+ path = File.expand_path '../resources', __FILE__
44
+ conf = File.join path, 'hello.rb'
45
+ list = File.join path, 'black'
46
+
47
+ stdout, stderr = capture_io do
48
+ MiddleSquid::CLI.start(%W[index #{list} -C #{conf} --full])
49
+ end
50
+
51
+ assert_match /\Ahello #<MiddleSquid:.+>$/, stdout
52
+ assert_match "reading #{list}", stdout
53
+ end
54
+
55
+ def test_index_relative_path
56
+ absolute = File.expand_path '../resources', __FILE__
57
+ path = Pathname.new(absolute).relative_path_from(Pathname.new(Dir.home))
58
+
59
+ conf = File.join '~', path, 'hello.rb'
60
+ list = File.join '~', path, 'black'
61
+
62
+ stdout, stderr = capture_io do
63
+ MiddleSquid::CLI.start(%W[index #{list} -C #{conf} --full])
64
+ end
65
+
66
+ assert_match /\Ahello #<MiddleSquid:.+>$/, stdout
67
+ assert_match "reading #{absolute}/black", stdout
68
+ end
69
+
70
+ def test_index_multiple
71
+ path = File.expand_path '../resources', __FILE__
72
+ config = File.join path, 'hello.rb'
73
+ list_1 = File.join path, 'black'
74
+ list_2 = File.join path, 'gray'
75
+
76
+ stdout, stderr = capture_io do
77
+ MiddleSquid::CLI.start(%W[index #{list_1} #{list_2} -C #{config} --full])
78
+ end
79
+
80
+ assert_match "reading #{list_1}", stdout
81
+ assert_match "reading #{list_2}", stdout
82
+ end
83
+
84
+ def test_version
85
+ stdout, stderr = capture_io do
86
+ MiddleSquid::CLI.start %w[version]
87
+ end
88
+
89
+ assert_match /MiddleSquid #{MiddleSquid::VERSION}/, stdout
90
+ assert_match /Copyright/, stdout
91
+ assert_match /GNU General Public License/, stdout
92
+ assert_match /version 3/, stdout
93
+ assert_empty stderr
94
+ end
95
+
96
+ def test_help
97
+ stdout, stderr = capture_io do
98
+ MiddleSquid::CLI.start %w[--help]
99
+ end
100
+
101
+ assert_match /MiddleSquid commands:/, stdout
102
+ assert_match /Options:/, stdout
103
+ assert_empty stderr
104
+ end
105
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class TestDatabase < MiniTest::Test
4
+ include MiddleSquid::Database
5
+
6
+ def test_db
7
+ assert_instance_of SQLite3::Database, db()
8
+ end
9
+
10
+ def test_setup
11
+ before = db()
12
+ refute before.closed?
13
+
14
+ MiddleSquid::Database.setup ':memory:'
15
+
16
+ after = db()
17
+ refute_same before, after
18
+ assert before.closed?, 'the old database should be closed'
19
+ end
20
+ end
data/test/test_hash.rb ADDED
@@ -0,0 +1,28 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class TestHash < MiniTest::Test
4
+ def test_sanitize_headers
5
+ before = {
6
+ 'Chunky-Bacon' => nil,
7
+ 'CONNECTION' => nil,
8
+ 'CONTENT_ENCODING' => nil,
9
+ 'CONTENT_LENGTH' => nil,
10
+ 'HELLO_WORLD' => nil,
11
+ 'HOST' => nil,
12
+ 'TEST' => nil,
13
+ 'Transfer-Encoding' => nil,
14
+ 'TRANSFER_ENCODING' => nil,
15
+ 'VERSION' => nil,
16
+ }
17
+
18
+ after = {
19
+ 'Chunky-Bacon' => nil,
20
+ 'Hello-World' => nil,
21
+ 'Test' => nil,
22
+ }
23
+
24
+ before.sanitize_headers!
25
+
26
+ assert_equal after, before
27
+ end
28
+ end
@@ -0,0 +1,76 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class TestHelpers < MiniTest::Test
4
+ FakeClass = Class.new { include MiddleSquid::Helpers }
5
+
6
+ def setup
7
+ @obj = FakeClass.new
8
+ end
9
+
10
+ def download_wrapper(uri, env)
11
+ bag = []
12
+ req = Rack::Request.new env
13
+
14
+ EM.run {
15
+ Fiber.new {
16
+ bag << @obj.download_like(req, uri)
17
+ }.resume
18
+ EM.next_tick { EM.stop }
19
+ }
20
+
21
+ assert_equal 1, bag.size
22
+ bag[0]
23
+ end
24
+
25
+ def test_download
26
+ uri = MiddleSquid::URI.parse 'http://test.com/path?query=string'
27
+
28
+ stub = stub_request(:get, uri).
29
+ with(:body => 'request%20body', :headers => {'User-Agent'=>'Mozilla/5.0', 'Chunky' => 'bacon', 'Content-Type'=>'test/plain'}).
30
+ to_return(:status => 200, :body => 'response', :headers => {'CHUNKY_BACON' => 'Hello World'})
31
+
32
+ status, headers, body = download_wrapper uri,
33
+ 'REQUEST_METHOD' => 'GET',
34
+ 'CONTENT_TYPE' => 'test/plain',
35
+ 'HTTP_CHUNKY' => 'bacon',
36
+ 'HTTP_CONNECTION' => 'ignored',
37
+ 'HTTP_USER_AGENT' => 'Mozilla/5.0',
38
+ 'rack.input' => StringIO.new('request%20body')
39
+
40
+ assert_requested stub
41
+ assert_not_requested :get, uri, :headers => {'Connection' => 'ignored'}
42
+
43
+ assert_equal 200, status
44
+ assert_equal({'Chunky-Bacon' => 'Hello World'}, headers)
45
+ assert_equal 'response', body
46
+ end
47
+
48
+ def test_download_method
49
+ uri = MiddleSquid::URI.parse 'http://test.com/'
50
+
51
+ stub = stub_request(:post, uri).
52
+ to_return(:status => 200, :body => '')
53
+
54
+ download_wrapper uri,
55
+ 'REQUEST_METHOD' => 'POST',
56
+ 'rack.input' => StringIO.new
57
+
58
+ assert_requested stub
59
+ end
60
+
61
+ def test_download_error
62
+ uri = MiddleSquid::URI.parse 'http://test.com/'
63
+
64
+ stub = stub_request(:get, uri).to_timeout
65
+
66
+ status, headers, body = download_wrapper uri,
67
+ 'REQUEST_METHOD' => 'GET',
68
+ 'rack.input' => StringIO.new
69
+
70
+ assert_requested stub
71
+
72
+ assert_equal 520, status
73
+ assert_empty headers
74
+ assert_equal '[MiddleSquid] WebMock timeout error', body
75
+ end
76
+ end