raktr 0.0.1

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -0
  3. data/LICENSE.md +29 -0
  4. data/README.md +77 -0
  5. data/Rakefile +53 -0
  6. data/lib/raktr/connection/callbacks.rb +71 -0
  7. data/lib/raktr/connection/error.rb +120 -0
  8. data/lib/raktr/connection/peer_info.rb +90 -0
  9. data/lib/raktr/connection/tls.rb +164 -0
  10. data/lib/raktr/connection.rb +339 -0
  11. data/lib/raktr/global.rb +24 -0
  12. data/lib/raktr/iterator.rb +249 -0
  13. data/lib/raktr/queue.rb +89 -0
  14. data/lib/raktr/tasks/base.rb +57 -0
  15. data/lib/raktr/tasks/delayed.rb +33 -0
  16. data/lib/raktr/tasks/one_off.rb +30 -0
  17. data/lib/raktr/tasks/periodic.rb +58 -0
  18. data/lib/raktr/tasks/persistent.rb +29 -0
  19. data/lib/raktr/tasks.rb +105 -0
  20. data/lib/raktr/version.rb +13 -0
  21. data/lib/raktr.rb +707 -0
  22. data/spec/raktr/connection/tls_spec.rb +348 -0
  23. data/spec/raktr/connection_spec.rb +74 -0
  24. data/spec/raktr/iterator_spec.rb +203 -0
  25. data/spec/raktr/queue_spec.rb +91 -0
  26. data/spec/raktr/tasks/base.rb +8 -0
  27. data/spec/raktr/tasks/delayed_spec.rb +71 -0
  28. data/spec/raktr/tasks/one_off_spec.rb +66 -0
  29. data/spec/raktr/tasks/periodic_spec.rb +57 -0
  30. data/spec/raktr/tasks/persistent_spec.rb +54 -0
  31. data/spec/raktr/tasks_spec.rb +155 -0
  32. data/spec/raktr_spec.rb +20 -0
  33. data/spec/raktr_tls_spec.rb +20 -0
  34. data/spec/spec_helper.rb +17 -0
  35. data/spec/support/fixtures/handlers/echo_client.rb +34 -0
  36. data/spec/support/fixtures/handlers/echo_client_tls.rb +10 -0
  37. data/spec/support/fixtures/handlers/echo_server.rb +12 -0
  38. data/spec/support/fixtures/handlers/echo_server_tls.rb +8 -0
  39. data/spec/support/fixtures/pems/cacert.pem +37 -0
  40. data/spec/support/fixtures/pems/client/cert.pem +37 -0
  41. data/spec/support/fixtures/pems/client/foo-cert.pem +39 -0
  42. data/spec/support/fixtures/pems/client/foo-key.pem +51 -0
  43. data/spec/support/fixtures/pems/client/key.pem +51 -0
  44. data/spec/support/fixtures/pems/server/cert.pem +37 -0
  45. data/spec/support/fixtures/pems/server/key.pem +51 -0
  46. data/spec/support/helpers/paths.rb +23 -0
  47. data/spec/support/helpers/utilities.rb +135 -0
  48. data/spec/support/lib/server_option_parser.rb +29 -0
  49. data/spec/support/lib/servers/runner.rb +13 -0
  50. data/spec/support/lib/servers.rb +133 -0
  51. data/spec/support/servers/echo.rb +14 -0
  52. data/spec/support/servers/echo_tls.rb +22 -0
  53. data/spec/support/servers/echo_unix.rb +14 -0
  54. data/spec/support/servers/echo_unix_tls.rb +22 -0
  55. data/spec/support/shared/connection.rb +696 -0
  56. data/spec/support/shared/raktr.rb +834 -0
  57. data/spec/support/shared/task.rb +21 -0
  58. metadata +140 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks::Base do
