From eac48155635074b14aaf11f6092558e5a2f13ab1 Mon Sep 17 00:00:00 2001 From: Thijs Cadier Date: Wed, 29 Jul 2015 10:49:39 +0200 Subject: [PATCH] Ssl options for client pool --- src/bulk_operation.rs | 4 +- src/client.rs | 119 +++++++++++++++++++++++++++++++++++++++--- src/collection.rs | 6 +-- src/cursor.rs | 4 +- src/database.rs | 6 +-- src/lib.rs | 2 + 6 files changed, 125 insertions(+), 16 deletions(-) diff --git a/src/bulk_operation.rs b/src/bulk_operation.rs index 0b698b0..142b906 100644 --- a/src/bulk_operation.rs +++ b/src/bulk_operation.rs @@ -208,7 +208,7 @@ mod tests { #[test] fn test_execute_error() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let collection = client.get_collection("rust_driver_test", "bulk_operation_error"); let bulk_operation = collection.create_bulk_operation(None); @@ -223,7 +223,7 @@ mod tests { #[test] fn test_insert_remove_replace_update() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let mut collection = client.get_collection("rust_driver_test", "bulk_operation_insert"); collection.drop().unwrap_or(()); diff --git a/src/client.rs b/src/client.rs index cfc7d8b..46ca3e3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,6 @@ use std::fmt; use std::ffi::CString; +use std::path::PathBuf; use std::ptr; use mongo_c_driver_wrapper::bindings; @@ -23,15 +24,28 @@ pub struct ClientPool { } impl ClientPool { - /// Create a new ClientPool + /// Create a new ClientPool with optionally SSL options + /// /// See: http://api.mongodb.org/c/current/mongoc_client_pool_t.html - pub fn new(uri: Uri) -> ClientPool { + /// And: http://api.mongodb.org/c/current/mongoc_ssl_opt_t.html + pub fn new(uri: Uri, ssl_options: Option) -> ClientPool { super::init(); let pool = unsafe { let pool_ptr = bindings::mongoc_client_pool_new(uri.inner()); assert!(!pool_ptr.is_null()); pool_ptr }; + match ssl_options { + Some(options) => { + unsafe { + bindings::mongoc_client_pool_set_ssl_opts( + pool, + options.inner() + ); + } + }, + None => () + }; ClientPool { root_instance: true, uri: uri, // Become owner of uri so it doesn't go out of scope @@ -92,6 +106,83 @@ impl Drop for ClientPool { } } +pub struct SslOptions { + inner: bindings::mongoc_ssl_opt_t, + pem_file: Option, + pem_password: Option, + ca_file: Option, + ca_dir: Option, + crl_file: Option, + weak_cert_validation: bool +} + +impl SslOptions { + pub fn new( + pem_file: Option, + pem_password: Option, + ca_file: Option, + ca_dir: Option, + crl_file: Option, + weak_cert_validation: bool + ) -> SslOptions { + let ssl_options = bindings::mongoc_ssl_opt_t { + pem_file: match pem_file { + Some(ref f) => Self::path_ptr(f), + None => ptr::null() + }, + pem_pwd: match pem_password { + Some(ref password) => CString::new(password.clone()).unwrap().as_ptr(), + None => ptr::null() + }, + ca_file: match ca_file { + Some(ref f) => Self::path_ptr(f), + None => ptr::null() + }, + ca_dir: match ca_dir { + Some(ref f) => Self::path_ptr(f), + None => ptr::null() + }, + crl_file: match crl_file { + Some(ref f) => Self::path_ptr(f), + None => ptr::null() + }, + weak_cert_validation: weak_cert_validation as u8, + padding: [ptr::null_mut(); 8] + }; + + SslOptions { + inner: ssl_options, + pem_file: pem_file, + pem_password: pem_password, + ca_file: ca_file, + ca_dir: ca_dir, + crl_file: crl_file, + weak_cert_validation: weak_cert_validation + } + } + + fn path_ptr(path: &PathBuf) -> *const i8 { + path.as_os_str().to_cstring().unwrap().as_ptr() + } + + fn inner(&self) -> *const bindings::mongoc_ssl_opt_t { + &self.inner + } +} + +impl Clone for SslOptions { + fn clone(&self) -> SslOptions { + SslOptions::new( + self.pem_file.clone(), + self.pem_password.clone(), + self.ca_file.clone(), + self.ca_dir.clone(), + self.crl_file.clone(), + self.weak_cert_validation + ) + } +} + pub struct Client<'a> { client_pool: &'a ClientPool, inner: *mut bindings::mongoc_client_t @@ -169,14 +260,15 @@ impl<'a> Drop for Client<'a> { #[cfg(test)] mod tests { + use std::path::PathBuf; use std::thread; use super::super::uri::Uri; - use super::super::client::ClientPool; + use super::{ClientPool,SslOptions}; #[test] fn test_new_pool_and_pop_client() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); // Pop a client and get a database and collection let client = pool.pop(); @@ -192,7 +284,7 @@ mod tests { #[test] fn test_new_pool_and_pop_client_in_threads() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let pool1 = pool.clone(); let guard1 = thread::spawn(move || { @@ -213,7 +305,7 @@ mod tests { #[test] fn test_get_server_status() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let status = client.get_server_status(None).unwrap(); @@ -221,4 +313,19 @@ mod tests { assert!(status.contains_key("host")); assert!(status.contains_key("version")); } + + #[test] + fn test_new_pool_with_ssl_options() { + // We currently have no way to test full operations + let uri = Uri::new("mongodb://localhost:27017/"); + let ssl_options = SslOptions::new( + Some(PathBuf::from("/tmp/pem_file")), + Some("password".to_string()), + Some(PathBuf::from("/tmp/ca_file")), + Some(PathBuf::from("/tmp/ca_dir")), + Some(PathBuf::from("/tmp/crl_file")), + false + ); + ClientPool::new(uri, Some(ssl_options)); + } } diff --git a/src/collection.rs b/src/collection.rs index 4f0983c..1851fcc 100644 --- a/src/collection.rs +++ b/src/collection.rs @@ -413,7 +413,7 @@ mod tests { #[test] fn test_command() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let collection = client.get_collection("rust_driver_test", "items"); @@ -427,7 +427,7 @@ mod tests { #[test] fn test_mutation_and_finding() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let mut collection = client.get_collection("rust_driver_test", "items"); collection.drop().unwrap_or(()); @@ -510,7 +510,7 @@ mod tests { #[test] fn test_insert_failure() { let uri = Uri::new("mongodb://localhost:27018/"); // There should be no mongo server here - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let collection = client.get_collection("rust_driver_test", "items"); let document = bson::Document::new(); diff --git a/src/cursor.rs b/src/cursor.rs index e80d0a3..25dc22c 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -241,7 +241,7 @@ mod tests { #[test] fn test_cursor() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let mut collection = client.get_collection("rust_driver_test", "cursor_items"); @@ -269,7 +269,7 @@ mod tests { // See: http://api.mongodb.org/c/1.1.8/cursors.html#tailable let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let database = client.get_database("rust_test"); database.get_collection("capped").drop().unwrap_or(()); diff --git a/src/database.rs b/src/database.rs index 37ddf08..7d8b4b1 100644 --- a/src/database.rs +++ b/src/database.rs @@ -140,7 +140,7 @@ mod tests { #[test] fn test_command() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let database = client.get_database("rust_test"); @@ -154,7 +154,7 @@ mod tests { #[test] fn test_get_collection_and_name() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let database = client.get_database("rust_test"); @@ -167,7 +167,7 @@ mod tests { #[test] fn test_create_collection() { let uri = Uri::new("mongodb://localhost:27017/"); - let pool = ClientPool::new(uri); + let pool = ClientPool::new(uri, None); let client = pool.pop(); let database = client.get_database("rust_test"); database.get_collection("created_collection").drop().unwrap_or(()); diff --git a/src/lib.rs b/src/lib.rs index 500a12e..1d2be72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(convert)] + extern crate libc; extern crate mongo_c_driver_wrapper; extern crate bson;