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.
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