em-synchrony-moped 0.9.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.
- 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:
|