4
+ it_should_behave_like 'Raktr::Tasks::Base'
5
+
6
+ subject { described_class.new{} }
7
+ end
8
+
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks::Delayed do
4
+ it_should_behave_like 'Raktr::Tasks::Base'
5
+
6
+ let(:list) { Raktr::Tasks.new }
7
+ let(:interval) { 0.25 }
8
+ subject { described_class.new( interval ){} }
9
+
10
+ describe '#initialize' do
11
+ context 'when the interval is <= 0' do
12
+ it "raises #{ArgumentError}" do
13
+ expect { described_class.new( 0 ){} }.to raise_error ArgumentError
14
+ expect { described_class.new( -1 ){} }.to raise_error ArgumentError
15
+ end
16
+ end
17
+ end
18
+
19
+ describe '#interval' do
20
+ it 'returns the configured interval' do
21
+ subject.interval.should == interval
22
+ end
23
+ end
24
+
25
+ describe '#call' do
26
+ context 'at the next interval' do
27
+ it 'calls the task' do
28
+ called = 0
29
+ task = described_class.new( interval ) do
30
+ called += 1
31
+ end
32
+
33
+ list << task
34
+
35
+ time = Time.now
36
+ task.call while called < 1
37
+
38
+ elapsed = (Time.now - time).round(2)
39
+ elapsed.should >= 0.25
40
+ elapsed.should < 0.30
41
+ end
42
+
43
+ it 'calls #done' do
44
+ called = 0
45
+ task = described_class.new( interval ) do
46
+ called += 1
47
+ end
48
+
49
+ list << task
50
+
51
+ task.should receive(:done)
52
+ task.call while called < 1
53
+ end
54
+
55
+ context 'when arguments have been provided' do
56
+ it 'passes them to the task' do
57
+ called = nil
58
+ task = described_class.new( interval ) do |_, s1, s2|
59
+ called = [s1, s2]
60
+ end
61
+
62
+ list << task
63
+
64
+ task.call( :stuff1, :stuff2 ) while !called
65
+
66
+ called.should == [:stuff1, :stuff2]
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks::OneOff do
4
+ it_should_behave_like 'Raktr::Tasks::Base'
5
+
6
+ let(:list) { Raktr::Tasks.new }
7
+ subject { described_class.new{} }
8
+
9
+ describe '#initialize' do
10
+ context 'when no task have been given' do
11
+ it "raises #{ArgumentError}" do
12
+ expect { described_class.new }.to raise_error ArgumentError
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#call' do
18
+ it 'calls the given task' do
19
+ callable = proc {}
20
+ callable.should receive(:call)
21
+
22
+ task = described_class.new(&callable)
23
+ list << task
24
+
25
+ task.call
26
+ end
27
+
28
+ it 'passes the task to it' do
29
+ callable = proc {}
30
+ task = described_class.new(&callable)
31
+
32
+ callable.should receive(:call).with(task)
33
+
34
+ list << task
35
+
36
+ task.call
37
+ end
38
+
39
+ it 'calls #done' do
40
+ callable = proc {}
41
+ task = described_class.new(&callable)
42
+
43
+ callable.should receive(:call).with(task)
44
+
45
+ list << task
46
+
47
+ task.should receive(:done)
48
+ task.call
49
+ end
50
+
51
+ context 'when arguments have been provided' do
52
+ it 'passes them to the task' do
53
+ got = nil
54
+ callable = proc do |_, arg|
55
+ got = arg
56
+ end
57
+
58
+ task = described_class.new(&callable)
59
+ list << task
60
+
61
+ task.call :stuff
62
+ got.should == :stuff
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks::Periodic do
4
+ it_should_behave_like 'Raktr::Tasks::Base'
5
+
6
+ let(:list) { Raktr::Tasks.new }
7
+ let(:interval) { 0.25 }
8
+ subject { described_class.new( interval ){} }
9
+
10
+ describe '#initialize' do
11
+ context 'when the interval is <= 0' do
12
+ it "raises #{ArgumentError}" do
13
+ expect { described_class.new( 0 ){} }.to raise_error ArgumentError
14
+ expect { described_class.new( -1 ){} }.to raise_error ArgumentError
15
+ end
16
+ end
17
+ end
18
+
19
+ describe '#interval' do
20
+ it 'returns the configured interval' do
21
+ subject.interval.should == interval
22
+ end
23
+ end
24
+
25
+ describe '#call' do
26
+ context 'at each interval' do
27
+ it 'calls the task' do
28
+ called = 0
29
+ task = described_class.new( interval ) do
30
+ called += 1
31
+ end
32
+
33
+ time = Time.now
34
+ task.call while called < 5
35
+
36
+ elapsed = (Time.now - time).round(2)
37
+ elapsed.should >= 1.25
38
+ elapsed.should < 1.35
39
+ end
40
+ end
41
+
42
+ context 'when arguments have been provided' do
43
+ it 'passes them to the task' do
44
+ called = nil
45
+ task = described_class.new( interval ) do |_, s1, s2|
46
+ called = [s1, s2]
47
+ end
48
+
49
+ list << task
50
+
51
+ task.call( :stuff1, :stuff2 ) while !called
52
+
53
+ called.should == [:stuff1, :stuff2]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks::Persistent do
4
+ it_should_behave_like 'Raktr::Tasks::Base'
5
+
6
+ let(:list) { Raktr::Tasks.new }
7
+ subject { described_class.new{} }
8
+
9
+ describe '#initialize' do
10
+ context 'when no task have been given' do
11
+ it "raises #{ArgumentError}" do
12
+ expect { described_class.new }.to raise_error ArgumentError
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#call' do
18
+ it 'calls the given task' do
19
+ callable = proc {}
20
+ callable.should receive(:call)
21
+
22
+ task = described_class.new(&callable)
23
+ list << task
24
+
25
+ task.call
26
+ end
27
+
28
+ it 'passes the task to it' do
29
+ callable = proc {}
30
+ task = described_class.new(&callable)
31
+
32
+ callable.should receive(:call).with(task)
33
+
34
+ list << task
35
+
36
+ task.call
37
+ end
38
+
39
+ context 'when arguments have been provided' do
40
+ it 'passes them to the task' do
41
+ got = nil
42
+ callable = proc do |_, arg|
43
+ got = arg
44
+ end
45
+
46
+ task = described_class.new(&callable)
47
+ list << task
48
+
49
+ task.call :stuff
50
+ got.should == :stuff
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr::Tasks do
4
+ subject { described_class.new }
5
+ let(:task) { described_class::Persistent.new{} }
6
+ let(:another_task) { described_class::Persistent.new{} }
7
+
8
+ describe '#<<' do
9
+ it 'adds a task to the list' do
10
+ subject << task
11
+ subject.should include task
12
+ end
13
+
14
+ it 'assigns an #owner to the task' do
15
+ subject << task
16
+ task.owner.should == subject
17
+ end
18
+
19
+ it 'returns self' do
20
+ (subject << task).should == subject
21
+ end
22
+ end
23
+
24
+ describe '#include?' do
25
+ context 'when it includes the given task' do
26
+ it 'returns true' do
27
+ subject << task
28
+ expect(subject.include?( task )).to be_truthy
29
+ end
30
+ end
31
+
32
+ context 'when it does not includes the given task' do
33
+ it 'returns false' do
34
+ subject << task
35
+ expect(subject.include?( another_task )).to be_falsey
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#delete' do
41
+ context 'when it includes the given task' do
42
+ it 'removes it' do
43
+ subject << task
44
+ subject.delete task
45
+ subject.should_not include task
46
+ end
47
+
48
+ it 'returns it' do
49
+ subject << task
50
+ subject.delete( task ).should == task
51
+ end
52
+
53
+ it 'removes the #owner association' do
54
+ subject << task
55
+ subject.delete( task ).should == task
56
+ task.owner.should be_nil
57
+ end
58
+ end
59
+
60
+ context 'when it does not include the given task' do
61
+ it 'returns nil' do
62
+ subject.delete( task ).should be_nil
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#size' do
68
+ it 'returns the size of the list' do
69
+ subject << task
70
+ subject << another_task
71
+ subject.size.should == 2
72
+ end
73
+ end
74
+
75
+ describe '#empty?' do
76
+ context 'when the list is empty' do
77
+ it 'returns true' do
78
+ subject.should be_empty
79
+ end
80
+ end
81
+
82
+ context 'when the list is not empty' do
83
+ it 'returns false' do
84
+ subject << task
85
+ subject.should_not be_empty
86
+ end
87
+ end
88
+ end
89
+
90
+ describe '#any?' do
91
+ context 'when the list is not empty' do
92
+ it 'returns true' do
93
+ subject << task
94
+ subject.should be_any
95
+ end
96
+ end
97
+
98
+ context 'when the list is empty' do
99
+ it 'returns false' do
100
+ subject.should_not be_any
101
+ end
102
+ end
103
+ end
104
+
105
+ describe '#clear' do
106
+ it 'removes all tasks' do
107
+ subject << task
108
+ subject << another_task
109
+ subject.clear
110
+ subject.should be_empty
111
+ end
112
+ end
113
+
114
+ describe '#call' do
115
+ it 'calls all tasks' do
116
+ called_one = false
117
+ called_two = false
118
+
119
+ subject << described_class::Persistent.new do
120
+ called_one = true
121
+ end
122
+ subject << described_class::Persistent.new do
123
+ called_two = true
124
+ end
125
+
126
+ subject.call
127
+
128
+ called_one.should be_truthy
129
+ called_two.should be_truthy
130
+ end
131
+
132
+ it 'returns self' do
133
+ subject.call.should == subject
134
+ end
135
+
136
+ context 'when arguments have been provided' do
137
+ it 'passes them to the tasks' do
138
+ called_one = nil
139
+ called_two = nil
140
+
141
+ subject << described_class::Persistent.new do |_, arg|
142
+ called_one = arg
143
+ end
144
+ subject << described_class::Persistent.new do |_, arg|
145
+ called_two = arg
146
+ end
147
+
148
+ subject.call( :stuff )
149
+
150
+ called_one.should == :stuff
151
+ called_two.should == :stuff
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Raktr do
4
+ before :all do
5
+ @host, @port = Servers.start( :echo )
6
+
7
+ if Raktr.supports_unix_sockets?
8
+ _, port = Servers.start( :echo_unix )
9
+ @unix_socket = port_to_socket( port )
10
+ end
11
+ end
12
+
13
+ let(:echo_client_handler) { EchoClient }
14
+ let(:echo_server_handler) { EchoServer }
15
+
16
+ let(:tcp_writer) { method(:tcp_write) }
17
+ let(:unix_writer) { method(:unix_write) }
18
+
19
+ it_should_behave_like 'Raktr'
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Raktr with TLS' do
4
+ before :all do
5
+ @host, @port = Servers.start( :echo_tls )
6
+
7
+ if Raktr.supports_unix_sockets?
8
+ _, port = Servers.start( :echo_unix_tls )
9
+ @unix_socket = port_to_socket( port )
10
+ end
11
+ end
12
+
13
+ let(:echo_client_handler) { EchoClientTLS }
14
+ let(:echo_server_handler) { EchoServerTLS }
15
+
16
+ let(:tcp_writer) { method(:tcp_ssl_write) }
17
+ let(:unix_writer) { method(:unix_ssl_write) }
18
+
19
+ it_should_behave_like 'Raktr'
20
+ end
@@ -0,0 +1,17 @@
1
+ require 'ap'
2
+ require_relative '../lib/raktr'
3
+
4
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each do |f|
5
+ next if f.include? '/servers/'
6
+ require f
7
+ end
8
+
9
+ RSpec.configure do |config|
10
+ config.color = true
11
+ config.add_formatter :documentation
12
+ config.filter_run_when_matching focus: true
13
+
14
+ config.after(:all) do
15
+ Servers.killall
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ class EchoClient < Raktr::Connection
2
+
3
+ attr_reader :initialization_args
4
+ attr_reader :received_data
5
+
6
+ attr_reader :error
7
+ attr_reader :on_write_count
8
+ attr_reader :called_on_flush
9
+
10
+ def initialize( *args )
11
+ @initialization_args = args
12
+ @on_write_count = 0
13
+ @called_on_flush = false
14
+ end
15
+
16
+ def on_write
17
+ @on_write_count += 1
18
+ end
19
+
20
+ def on_flush
21
+ @called_on_flush = !has_outgoing_data?
22
+ end
23
+
24
+ def on_close( error )
25
+ @error = error
26
+ @raktr.stop
27
+ end
28
+
29
+ def on_read( data )
30
+ (@received_data ||= '') << data
31
+ @raktr.stop if @received_data.end_with? "\n\n"
32
+ end
33
+
34
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'echo_client'
2
+
3
+ class EchoClientTLS < EchoClient
4
+ include TLS
5
+
6
+ def on_connect
7
+ start_tls
8
+ end
9
+
10
+ end
@@ -0,0 +1,12 @@
1
+ class EchoServer < Raktr::Connection
2
+ attr_reader :initialization_args
3
+
4
+ def initialize( *args )
5
+ @initialization_args = args
6
+ end
7
+
8
+ def on_read( data )
9
+ write data
10
+ end
11
+
12
+ end
@@ -0,0 +1,8 @@
1
+ class EchoServerTLS < EchoServer
2
+ include TLS
3
+
4
+ def on_connect
5
+ start_tls
6
+ end
7
+
8
+ end
@@ -0,0 +1,37 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGaDCCBFCgAwIBAgIJAPBYwqAog9f1MA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV
3
+ BAYTAkdSMRgwFgYDVQQDEw9BcmFjaG5pLXRlc3QtQ0ExKjAoBgkqhkiG9w0BCQEW
4
+ G2FyYWNobmlAYXJhY2huaS1zY2FubmVyLmNvbTAeFw0xMjExMDIxMDIyNTNaFw0y
5
+ MjEwMzExMDIyNTNaMFMxCzAJBgNVBAYTAkdSMRgwFgYDVQQDEw9BcmFjaG5pLXRl
6
+ c3QtQ0ExKjAoBgkqhkiG9w0BCQEWG2FyYWNobmlAYXJhY2huaS1zY2FubmVyLmNv
7
+ bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANHbVRqyD7FT8KSCZLm1
8
+ YrOwMj78OXRjMb+ucPR+fncXR1TEuPlEFojLtzqtsaA5OJXpj+0toFP+2T4DeFlu
9
+ YT4TBrRQ3DxmeY2b5b6ZuurLMfMc1vU+dE92Tj4nuInBz3Z09aDQ8ZWXWzJ7uD3J
10
+ eNjOcj7Jc94AGFx05Tii9VriUmX+jXQALv5S5WGVtKt4p67mLm/2xD4JhS+a0+B8
11
+ s/Xo7l6EXaFeTsH5jgZDiY+f0Dpk6cM+pZ5AJVJiNonDJs8/nl9vdWPRH40GHsyN
12
+ H0/lo/wTxuth/TvX3DBB5hTi/9V5eYbLTLtE1oyXgBxNKrjDu8FVn/jUl8DAIdJL
13
+ n4vXwXI70wLyS6aF8uu9ApNnmSbTTc2scAKDmnlINLHqGGlpyleojqphDy3MfQYk
14
+ YT9QSXNKHlO4NMLFqrqM1F3hvM3MEteeM12gAeeJLY6YYYJafMMMh/e7kK/y5u+J
15
+ ype5t5N8GKskSRp0RvlRYfoH/lnyJd6FEyh9P0QHA4CKAadZBCfOcmwmTY/G0Kjn
16
+ 3Y7r7BmJb4PIEcDqUjXwuyq6ZHjx7sawuGG6eXhIGln0JtSymy4j+h+xlh0S7O8B
17
+ Ti6dMVxg+DNTkEJz2O00IIBcyToqZ26XovFkN5ueRNOROB3YVpldmpbLyuOQae/D
18
+ 4Gc21bEWoR7OAaY2PRl4r563AgMBAAGjggE9MIIBOTAdBgNVHQ4EFgQU8VOtNUbZ
19
+ rnbX0gRWIds5yaT+uCwwgYMGA1UdIwR8MHqAFPFTrTVG2a5219IEViHbOcmk/rgs
20
+ oVekVTBTMQswCQYDVQQGEwJHUjEYMBYGA1UEAxMPQXJhY2huaS10ZXN0LUNBMSow
21
+ KAYJKoZIhvcNAQkBFhthcmFjaG5pQGFyYWNobmktc2Nhbm5lci5jb22CCQDwWMKg
22
+ KIPX9TAPBgNVHRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBBjAJBgNVHRIE
23
+ AjAAMCsGCWCGSAGG+EIBDQQeFhxUaW55Q0EgR2VuZXJhdGVkIENlcnRpZmljYXRl
24
+ MCYGA1UdEQQfMB2BG2FyYWNobmlAYXJhY2huaS1zY2FubmVyLmNvbTAOBgNVHQ8B
25
+ Af8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggIBAAAAebhmNydIUT+sZpvWM5JKNQdq
26
+ YtnghnpZyM37cxLmFIeDKKPTw/3lhDViRRqQaaFTI7ukcqgloPmhMuymQT4o11Fw
27
+ XLoQuIeSgS7Mg6eZF3CUKoEy1KnlluegDXtDI+WH/EQHlokBvoMaClltj6vsfqI/
28
+ K9K2MAXUKi8K7NRq6VYO1QPtrBfrX9VmLyndbYm8lSG5oDkGGh8NjVgHHZDgrQAQ
29
+ 2EmsWbE9yMZ6yl+AaaE5XrbPWnBI8rK77WP93JYVAhmcaQiJzPfMw3sb2QojKdak
30
+ 7fvJzAjBeXAoTP5Mu/E+BPPgELzB/DnRaWlrYsAQeRZBV+I3+k5CCVqdOAdJCk5Y
31
+ dFNTppHfwVaDj5qKOmodzdUDcDL6ynl15t6WHgj2yBwsDVpWsvbqyitZkemLFwrf
32
+ hAedR3dKr+IxrOynST1w4LorDorcGK/DqhD475bQ9EDel5nW18hotUeeeO+K3qc7
33
+ iGgj7zTKfmhzL/KMotir/SQYYxQbbtLkkhXDaNVlWiYkHotOzrNbpKAFM776CI47
34
+ KTXG88FydcycGHYU8SQLEbEDiowAikr2u+CUHKrJvz2Wr8jkWaMCSfgCyokcY6vR
35
+ IIqnrpYHhX2FmKf+tRB8o3KXM6uiOSUvaW23LHcs0OKqcJ0XHOkhTMDFZ82eDZzl
36
+ CXJQkVNhmc0Y9prF
37
+ -----END CERTIFICATE-----
@@ -0,0 +1,37 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGazCCBFOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBTMQswCQYDVQQGEwJHUjEY
3
+ MBYGA1UEAxMPQXJhY2huaS10ZXN0LUNBMSowKAYJKoZIhvcNAQkBFhthcmFjaG5p
4
+ QGFyYWNobmktc2Nhbm5lci5jb20wHhcNMTIxMTAyMTAyNDA4WhcNMjIxMDMwMTAy
5
+ NDA4WjBKMQswCQYDVQQGEwJHUjEPMA0GA1UEAxMGQ2xpZW50MSowKAYJKoZIhvcN
6
+ AQkBFhthcmFjaG5pQGFyYWNobmktc2Nhbm5lci5jb20wggIiMA0GCSqGSIb3DQEB
7
+ AQUAA4ICDwAwggIKAoICAQDEl91flpFH2Y1b2voSsjYDEiC70ArJWrmgm/UFdtXT
8
+ pCng9ACjJWuf/evBOa8SKmNFgM1NKMF7GaZghDid3npq4Pdz/C74Ci8Q3ORMPC25
9
+ Cq5T8oLYr7OGRQG7cmAqq7fP7MbPikEoaV3sg9CYdCqeK5WqT4+2eWvJGZ6t3z/g
10
+ A1WYoHMbhXS1MedPlJIboSUcUlvf2BEld4EzwjCAlF7IICAT37ijtlDqVZpByfii
11
+ xj47wP/fx7AtHe7tog9h1MgM0ciJgvH9TT3Kc/iSHYwrhS6jcnlwju7P1YkaRjjO
12
+ ODIt7HCf6ScMmK+XIJZRuI7I4zWSSUKI5vgj5BKtlyj71xHRcKX+wfUwhz92BwwE
13
+ 9kakl+0L4C11aWKHsYpT8J3NFH8soFpyUPmVQTDiNDcmbxQYHuZbSdWG5+XLYrLZ
14
+ MJ8am9HB7Z9uQugyZxki/AgQyT21eCJBrg83A0zd+SYezsDA/SVEZXCCrrO5/u/f
15
+ 6+RGYZcWXaIk+18uai5ax0HwksN9AnIIYyH19Fkq516a231Hy37/RKn2W/vH7A/J
16
+ YdleDe1wqeIApDC/jJncuO380BdzvvwbhTkp3KKjNcx0B9d917q+pguzotiVR19n
17
+ /MyIZ2/EU6r+AGyt1jxFZQhbgL6ayVlMgflyCTcsfgN7kC6dW+7L5gfBt3MwoXgK
18
+ lwIDAQABo4IBUTCCAU0wCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBLAwKwYJ
19
+ YIZIAYb4QgENBB4WHFRpbnlDQSBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
20
+ BBYEFNDF0OQgaYJqWYB9onMoDJrI6sEHMIGDBgNVHSMEfDB6gBTxU601RtmudtfS
21
+ BFYh2znJpP64LKFXpFUwUzELMAkGA1UEBhMCR1IxGDAWBgNVBAMTD0FyYWNobmkt
22
+ dGVzdC1DQTEqMCgGCSqGSIb3DQEJARYbYXJhY2huaUBhcmFjaG5pLXNjYW5uZXIu
23
+ Y29tggkA8FjCoCiD1/UwJgYDVR0SBB8wHYEbYXJhY2huaUBhcmFjaG5pLXNjYW5u
24
+ ZXIuY29tMCYGA1UdEQQfMB2BG2FyYWNobmlAYXJhY2huaS1zY2FubmVyLmNvbTAL
25
+ BgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADggIBAKOrRHhird4fhaVMHyNdTqQx
26
+ tMuqYWrPb+L4vir7Gu9bfNXlS/b5QBBeFbg5YwVeMx2KTdJR9u3XK9PaQQCC0+ak
27
+ tDy3beasiFvoThWmzaVLnPR2OpdRbbK9oFZuK7Y7Sdj6hFapbPcS3hG1M7uWtmiF
28
+ Cwd3hmXzvyOH7DToQ5wRAtS3kE2I5J9kH8OVP/pIZ/OTnfDTHOilznOMmlJ+LuFh
29
+ ECgxIFv9GRAb+J+AxFWBFNgm6yv6cGjAnT2rZR2B2WyKpmHs+mIxqmNSYldublKi
30
+ OBVl13M2ETH9NKRkvNjYbD4nsZGWO85zGiv0AVaZxwEfIHuXQdWfSIhxno3UQpxJ
31
+ UlCZTpGJ0wvHHrHC7GQZCCdr83Zq8MgcMgCuE78qNbYIE+rf6+MOhnxgg0sJ12Yr
32
+ +++VrQx5HDOoChr39rFISRpi2vFxz5QsJONoNLvH0uJoxQ5UDlOXqeq6TlJBBNUk
33
+ 77IkxGfqU7XmF9uT8nmcU4hx8yhKFJOZ5ORHX+U8+yaQN8RsxQadF7OzS1MMQXkl
34
+ UwIeFEQNNv0JOIkjZILIDHz++PL5Fa+5/lgAV24X68ZIQ5FkgoLoOIWgbcARlsj0
35
+ 62BJLPhrIbCUI7XDos+hTmMPWkzfGoIahL1mEMshlrKK/XGIFh9l1iKnI/4ze1bH
36
+ 9nvAl0/txVluZtYXlf2E
37
+ -----END CERTIFICATE-----
@@ -0,0 +1,39 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGzjCCBLagAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJGTzEM
3
+ MAoGA1UECBMDZm9vMQwwCgYDVQQHEwNmb28xDDAKBgNVBAoTA2ZvbzEMMAoGA1UE
4
+ CxMDZm9vMQwwCgYDVQQDEwNmb28xGjAYBgkqhkiG9w0BCQEWC2Zvb0Bmb28uZm9v
5
+ MB4XDTExMDkyNjE0MDEzM1oXDTEyMDkyNTE0MDEzM1owgYMxCzAJBgNVBAYTAkZP
6
+ MQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYD
7
+ VQQLEwNmb28xETAPBgNVBAMTCHNvbWVuYW1lMSkwJwYJKoZIhvcNAQkBFhpzb21l
8
+ bmFtZUBzb21lbmFtZS5zb21lbmFtZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
9
+ AgoCggIBAL0r5N/tveIx+Mvuwx5R1rFuK6I8udjkzj7N5zFs/JNsHA/9pVfEX6Y4
10
+ NPlER/0MvPUNfX6quuAN3IdEW1g7ond/fuI4iARY/TSgPipIn6jk4v6Y2A6nOmUp
11
+ O/32JWZBcM3IF0qMFGfYOq5+D20iWc4l/wPkcHz46/x8Qx3bnncXJix2M/AS9RwN
12
+ Kt26Ue5tG8sPY/ckMsvMbfMQ+R+15k1x6RAnBIHeh8QsFlDFBGT+EmKzDgCI41zN
13
+ akKiS+ZvJy2byKYT/r0P47Rzx6YP52+rIVh1SlkWwjD6EbVcnvDcW52rDrcqtsSg
14
+ uqiZfr+2Td+iOQBtUS2Y5htcjdipRaVLLoCY0qwX6i4JKGiL6fPVTgIUReZPFdk7
15
+ CHVCVAAEDl3yGLe6wpqGonKk6JjBZByiW3EE9T8f3uxS3pxD6BitpVCzwYiAJnFr
16
+ DvV0xNBLriSJ+Ebcc7f0ng+L7CPO9C8ILX+vIfToURhrup4+vn7W4pyft3b588O2
17
+ XBcax+XyBn1aQN6pwZrT/9wv85J94A/WBYkOvPl3Rv2uwjlzwfR/owLVPJkbowgF
18
+ iUGQz9vl/0C+KcWkyjnXKXxq2EK7kszBH5m3vgDz2j3mMBGv0xfTZmDVM+Qs12xv
19
+ wMwIfsOxo1oMmI6mWSx3NsJqP89ui650WAqORsWZ6O0jVv64tlnXAgMBAAGjggFe
20
+ MIIBWjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIEsDArBglghkgBhvhCAQ0E
21
+ HhYcVGlueUNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUililQx5n
22
+ hJGu4Zx3C8kDJEU08ogwgaEGA1UdIwSBmTCBloAUX93JoFY2qeY+HVPZ+jAIbA/Y
23
+ rkGhc6RxMG8xCzAJBgNVBAYTAkZPMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2Zv
24
+ bzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzEaMBgG
25
+ CSqGSIb3DQEJARYLZm9vQGZvby5mb2+CCQCmSX0QNZkjADAWBgNVHRIEDzANgQtm
26
+ b29AZm9vLmZvbzAlBgNVHREEHjAcgRpzb21lbmFtZUBzb21lbmFtZS5zb21lbmFt
27
+ ZTALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADggIBAFlzE1hgfZ6Zhl8RpckD
28
+ 0NDEZFAij+gQl91gcgAnkOE70JxbBiW3LXtdQvdNNpOUUdi10+UtbRyM1XayS7tQ
29
+ v/yHvfTINtMXazDQiG+ClcCSapjAFhMJhA7HWMtZLtzXb/Pox2JciGdilbyPeHTb
30
+ xitlun85TuTSseOkriND8OnjFolOBb/713adKE/p/UEbqZ9vbMyMgxOgemdPKKSB
31
+ H8k/mdQtMbcK7Q01Z/3UMDyxiVoQk2x8SqG4NxKKTRhKN4U8DKCGO8b4awgQo+je
32
+ mc01hW60ScVhBR+ha8NkvmReUm/pvIrYdaHnyJxwlY+RjIn2Y3OBlvBHkOVBCTJo
33
+ MVHqVQGksEQH/U+zlcWrv8H/1JOhdnq4lXnWkFvOBRUVSXF3vw9q4aMYMB1bagAU
34
+ ykciVW367xwj0HMzfAKT09uo0BhyqUuLec4/ksOeDGxLRn5KdrVwAp6b+quBHbkx
35
+ BCGdLvBVxgx11E+YV+WbY0pvNNdqpsKq9oZxOLnTQek8YJ317WSzUeUPOT5zu4sM
36
+ /B/i43wDiFWV1EcV8gEAy72l7jXi3++JbN56Cd03DML/BxSmfWXwrT3hKDP9mG5+
37
+ X4N8iCT+NBIMDYX1EAiBfD7ioxDpIv5yu+WNhTH7qsDPAE0Q3aTd1Un1Lkn7F/51
38
+ bKDKa/6PCJlZOkZGTU7wxaCy
39
+ -----END CERTIFICATE-----