em-synchrony-moped 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +5 -0
- data/README.md +25 -0
- data/Rakefile +16 -0
- data/em-synchrony-moped.gemspec +27 -0
- data/lib/em-synchrony/moped.rb +118 -0
- data/spec/moped_spec.rb +124 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/ssl/ca_cert.pem +20 -0
- data/spec/ssl/server.crt +20 -0
- data/spec/ssl/server.key +31 -0
- data/spec/ssl/untrusted.crt +25 -0
- data/spec/ssl/untrusted.key +31 -0
- data/spec/support/simulated_mongod.rb +142 -0
- metadata +133 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# EM-Synchrony-Moped
|
2
|
+
|
3
|
+
EM-Synchrony-Moped is a [Moped](https://github.com/mongoid/mongoid) driver patch for [EM-Synchrony](http://github.com/igrigorik/em-synchrony). Moped is the MongoDB driver for the [Mongoid](http://github.com/mongoid/mongoid).
|
4
|
+
|
5
|
+
* Supports SSL connections
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
In order to use this driver in an EM-Synchrony environment, simply include the driver.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require "em-synchrony/moped"
|
13
|
+
|
14
|
+
```
|
15
|
+
|
16
|
+
To use SSL:
|
17
|
+
```ruby
|
18
|
+
require "em-synchrony/moped"
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
|
23
|
+
# License
|
24
|
+
|
25
|
+
The MIT License - Copyright (c) 2013 Adam Lebsack
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
task :default => [:spec]
|
8
|
+
task :test => [:spec]
|
9
|
+
|
10
|
+
desc "Run all RSpec tests"
|
11
|
+
RSpec::Core::RakeTask.new(:spec)
|
12
|
+
|
13
|
+
|
14
|
+
rescue LoadError
|
15
|
+
# silent failure for when rspec is not installed (production mode)
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'em-synchrony-moped'
|
5
|
+
s.version = "0.9.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Adam Lebsack"]
|
9
|
+
s.email = ["alebsack@gmail.com"]
|
10
|
+
|
11
|
+
s.summary = %q{Moped driver for EM-Synchrony}
|
12
|
+
s.description = %q{EM-Synchrony-Moped is a Moped driver patch for EM-Synchtony, allowing your asynchronous application use non-blocking connections to MongoDB. Moped is the MongoDB driver for the Mongoid ORM.}
|
13
|
+
s.email = %q{alebsack@gmail.com}
|
14
|
+
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'eventmachine'
|
22
|
+
s.add_runtime_dependency 'em-synchrony', '~> 1.0'
|
23
|
+
s.add_runtime_dependency 'moped', '~> 1.4.5'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "moped/connection"
|
2
|
+
|
3
|
+
silence_warnings {
|
4
|
+
|
5
|
+
module Moped
|
6
|
+
class Cluster
|
7
|
+
def sleep(seconds)
|
8
|
+
EM::Synchrony.sleep(seconds)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Connection
|
13
|
+
def connect
|
14
|
+
@sock = if !!options[:ssl]
|
15
|
+
Sockets::SSL.connect(host, port, timeout, options)
|
16
|
+
else
|
17
|
+
Sockets::TCP.connect(host, port, timeout, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Sockets.send(:remove_const, :TCP)
|
23
|
+
Sockets.send(:remove_const, :SSL)
|
24
|
+
module Sockets
|
25
|
+
module Connectable
|
26
|
+
attr_accessor :options
|
27
|
+
|
28
|
+
def alive?
|
29
|
+
!closed?
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
|
34
|
+
def connect(host, port, timeout, options={})
|
35
|
+
socket = EM.connect(host, port, self) do |c|
|
36
|
+
c.pending_connect_timeout = timeout
|
37
|
+
c.comm_inactivity_timeout = timeout
|
38
|
+
c.options = options.merge(:host => host)
|
39
|
+
end
|
40
|
+
# In TCPSocket, new against a closed port raises Errno::ECONNREFUSED.
|
41
|
+
# In EM, connect against a closed port result in a call to unbind with
|
42
|
+
# a reason param of Errno::ECONNREFUSED as a class, not an instance.
|
43
|
+
unless socket.sync(:in) # wait for connection
|
44
|
+
raise socket.unbind_reason.new if socket.unbind_reason.is_a? Class
|
45
|
+
raise SocketError, socket.unbind_reason
|
46
|
+
end
|
47
|
+
socket
|
48
|
+
|
49
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, IOError => error
|
50
|
+
raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name} (#{error.errno}): #{error.message}"
|
51
|
+
rescue SocketError => error
|
52
|
+
raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name}: #{error.message}"
|
53
|
+
rescue OpenSSL::SSL::SSLError => error
|
54
|
+
raise Errors::ConnectionFailure, "#{host}:#{port}: #{error.class.name} (#{error.errno}): #{error.message}"
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class TCP < EventMachine::Synchrony::TCPSocket
|
62
|
+
include Connectable
|
63
|
+
end
|
64
|
+
|
65
|
+
class SSL < EventMachine::Synchrony::TCPSocket
|
66
|
+
include Connectable
|
67
|
+
|
68
|
+
def connection_completed
|
69
|
+
@verified = false
|
70
|
+
if @options[:ssl].is_a?(Hash)
|
71
|
+
start_tls(@options[:ssl])
|
72
|
+
else
|
73
|
+
start_tls
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def ssl_verify_peer(pem)
|
78
|
+
unless cert_store = @options[:ssl][:cert_store]
|
79
|
+
cert_store = OpenSSL::X509::Store.new
|
80
|
+
cert_store.add_file(@options[:ssl][:verify_cert])
|
81
|
+
end
|
82
|
+
|
83
|
+
if cert = OpenSSL::X509::Certificate.new(pem) rescue nil
|
84
|
+
if cert_store.verify(cert)
|
85
|
+
|
86
|
+
cert.extensions.each do |e|
|
87
|
+
if e.oid == 'basicConstraints' && e.value == 'CA:TRUE'
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
host = @options[:ssl][:verify_host] || @options[:host]
|
93
|
+
if OpenSSL::SSL.verify_certificate_identity(cert, host)
|
94
|
+
@verified = true
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
true
|
101
|
+
rescue => e
|
102
|
+
unbind "Failed to verify SSL certificate of peer"
|
103
|
+
false
|
104
|
+
end
|
105
|
+
|
106
|
+
def ssl_handshake_completed
|
107
|
+
if @options[:ssl][:verify_peer] && !@verified
|
108
|
+
unbind "Failed to verify SSL certificate of peer"
|
109
|
+
else
|
110
|
+
@opening = false
|
111
|
+
@in_req.succeed self
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
}
|
data/spec/moped_spec.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'moped'
|
4
|
+
require 'em-synchrony/moped'
|
5
|
+
|
6
|
+
describe "em-synchrony/moped" do
|
7
|
+
|
8
|
+
def new_node(options={})
|
9
|
+
options.merge!(:timeout => 1)
|
10
|
+
host = options.delete(:host) || 'localhost'
|
11
|
+
Moped::Node.new("#{host}:#{FakeMongodHelper::BASE_PORT}", options)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "without ssl" do
|
15
|
+
|
16
|
+
it "should connect" do
|
17
|
+
EventMachine.synchrony do
|
18
|
+
start_mongod
|
19
|
+
|
20
|
+
node = new_node
|
21
|
+
node.refresh
|
22
|
+
node.should be_primary
|
23
|
+
EM.stop
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it "should raise a connection error on timeout" do
|
29
|
+
lambda {
|
30
|
+
EventMachine.synchrony do
|
31
|
+
start_mongod
|
32
|
+
|
33
|
+
# google.com seems timeout for my tests...
|
34
|
+
node = new_node(:host => "google.com")
|
35
|
+
node.refresh
|
36
|
+
|
37
|
+
EM.stop
|
38
|
+
end
|
39
|
+
}.should raise_exception(Moped::Errors::ConnectionFailure, /ETIMEDOUT/)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should raise a connection error on connection refused" do
|
43
|
+
lambda {
|
44
|
+
EventMachine.synchrony do
|
45
|
+
new_node.refresh
|
46
|
+
EM.stop
|
47
|
+
end
|
48
|
+
}.should raise_exception(Moped::Errors::ConnectionFailure, /ECONNREFUSED/)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "without ssl" do
|
53
|
+
it "should connect and not verify peer" do
|
54
|
+
EventMachine.synchrony do
|
55
|
+
start_mongod(
|
56
|
+
:ssl => {
|
57
|
+
:private_key_file => "#{SSL_DIR}/server.key",
|
58
|
+
:cert_chain_file => "#{SSL_DIR}/server.crt",
|
59
|
+
:verify_peer => false
|
60
|
+
}
|
61
|
+
)
|
62
|
+
|
63
|
+
node = new_node(:ssl => {:verify_peer => false})
|
64
|
+
node.refresh
|
65
|
+
node.should be_primary
|
66
|
+
|
67
|
+
EM.stop
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should connect and verify peer" do
|
72
|
+
EventMachine.synchrony do
|
73
|
+
start_mongod(
|
74
|
+
:ssl => {
|
75
|
+
:private_key_file => "#{SSL_DIR}/server.key",
|
76
|
+
:cert_chain_file => "#{SSL_DIR}/server.crt",
|
77
|
+
:verify_peer => false
|
78
|
+
}
|
79
|
+
)
|
80
|
+
|
81
|
+
node = new_node(:ssl => {
|
82
|
+
:verify_peer => true,
|
83
|
+
:verify_cert => "#{SSL_DIR}/ca_cert.pem",
|
84
|
+
:verify_host => "localhost"
|
85
|
+
})
|
86
|
+
node.refresh
|
87
|
+
node.should be_primary
|
88
|
+
|
89
|
+
EM.stop
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
it "should connect and fail to verify peer" do
|
95
|
+
lambda {
|
96
|
+
|
97
|
+
EventMachine.synchrony do
|
98
|
+
start_mongod(
|
99
|
+
:ssl => {
|
100
|
+
:private_key_file => "#{SSL_DIR}/untrusted.key",
|
101
|
+
:cert_chain_file => "#{SSL_DIR}/untrusted.crt",
|
102
|
+
:verify_peer => false
|
103
|
+
}
|
104
|
+
)
|
105
|
+
|
106
|
+
node = new_node(:ssl => {
|
107
|
+
:verify_peer => true,
|
108
|
+
:verify_cert => "#{SSL_DIR}/ca_cert.pem",
|
109
|
+
:verify_host => "localhost"
|
110
|
+
})
|
111
|
+
|
112
|
+
node.refresh
|
113
|
+
node.should be_primary
|
114
|
+
|
115
|
+
EM.stop
|
116
|
+
end
|
117
|
+
}.should raise_exception(Moped::Errors::ConnectionFailure, /Failed to verify SSL certificate of peer/)
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
3
|
+
|
4
|
+
require "rspec"
|
5
|
+
|
6
|
+
require 'em-synchrony'
|
7
|
+
|
8
|
+
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |f| require f }
|
9
|
+
|
10
|
+
SSL_DIR = File.expand_path("../ssl", __FILE__)
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDODCCAiCgAwIBAgIBATALBgkqhkiG9w0BAQswQjEQMA4GA1UEAwwHVGVzdCBD
|
3
|
+
QTELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdtYWlsLmNv
|
4
|
+
bTAeFw0xMzA0MjgyMjAwMzBaFw0yMzA0MjYyMjAwMzBaMEIxEDAOBgNVBAMMB1Rl
|
5
|
+
c3QgQ0ExCzAJBgNVBAYTAlVTMSEwHwYJKoZIhvcNAQkBFhJhbGVic2Fja0BnbWFp
|
6
|
+
bC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFWoHcCntUnNpD
|
7
|
+
qBSZqx5LyrvIHqXOo1a/vKP6OE2uBRVGA8M2V8OPJfFJA6rvNMwU9Hd6Ft7znN+G
|
8
|
+
Nrtoagl4w2Fr+DoaUQdjUbg8T5e1kAhcOXrqzQMv70ig+hispU2JgbX7ixHu0vC8
|
9
|
+
PEDPLWmrb8fSWnF8APhamFOL5efEzL0vI1HlVfTKN52Twc5obHzmRXyxER13dQit
|
10
|
+
HBrxB69uN7M9deozmpu34/Pjw7OMBQTAs+r7nWTvX8rQaf15PXkwYb+PQrWZp8bd
|
11
|
+
HKpqr/R9E4k+J9QA6CLNMXeeZwoJ5TRz8dHXHCS2xctJnC84+Q92EnM2i8cwWA95
|
12
|
+
YpIPI/o9AgMBAAGjOzA5MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKE
|
13
|
+
MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBm8A8M
|
14
|
+
49WMsWyowvao7psT/b1qe41uI7IfqCx8Mjh4+TRyk5/+zZtME+GWM0iRt0JMGomc
|
15
|
+
lhKjM9Q7S7kuE6oaMvwhFrrjtdMGlB+uQRG05AQaeDifYKsCACg+/1lRCbavGEvm
|
16
|
+
GqNSG5/jLoPE9ekuDsanz1ZxcfBTd1qhYfI9TW+7rpbpY+nGhkNpURA4WjeKSq7X
|
17
|
+
I2xTQhbSSiQYNwvSOEH8V2PP+6F2IEv//wCu7S5r/gPWp/B7JocvFK2oprAqgvm+
|
18
|
+
ZMkrYM4r2Mi96KUtmlPvNF4u7F3/FVPtoNmvw9nqM7ODIrKudNf5OJRC6C4FwpV4
|
19
|
+
5Mud2Jw9mvbcZzNT
|
20
|
+
-----END CERTIFICATE-----
|
data/spec/ssl/server.crt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDRTCCAi2gAwIBAgIBAjALBgkqhkiG9w0BAQswQjEQMA4GA1UEAwwHVGVzdCBD
|
3
|
+
QTELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdtYWlsLmNv
|
4
|
+
bTAeFw0xMzA0MjgyMjA2MjVaFw0yMzA0MjYyMjA2MjVaMEQxEjAQBgNVBAMMCWxv
|
5
|
+
Y2FsaG9zdDELMAkGA1UEBhMCVVMxITAfBgkqhkiG9w0BCQEWEmFsZWJzYWNrQGdt
|
6
|
+
YWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOrW1F5LzzR6
|
7
|
+
L+UnzTamxPZIIACBlyymkPA8TVlFKSu1tITSzAyHiNoP6y3tig1l+R1LxT+eY26Z
|
8
|
+
eAgwbXznvY1dJfKo7sH38IgL2cNsC3DCe/b1Ue15H5SLa+uDHTXUaybfve/dwCXO
|
9
|
+
9oq0yHhrC9+4zppnLWXQekemW35WtRAX1Rds0pZNwxfanj8wy7+qfGIUPqQ11JiV
|
10
|
+
lJ1jx2Th+3IxvPFmoNZ5HFTgudNK76hzYjVq7SZb0fH/YwGt1uVR2qI7NW1GooCm
|
11
|
+
lK46SGAT3VDQqyNrXmNk5CSoID+4GqFuruLEK/KFgE6U30/8haWPrVQ5cNp/EoXA
|
12
|
+
Wp/q+Q/dSnkCAwEAAaNGMEQwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoG
|
13
|
+
CCsGAQUFBwMBMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0B
|
14
|
+
AQsFAAOCAQEAnm7sxj9bYLLa2t5aLQU3drUKX8FaEcA2TUTWFNvSt7tnLhL+5tVO
|
15
|
+
KGN8Xh9q97MWE3jSaJwaZvV+dKp1coH6IxS7jiSeGcLlyLdvW8qoou11LWSR2W4a
|
16
|
+
V71LaBgBkaLDupFLGrC9OKuJH2TfV0lII4Rp4w9OQNyPGDd1QTd57JV1IzvByarQ
|
17
|
+
X8bSI3VKp2mSzw5z75+zfjC0tjwuJ2uPNEhcrWE1Q46gxH77ucbfqfm2kSr4JXVT
|
18
|
+
f8U9R3ee/ReQuk94dC13/lPyj+RMBvgtGoozQR5dG74ZNiG3YTEcl9JmFTCaoM3/
|
19
|
+
qV/886MaDQ2weg/1+y4RoZipssK7wBnGtg==
|
20
|
+
-----END CERTIFICATE-----
|
data/spec/ssl/server.key
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
friendlyName: localhost
|
3
|
+
localKeyID: 15 89 76 85 F8 5E 3F E6 0F B0 4D 0B 06 A9 90 39 1B 32 8A A0
|
4
|
+
Key Attributes: <No Attributes>
|
5
|
+
-----BEGIN RSA PRIVATE KEY-----
|
6
|
+
MIIEpAIBAAKCAQEA6tbUXkvPNHov5SfNNqbE9kggAIGXLKaQ8DxNWUUpK7W0hNLM
|
7
|
+
DIeI2g/rLe2KDWX5HUvFP55jbpl4CDBtfOe9jV0l8qjuwffwiAvZw2wLcMJ79vVR
|
8
|
+
7XkflItr64MdNdRrJt+9793AJc72irTIeGsL37jOmmctZdB6R6Zbfla1EBfVF2zS
|
9
|
+
lk3DF9qePzDLv6p8YhQ+pDXUmJWUnWPHZOH7cjG88Wag1nkcVOC500rvqHNiNWrt
|
10
|
+
JlvR8f9jAa3W5VHaojs1bUaigKaUrjpIYBPdUNCrI2teY2TkJKggP7gaoW6u4sQr
|
11
|
+
8oWATpTfT/yFpY+tVDlw2n8ShcBan+r5D91KeQIDAQABAoIBACL5G2dvoswN5lQa
|
12
|
+
OVWKQIrs8tcgdYMQy0T7tgk1Y4w+40NkoT68cIUJGd0dIxIbvZ2/SwDOdcBi2p1d
|
13
|
+
mPChEnmbBau9vNDmO8wG98dCr/F7BTsiDbFv+GQG32uTeyYpHEwNxhuSyqrWx6Cg
|
14
|
+
i7pjNsF6pEoaU4h2I7/H5phKEWzz1p+XWutIhww/Z2LcH3Pfp0sJGx5jxQW27zcK
|
15
|
+
oqq4F4hsa9otZp4UjTNYM3QtBHRpVofq1RECfDHbX2cNOK37CdgI68X5ssZr9b1b
|
16
|
+
ercZylqR6rSHWWqE5+CIN3Vvw/fttJazsvxs+zagJXV4eppeGzW75IPfHTDbLB6v
|
17
|
+
lefd0AECgYEA94Zd4xdGScIbGYYUYh0WHGxtf2B2pGruv8cLjsVtLNcWaUP9HiJb
|
18
|
+
lp4h5rR+lBn5VFPz3OJiEE5UL3xNhEZ7Sh4hiuQGFlsxmYvUMbbbJz8q89dVpmey
|
19
|
+
pCtseslfuglcYYxSW/PA9JjLyTDFc7hdndhUPAaFfr0ucpsPxjEPgBECgYEA8uFE
|
20
|
+
zCyu3KwIBsMXUN/gCufKrXEZv3UaHKeArLtKx+CrKYl/UAqxylU9YymyiAEa69q2
|
21
|
+
7s0CpJFsoxcXToyx2QnnNKMg168kgS9ga8lrCKFF5HPmWYIJDyYirRPz1DjDE06s
|
22
|
+
T/3t5JYDGpdLocynALHYxFyxXaWEjl7HWosxC+kCgYEA5kxuLkwJabbf3++QJ3lI
|
23
|
+
iUmY11q5CGE1odlgN4YY/g9hGq/XYaI19P1MLYrh+onwITW7P1iiROmcClJtDRVG
|
24
|
+
wL8oFkHyJ/rROzuOQnMPlISBQj6nwhvZakW8uMGD/2OWQGx+dG9mqC1B7f8it3hi
|
25
|
+
IeqU9QRcUH9UJ+19z7j14wECgYEA77FbOPhb9ZGdNjcwenMGYxzPy41TsLv7cg3o
|
26
|
+
kg8gRNO3d32ndDGpthmbRJKxC0Gz9NFbOZ5/HjQad3VhXfbByYTZdPwMfG7vYsKD
|
27
|
+
sLwNcm3eURAEY49OK3IiRJbtSiJeel5o9WSPcsiM9aAcVuhmY+wgFeG4dMfVYr+s
|
28
|
+
k/HMDIkCgYAf++B1I76Z6XdMt29wOP6bRk+oSTh/9bJ8KSD8PAq7DYdBAZRPqw72
|
29
|
+
cvx+iGbxcA2Erzag0mseOJkyEJmd8UypjtE/uw1VetjS0iBkKqRetBURTHDNt6Ef
|
30
|
+
Qv4Nr9OBhlcGKe8hVQ6ArN4JJk8pJ1PE7t2aCWds891ooN7dcsTKSw==
|
31
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
friendlyName: localhost
|
3
|
+
localKeyID: 47 6A C5 CA E0 0D 13 B6 6B 84 F0 20 18 E9 F7 40 00 E7 EC E9
|
4
|
+
subject=/CN=localhost/C=US/emailAddress=alebsack@gmail.com
|
5
|
+
issuer=/CN=localhost/C=US/emailAddress=alebsack@gmail.com
|
6
|
+
-----BEGIN CERTIFICATE-----
|
7
|
+
MIIDRzCCAi+gAwIBAgIBATALBgkqhkiG9w0BAQswRDESMBAGA1UEAwwJbG9jYWxo
|
8
|
+
b3N0MQswCQYDVQQGEwJVUzEhMB8GCSqGSIb3DQEJARYSYWxlYnNhY2tAZ21haWwu
|
9
|
+
Y29tMB4XDTEzMDQyODIyMzQyOFoXDTIzMDQyNjIyMzQyOFowRDESMBAGA1UEAwwJ
|
10
|
+
bG9jYWxob3N0MQswCQYDVQQGEwJVUzEhMB8GCSqGSIb3DQEJARYSYWxlYnNhY2tA
|
11
|
+
Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvErl6uVq
|
12
|
+
op8gvmABuF/3MaLnqBqZEZ45okxM7XPw9zeJeVNvJ7+19rhV0tH44FbRVhOtAB/+
|
13
|
+
1fbEa5DxGTfwWPEMDLEy8DIfXU513xPzCYU9AUSYOGiDDMKaoWKXC2HjjWXtcZMI
|
14
|
+
eZ5QG17/TWy4ElkrbxS3opROPcNQLrs810+4uvwOWibFEvHCGNCGnMm94Df2LqU+
|
15
|
+
y1s9Pj5FMo35kMYeJMWeLXmA8KCac2rOpBYUPgyVfXsjBgiEZFls8lBqpI4tOztQ
|
16
|
+
ZFyhqRfyqpdQ8IMHIELx39+9ydF85eYAb+bGgy8L1w9DZxAPc9Hcujctnd+F4KZi
|
17
|
+
qjA1oAwJOTOmrQIDAQABo0YwRDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAww
|
18
|
+
CgYIKwYBBQUHAwEwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3
|
19
|
+
DQEBCwUAA4IBAQC7TWaKJFnIpaugXkyHWdMvzd9A/KbegOXzN107FgQ/7oyEFUL9
|
20
|
+
Mss3MN2lfnRy5WDFLkIWNivKoTBVEJ1b8cHp4CJmA8IcsFSvJw308H9MZoxhyRQ0
|
21
|
+
Ud4ezhXxmzKtwbwCaKmGzx63DtpsdC/uXPCYix4M2CvXmvUKbzSIBR3hD9UL4W9k
|
22
|
+
Rpe5tCRYJQHATlrW4e4W8Xg4+bszDb29LHCl8e8dAazmMl94j91BkmFBwodrLwVm
|
23
|
+
5ss8SRpNxkGIX1VeL140sWlMGg9Cqk+Fj8zaeTUB85YYMkNF7RNolaGumMv0rmou
|
24
|
+
T6kYq7wNK/xm0P9WhSosvH+n/Xx3y/aalwgr
|
25
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
friendlyName: localhost
|
3
|
+
localKeyID: 47 6A C5 CA E0 0D 13 B6 6B 84 F0 20 18 E9 F7 40 00 E7 EC E9
|
4
|
+
Key Attributes: <No Attributes>
|
5
|
+
-----BEGIN RSA PRIVATE KEY-----
|
6
|
+
MIIEogIBAAKCAQEAvErl6uVqop8gvmABuF/3MaLnqBqZEZ45okxM7XPw9zeJeVNv
|
7
|
+
J7+19rhV0tH44FbRVhOtAB/+1fbEa5DxGTfwWPEMDLEy8DIfXU513xPzCYU9AUSY
|
8
|
+
OGiDDMKaoWKXC2HjjWXtcZMIeZ5QG17/TWy4ElkrbxS3opROPcNQLrs810+4uvwO
|
9
|
+
WibFEvHCGNCGnMm94Df2LqU+y1s9Pj5FMo35kMYeJMWeLXmA8KCac2rOpBYUPgyV
|
10
|
+
fXsjBgiEZFls8lBqpI4tOztQZFyhqRfyqpdQ8IMHIELx39+9ydF85eYAb+bGgy8L
|
11
|
+
1w9DZxAPc9Hcujctnd+F4KZiqjA1oAwJOTOmrQIDAQABAoIBAGrg2MEMmArW6G8n
|
12
|
+
b9KIJng2T+hLsLcfaPeG9+OQ/CZXj+EeSun1GASDfbO9G9e7b/e8E2cOwkgRWkz0
|
13
|
+
aOY3qmXR7VUHADL3QHZmIuININc2mfouRXk/WaPUkpEotTPwzIlmYfEl1Jm0EyR2
|
14
|
+
N9Rq8dD4bH8Q82uFYyQLyWe9QDu2O5Hw+gwwjt3t2buOKX+pzymqH8LpKNlTBTol
|
15
|
+
1qG1xp3lZKU7QmNOsznBSSdRV13WK3b+tD+iFSVrsQIX0r3Rh4UVw4QAqyT/8tjY
|
16
|
+
Aqb8qv9ccOdU2mKGSEhe0imqJcMBL/Ksh4e+tP0m8eJF/v6QpuqJw56iJ9kzsfY3
|
17
|
+
1AH7QgECgYEA3hxQ9vgA9F4otI7jA/eq+m8D/Ecx2IKZRsOfZvA6J0a4KqXe/auN
|
18
|
+
gH4vjMJnTgcWVOheF8WctUf+F89f9Zh0xus6wBJrD6ichWAYUGzFafvpFSe0yNhW
|
19
|
+
UIvEhe5UYQp7pQMj4Oi9/PFVQT/zKroOZWY3Y37mkeIzhyEFdpLJ7ikCgYEA2QWk
|
20
|
+
gzK6fpOOM+bN3+vJU/1OVk4CdVoSrnz3f9hRj96BxEvr+EXn4f/J4+bItsq16U4f
|
21
|
+
0xAhq+bGVV1PNOrXFqFzhMPtG14xW20mM89/MqBtke5ixB7D0cei29J87SbUX5MB
|
22
|
+
oNOg58vAbXb7NFYn3Q+SrQ89LvSASxxpfTjAPOUCgYAb8IvuxTu5ga61J9Q+x4Tm
|
23
|
+
g9iIf5wxlBwb3rfKhyWJk0fPdZYbat0d8MGif0HnetTAUYqkiuMvmqLH8/oqNsdZ
|
24
|
+
znVRe/+jtJ4b2P61/zjGID4tvxTqvuv8rdhG0LgkjOEI3OBChoR/sQv8bUL1ePoe
|
25
|
+
n0EQbwIqD75TnT/GrqhgIQKBgHNJsxZbWYUqX82km9OLj31FwFrKwDWVLv1wt447
|
26
|
+
3UA/ZNJhvq46fK+rUZX3IMMyNqcE8JUQKcMHKm9ozU4AP1jvVc2+w3PZewDln/jA
|
27
|
+
DwNXBD4U1HT5Hu+PTS3XyLO2//TxxFiqc/0PWV8NaO9poW2m+zViNg9+pbTBGC0E
|
28
|
+
e+MdAoGAeLHx2ftPjj2+/6Zu/p4jzMcMDJurVJLWaHpaSfBAxggMKOHeXeaLCoGd
|
29
|
+
mcei57mVOK1udZTnjtFRDLz198pwk1ht2DzzjDSHYQDuOMAekeY0+MfbFzMGha5c
|
30
|
+
cUtmdCGOBYbbGnB3oqv6XNSY6cM8EvnVP/VV67fSoxy+DV8La/g=
|
31
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
require 'moped/protocol/message'
|
4
|
+
module Moped
|
5
|
+
module Protocol
|
6
|
+
|
7
|
+
# This patch is so we can parse a query as a server
|
8
|
+
module Message
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
alias_method :_old_cstring, :cstring
|
12
|
+
def cstring(name)
|
13
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
14
|
+
def deserialize_#{name}(buffer)
|
15
|
+
str = ''
|
16
|
+
while c = buffer.getc
|
17
|
+
break if c == '\0'
|
18
|
+
str << c
|
19
|
+
end
|
20
|
+
self.#{name} = str
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
_old_cstring(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :_old_document, :document
|
27
|
+
def document(name, options = {})
|
28
|
+
if options[:optional]
|
29
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
30
|
+
def deserialize_#{name}(buffer)
|
31
|
+
# noop for now
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
else
|
35
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
36
|
+
def deserialize_#{name}(buffer)
|
37
|
+
self.#{name} = BSON::Document.deserialize(buffer)
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
end
|
41
|
+
_old_document(name, options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# now that the class DSL is patched, load the message classes we need to patch further
|
47
|
+
|
48
|
+
# This patch is so we can parse a query as a server
|
49
|
+
require 'moped/protocol/query'
|
50
|
+
class Query
|
51
|
+
class << self
|
52
|
+
def deserialize(buffer)
|
53
|
+
reply = allocate
|
54
|
+
fields.each do |field|
|
55
|
+
reply.__send__ :"deserialize_#{field}", buffer
|
56
|
+
end
|
57
|
+
reply
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# This patch is so we can create a Reply object as a server
|
64
|
+
require 'moped/protocol/reply'
|
65
|
+
class Reply
|
66
|
+
def initialize(documents, options = {})
|
67
|
+
@documents = documents
|
68
|
+
@request_id = options[:request_id]
|
69
|
+
@response_to = options[:response_to]
|
70
|
+
@flags = options[:flags] || []
|
71
|
+
@count = documents.length
|
72
|
+
@op_code = 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
class FakeMongod < EventMachine::Connection
|
82
|
+
def initialize(options)
|
83
|
+
@options = options
|
84
|
+
@request_id = 0
|
85
|
+
end
|
86
|
+
|
87
|
+
def post_init
|
88
|
+
if @options[:ssl]
|
89
|
+
start_tls(@options[:ssl])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def receive_data(data)
|
94
|
+
query = Moped::Protocol::Query.deserialize(StringIO.new(data))
|
95
|
+
if query.full_collection_name == 'admin.$cmd'
|
96
|
+
if query.selector == {'ismaster' => 1}
|
97
|
+
send_reply(query,
|
98
|
+
:ok => 1,
|
99
|
+
:ismaster => 1
|
100
|
+
)
|
101
|
+
elsif query.selector == {'listDatabases' => 1}
|
102
|
+
send_reply(query,
|
103
|
+
:ok => 1,
|
104
|
+
:databases => [{
|
105
|
+
:name => 'test_db'
|
106
|
+
}]
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def send_reply(query, *documents)
|
113
|
+
@request_id += 1
|
114
|
+
reply = Moped::Protocol::Reply.new(
|
115
|
+
documents,
|
116
|
+
:request_id => @request_ud,
|
117
|
+
:response_to => query.request_id
|
118
|
+
)
|
119
|
+
send_data reply.serialize
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
module FakeMongodHelper
|
125
|
+
|
126
|
+
BASE_PORT = 37017
|
127
|
+
|
128
|
+
def start_mongod(options={})
|
129
|
+
@server = EventMachine.start_server('127.0.0.1', BASE_PORT, FakeMongod, options)
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def stop_mongod
|
134
|
+
EventMachine.stop_server(@server)
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
RSpec.configure do |config|
|
140
|
+
config.include FakeMongodHelper
|
141
|
+
|
142
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: em-synchrony-moped
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Lebsack
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
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: em-synchrony
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: moped
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.4.5
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.4.5
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.12.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.12.0
|
78
|
+
description: EM-Synchrony-Moped is a Moped driver patch for EM-Synchtony, allowing
|
79
|
+
your asynchronous application use non-blocking connections to MongoDB. Moped is
|
80
|
+
the MongoDB driver for the Mongoid ORM.
|
81
|
+
email: alebsack@gmail.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- em-synchrony-moped.gemspec
|
91
|
+
- lib/em-synchrony/moped.rb
|
92
|
+
- spec/moped_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
94
|
+
- spec/ssl/ca_cert.pem
|
95
|
+
- spec/ssl/server.crt
|
96
|
+
- spec/ssl/server.key
|
97
|
+
- spec/ssl/untrusted.crt
|
98
|
+
- spec/ssl/untrusted.key
|
99
|
+
- spec/support/simulated_mongod.rb
|
100
|
+
homepage:
|
101
|
+
licenses: []
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.8.25
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Moped driver for EM-Synchrony
|
124
|
+
test_files:
|
125
|
+
- spec/moped_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
- spec/ssl/ca_cert.pem
|
128
|
+
- spec/ssl/server.crt
|
129
|
+
- spec/ssl/server.key
|
130
|
+
- spec/ssl/untrusted.crt
|
131
|
+
- spec/ssl/untrusted.key
|
132
|
+
- spec/support/simulated_mongod.rb
|
133
|
+
has_rdoc:
|