From 83752e472c35632174534763dffd312fc120a429 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=9F=D1=80?=
 =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B7=D0=B0=D0=BD=D0=BE=D0=B2?=
 <weirdcarrotmonster@gmail.com>
Date: Fri, 10 Apr 2015 22:56:59 +0400
Subject: [PATCH 1/3] Updated GridFS plugin to work with legacy
 mongo-cxx-driver version 1.0.0

---
 plugins/gridfs/gridfs.cc      | 53 +++++++++++++++++++++++++++++++++----------
 plugins/gridfs/uwsgiplugin.py |  7 +++---
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/plugins/gridfs/gridfs.cc b/plugins/gridfs/gridfs.cc
index d11451a..81ff0d9 100644
--- a/plugins/gridfs/gridfs.cc
+++ b/plugins/gridfs/gridfs.cc
@@ -1,3 +1,7 @@
+#include <memory>
+#include <vector>
+#include <cstring>
+
 #include <uwsgi.h>
 
 #include <client/dbclient.h>
@@ -7,6 +11,7 @@ struct uwsgi_gridfs_mountpoint {
 	char *mountpoint;
 	uint16_t mountpoint_len;
 	char *server;
+	char *replica;
 	char *db;
 	char *timeout_str;
 	int timeout;
@@ -21,6 +26,7 @@ struct uwsgi_gridfs_mountpoint {
 	uint16_t prefix_len;
 	char *username;
 	char *password;
+	std::vector<mongo::HostAndPort> servers;
 };
 
 struct uwsgi_gridfs {
@@ -38,33 +44,44 @@ extern struct uwsgi_server uwsgi;
 extern struct uwsgi_plugin gridfs_plugin;
 
 static void uwsgi_gridfs_do(struct wsgi_request *wsgi_req, struct uwsgi_gridfs_mountpoint *ugm, char *itemname, int need_free) {
-
 	try {
-		mongo::scoped_ptr<mongo::ScopedDbConnection> conn( mongo::ScopedDbConnection::getScopedDbConnection(ugm->server, ugm->timeout) );
+		std::unique_ptr<mongo::DBClientBase> conn;
+
+		if (ugm->replica) {
+			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientReplicaSet(ugm->replica, ugm->servers));
+			dynamic_cast<mongo::DBClientReplicaSet *>(conn.get())->connect();
+		}
+		else {
+			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientConnection());
+			dynamic_cast<mongo::DBClientConnection *>(conn.get())->connect(ugm->server);
+		}
+		
 		try {
 			if (ugm->username && ugm->password) {
 				std::string errmsg;
-				if ((*conn).conn().auth(ugm->db, ugm->username, ugm->password, errmsg)) {
+				if (!conn->auth(ugm->db, ugm->username, ugm->password, errmsg)) {
 					uwsgi_log("[uwsgi-gridfs]: %s\n", errmsg.c_str());
-					(*conn).done();
 					uwsgi_403(wsgi_req);
 					return;
 				}
 			}
-			mongo::GridFS gridfs((*conn).conn(), ugm->db);
-			mongo::GridFile gfile = gridfs.findFile(itemname);
+			mongo::GridFS gridfs((*conn.get()), ugm->db);
+			mongo::GridFile gfile = gridfs.findFileByName(itemname);
+
 			if (need_free) {
 				free(itemname);
 				itemname = NULL;
 			}
+
 			if (!gfile.exists()) {
-				(*conn).done();
 				uwsgi_404(wsgi_req);
 				return;
 			}
+
 			uwsgi_response_prepare_headers(wsgi_req, (char *)"200 OK", 6);
 			// first get the content_type (if possibile)
 			std::string filename = gfile.getFilename();
+
 			if (!ugm->no_mime) {
 				size_t mime_type_len = 0;
 				char *mime_type = uwsgi_get_mime_type((char *)filename.c_str(), filename.length(), &mime_type_len);
@@ -72,11 +89,13 @@ static void uwsgi_gridfs_do(struct wsgi_request *wsgi_req, struct uwsgi_gridfs_m
 					uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len);
 				}
 			}
+
 			if (ugm->orig_filename) {
 				char *filename_header = uwsgi_concat3((char *)"inline; filename=\"", (char *)filename.c_str(), (char *)"\"");
 				uwsgi_response_add_header(wsgi_req, (char *)"Content-Disposition", 19, filename_header, 19 + filename.length());
 				free(filename_header);
 			}
+
 			uwsgi_response_add_content_length(wsgi_req, gfile.getContentLength());
 
 			char http_last_modified[49];
@@ -90,7 +109,7 @@ static void uwsgi_gridfs_do(struct wsgi_request *wsgi_req, struct uwsgi_gridfs_m
 					char *etag = uwsgi_concat3((char *)"\"", (char *)g_md5.c_str(), (char *)"\"");
 					uwsgi_response_add_header(wsgi_req, (char *)"ETag", 4, etag, 2+g_md5.length());
 					free(etag);
-				}	
+				}
 			}
 
 			if (ugm->md5) {
@@ -106,22 +125,20 @@ static void uwsgi_gridfs_do(struct wsgi_request *wsgi_req, struct uwsgi_gridfs_m
 				int i;
 				for(i=0;i<nc;i++) {
 					mongo::GridFSChunk gchunk = gfile.getChunk(i);
-					int chunk_len = 0;	
+					int chunk_len = 0;
 					const char *chunk = gchunk.data(chunk_len);
 					uwsgi_response_write_body_do(wsgi_req, (char *) chunk, chunk_len);
 				}
 			}
-			(*conn).done();
 		}
 		catch ( mongo::DBException &e ) {
 			uwsgi_log("[uwsgi-gridfs]: %s\n", e.what());
-			(*conn).done();
 			if (need_free && itemname) {
 				free(itemname);
 				itemname = NULL;
 			}
 		}
-	}	
+	}
 	catch ( mongo::DBException &e ) {
 		uwsgi_log("[uwsgi-gridfs]: %s\n", e.what());
 		if (need_free && itemname) {
@@ -137,6 +154,7 @@ static struct uwsgi_gridfs_mountpoint *uwsgi_gridfs_add_mountpoint(char *arg, si
 	if (uwsgi_kvlist_parse(arg, arg_len, ',', '=',
                         "mountpoint", &ugm->mountpoint,
                         "server", &ugm->server,
+                        "replica", &ugm->replica,
                         "db", &ugm->db,
                         "prefix", &ugm->prefix,
                         "no_mime", &ugm->no_mime,
@@ -185,6 +203,16 @@ static struct uwsgi_gridfs_mountpoint *uwsgi_gridfs_add_mountpoint(char *arg, si
 		ugm->itemname_len = strlen(ugm->itemname);
 	}
 
+	if (ugm->replica) {
+		std::string buffer(ugm->server);
+		
+		size_t pos;
+		while ((pos = buffer.find(",")) != std::string::npos) {
+			ugm->servers.push_back(mongo::HostAndPort(buffer.substr(0, pos)));
+			buffer.erase(0, pos + 1);
+		}
+	}
+
 	return ugm;
 }
 
@@ -236,6 +264,7 @@ extern "C" int uwsgi_gridfs_request(struct wsgi_request *wsgi_req) {
 
 
 extern "C" void uwsgi_gridfs_mount() {
+	mongo::client::initialize();
 	if (!uwsgi.skip_atexit) {
 		uwsgi_log("*** WARNING libmongoclient could have a bug with atexit() hooks, if you get segfault on end/reload, add --skip-atexit ***\n");
 	}
diff --git a/plugins/gridfs/uwsgiplugin.py b/plugins/gridfs/uwsgiplugin.py
index a2163d7..61567bc 100644
--- a/plugins/gridfs/uwsgiplugin.py
+++ b/plugins/gridfs/uwsgiplugin.py
@@ -1,16 +1,17 @@
 import os
 
-NAME='gridfs'
+NAME = 'gridfs'
 
-CFLAGS = ['-I/usr/include/mongo','-I/usr/local/include/mongo']
+CFLAGS = ['-I/usr/include/mongo', '-I/usr/local/include/mongo', '-std=c++11', '-Wno-error']
 LDFLAGS = []
 
 LIBS = []
-if not 'UWSGI_MONGODB_NOLIB' in os.environ:
+if 'UWSGI_MONGODB_NOLIB' not in os.environ:
     LIBS.append('-lmongoclient')
     LIBS.append('-lstdc++')
     LIBS.append('-lboost_thread')
     LIBS.append('-lboost_system')
     LIBS.append('-lboost_filesystem')
+    LIBS.append('-lboost_regex')
 
 GCC_LIST = ['plugin', 'gridfs.cc']
-- 
2.1.0


From 932caed82a2338e0f1bd5d68833ca5c31360b882 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=9F=D1=80?=
 =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B7=D0=B0=D0=BD=D0=BE=D0=B2?=
 <weirdcarrotmonster@gmail.com>
Date: Fri, 10 Apr 2015 23:07:41 +0400
Subject: [PATCH 2/3] Fixed server list parsing

---
 plugins/gridfs/gridfs.cc | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/plugins/gridfs/gridfs.cc b/plugins/gridfs/gridfs.cc
index 81ff0d9..f58d976 100644
--- a/plugins/gridfs/gridfs.cc
+++ b/plugins/gridfs/gridfs.cc
@@ -211,6 +211,10 @@ static struct uwsgi_gridfs_mountpoint *uwsgi_gridfs_add_mountpoint(char *arg, si
 			ugm->servers.push_back(mongo::HostAndPort(buffer.substr(0, pos)));
 			buffer.erase(0, pos + 1);
 		}
+
+		if (!ugm->servers.size()) {
+			ugm->servers.push_back(mongo::HostAndPort(ugm->server));
+		}
 	}
 
 	return ugm;
-- 
2.1.0


From a870dbfb0dc4268cbcecf573765338ec5a52f195 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=9F=D1=80?=
 =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B7=D0=B0=D0=BD=D0=BE=D0=B2?=
 <weirdcarrotmonster@gmail.com>
Date: Fri, 10 Apr 2015 23:38:38 +0400
Subject: [PATCH 3/3] Passing timeout argument to MongoDB connection

---
 plugins/gridfs/gridfs.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/gridfs/gridfs.cc b/plugins/gridfs/gridfs.cc
index f58d976..5f7c4ba 100644
--- a/plugins/gridfs/gridfs.cc
+++ b/plugins/gridfs/gridfs.cc
@@ -48,14 +48,14 @@ static void uwsgi_gridfs_do(struct wsgi_request *wsgi_req, struct uwsgi_gridfs_m
 		std::unique_ptr<mongo::DBClientBase> conn;
 
 		if (ugm->replica) {
-			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientReplicaSet(ugm->replica, ugm->servers));
+			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientReplicaSet(ugm->replica, ugm->servers, ugm->timeout));
 			dynamic_cast<mongo::DBClientReplicaSet *>(conn.get())->connect();
 		}
 		else {
-			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientConnection());
+			conn = std::unique_ptr<mongo::DBClientBase> (new mongo::DBClientConnection(true, 0, ugm->timeout));
 			dynamic_cast<mongo::DBClientConnection *>(conn.get())->connect(ugm->server);
 		}
-		
+
 		try {
 			if (ugm->username && ugm->password) {
 				std::string errmsg;
-- 
2.1.0

