summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project2/json/couchSession.cpp188
1 files changed, 0 insertions, 188 deletions
diff --git a/project2/json/couchSession.cpp b/project2/json/couchSession.cpp
deleted file mode 100644
index 51d466c..0000000
--- a/project2/json/couchSession.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <pch.hpp>
-#include "curlHelper.h"
-#include "safeMapFind.h"
-#include "exceptions.h"
-#include "logger.h"
-#include "buffer.h"
-#include "curlsup.h"
-#include <scriptLoader.h>
-#include <sessionContainer.h>
-#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/uuid/uuid_io.hpp>
-#include <boost/uuid/uuid_generators.hpp>
-#include "jsonpp.h"
-#include "safeMapFind.h"
-#include "conversion.h"
-#include "options.h"
-
-class CouchDBFailure : public std::exception { };
-
-class CouchSessionContainer : public SessionContainer {
- public:
- CouchSessionContainer() {
- }
- virtual SessionPtr getSession(const boost::uuids::uuid & uuid) const {
- try {
- json::Object obj = getSessionFromServer(uuid);
- if (boost::get<json::Number>(*safeMapLookup<Session::VariableNotFound>(obj, ExpiryKey)) > time(NULL)) {
- SessionPtr s = new Session(uuid);
- for (const json::Object::value_type & v : obj) {
- s->SetValue(v.first, boost::apply_visitor(JsonToProject2(), *v.second));
- }
- return s;
- }
- }
- catch (...) {
- }
- return NULL;
- }
-
- virtual void SaveSession(SessionPtr s) const {
- CurlPtr c = new Curl();
- c->setopt(CURLOPT_UPLOAD, 1L);
- c->setopt(CURLOPT_FAILONERROR, 1);
- json::Object obj;
- s->ForeachValue(boost::bind(&CouchSessionContainer::addToObject, &obj, _1, _2));
- obj[ExpiryKey] = json::ValuePtr(new json::Value((json::Number)s->ExpiryTime()));
- Glib::ustring out = json::serializeObject(obj, "utf-8");
- c->setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)out.size());
- unsigned int off = 0;
- for (const std::string & b : baseUrls) {
- c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(s->ID())).c_str());
- try {
- c->performSend(boost::bind(send, &out, &off, _1, _2));
- return;
- }
- catch (...) {
- }
- }
- throw CouchDBFailure();
- }
-
- json::Object getSessionFromServer(const boost::uuids::uuid & uuid) const {
- CurlPtr c = new Curl();
- c->setopt(CURLOPT_FAILONERROR, 1);
- Glib::ustring msg;
- for (const std::string & b : baseUrls) {
- try {
- c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(uuid)).c_str());
- c->performRead(boost::bind(append, &msg, _1, _2));
- json::Object o = json::parseObject(msg);
- return o;
- }
- catch (...) {
- }
- }
- throw CouchDBFailure();
- }
-
- private:
- static void addToObject(json::Object * obj, const Glib::ustring & name, const VariableType & value) {
- (*obj)[name] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value)));
- }
-
- static size_t send(Glib::ustring * buf, unsigned int * off, char * str, size_t l) {
- size_t len = std::min(buf->size() - *off, l);
- memcpy(str, buf->c_str() + *off, len);
- return len;
- }
-
- static size_t append(Glib::ustring * buf, const char * str, size_t l) {
- buf->append(str, l);
- return l;
- }
-
- void setopt_s(CurlHandle::Ptr c, CURLoption o, const char * v) {
- c->setopt(o, v);
- }
-
- void setopt_l(CurlHandle::Ptr c, CURLoption o, int64_t v) {
- c->setopt(o, (long)v);
- }
-
- static std::vector<std::string> baseUrls;
- static const Glib::ustring ExpiryKey;
- friend class CustomCouchSessionLoader;
-};
-std::vector<std::string> CouchSessionContainer::baseUrls;
-const Glib::ustring CouchSessionContainer::ExpiryKey("project2:expires");
-
-class CustomCouchSessionLoader : public SessionContainerLoader::For<CouchSessionContainer> {
- public:
- void onPeriodic() override {
- try {
- deleteSessions();
- compactDB();
- }
- catch (...) {
- Logger()->messagebf(LOG_WARNING, "Failed to purge expired sessions and compact DB");
- }
- }
-
- INITOPTIONS;
- private:
- static size_t discard(size_t l) {
- return l;
- }
-
- void compactDB() {
- CurlPtr c = new Curl();
- c->setopt(CURLOPT_POST, 1);
- c->appendHeader("Content-Type: application/json");
- for (const std::string & b : CouchSessionContainer::baseUrls) {
- c->setopt(CURLOPT_URL, (b + "_compact").c_str());
- c->performRead(boost::bind(discard, _2));
- }
- }
- void deleteSessions() {
- // Create the server side search map
- json::Object map;
- Buffer mapBuf;
- mapBuf.appendf("function(doc) { var exp = doc['%s']; if (exp < %u) { emit(exp, doc._rev); } }",
- CouchSessionContainer::ExpiryKey.c_str(), (unsigned int)time(NULL));
- map["map"] = json::ValuePtr(new json::Value(mapBuf.str()));
- Glib::ustring mapStr(json::serializeObject(map, "utf-8"));
- // Create the CURL handle
- CurlPtr c = new Curl();
- c->setopt(CURLOPT_FAILONERROR, 1);
- c->appendHeader("Content-Type: application/json");
- c->setopt(CURLOPT_POST, 1);
- c->setopt(CURLOPT_POSTFIELDS, mapStr.c_str());
- c->setopt(CURLOPT_POSTFIELDSIZE, mapStr.bytes());
- for (const std::string & b : CouchSessionContainer::baseUrls) {
- Glib::ustring msg;
- try {
- c->setopt(CURLOPT_URL, (b + "_temp_view").c_str());
- c->performRead(boost::bind(CouchSessionContainer::append, &msg, _1, _2));
- json::Object o = json::parseObject(msg);
- for (const json::Array::value_type & v : boost::get<json::Array>(*safeMapLookup<ParamNotFound>(o, "rows"))) {
- json::Object rec = boost::get<json::Object>(*v);
- boost::uuids::uuid u = boost::uuids::string_generator()(boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "id")).raw());
- Glib::ustring & rev = boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "value"));
- deleteSession(u, rev);
- }
- return;
- }
- catch (...) {
- }
- }
- }
-
- void deleteSession(const boost::uuids::uuid & sid, const Glib::ustring & rev) const {
- CurlPtr c = new Curl();
- c->setopt(CURLOPT_CUSTOMREQUEST, "DELETE");
- for (const std::string & b : CouchSessionContainer::baseUrls) {
- c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(sid) + "?rev=" + rev).c_str());
- c->performRead(boost::bind(discard, _2));
- return;
- }
- }
-};
-DECLARE_CUSTOM_COMPONENT_LOADER("couchsession", CouchSessionContainer, CustomCouchSessionLoader, SessionContainerLoader);
-
-DECLARE_OPTIONS(CustomCouchSessionLoader, "Session CouchDB options")
-("session.couchdb.baseUrl", Options::functions([](const VariableType & v) { CouchSessionContainer::baseUrls.push_back(v); }, boost::bind(&std::vector<std::string>::clear, &CouchSessionContainer::baseUrls)),
- "Base URL to store sessions in")
-END_OPTIONS(CustomCouchSessionLoader);
-