Loading CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ find_package(Brotli REQUIRED) include_directories( ${NETPLUS_INCLUDE_DIRS} ${HTTPPP_INCLUDE_DIRS} ${CRYPTPLUS_INCLUDE_DIRS} ${PostgreSQL_INCLUDE_DIRS} ${SQLite3_INCLUDE_DIRS} Loading plugins/media/backend.h +13 −9 Original line number Diff line number Diff line Loading @@ -25,30 +25,34 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #pragma once #include <string> #include <vector> #include <hiredis/hiredis.h> #include <httppp/http.h> namespace blogi { class Store { public: Store(){}; virtual ~Store(){}; virtual void save(const std::string key,const std::vector<char> value)=0; virtual void load(const std::string key,std::vector<char> &value) =0; virtual void save(const char *key, const char *data,size_t datalen)=0; virtual void load(libhttppp::HttpRequest *req,const char *key,const char *ctype) =0; }; class RedisStore : public Store { public: RedisStore(const char *host,int port,const char *password=nullptr); void save(const std::string key,const std::vector<char> value) override; void load(const std::string key,std::vector<char> &value) override; ~RedisStore(); void save(const char *key,const char *data,size_t datalen) override; void load(libhttppp::HttpRequest *req,const char *key,const char *ctype) override; private: void _reconnect(); redisContext *_RedisCTX; std::string _host; int _port; std::string _pw; std::string _RedisPassword; }; }; plugins/media/media.cpp +8 −16 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ namespace blogi { Args->database->exec(&sql,res); sql.clear(); _store->save(cfuuid,mediafile); _store->save(cfuuid,mediafile.data(),mediafile.size()); } Loading Loading @@ -512,13 +512,11 @@ namespace blogi { if(mlen-plen<0) return false; std::string suuid; std::vector<char> suuid; size_t tpos=std::string::npos; suuid.resize(mlen-plen); for(size_t i = mlen; i>plen; --i){ if(ccurl[i]=='.'){ tpos=i; Loading @@ -533,26 +531,20 @@ namespace blogi { blogi::SQL sql; blogi::DBResult res; sql << "SELECT media_type.ctype from media_items_files LEFT JOIN media_type ON media_type.id=media_type.id WHERE redis_uuid='"; sql.escaped(suuid.c_str()) <<"'"; sql << "SELECT media_type.ctype from media_items_files LEFT JOIN media_type ON media_type.id=media_type.id WHERE media_items_files.redis_uuid='"; sql.escaped(suuid.data()) <<"'"; int n = Args->database->exec(&sql,res); libhttppp::HttpResponse curres; curres.setVersion(HTTPVERSION(1.1)); std::vector<char> value; if(n>0){ _store->load(suuid,value); curres.setContentType(res[0][0]); curres.setState(HTTP200); _store->load(req,suuid.data(),res[0][0]); }else{ libhttppp::HttpResponse curres; curres.setVersion(HTTPVERSION(1.1)); curres.setState(HTTP404); curres.send(req,nullptr,0); curres.send(req,nullptr,-1); } curres.send(req, value.data(), value.size()); return true; } return false; Loading plugins/media/redis.cpp +44 −73 Original line number Diff line number Diff line Loading @@ -26,24 +26,20 @@ *******************************************************************************/ #include <iostream> #include <algorithm> #include <cstring> #include <thread> #include <httppp/exception.h> #include <mutex> #include <httppp/httpd.h> #include "backend.h" std::mutex recon_mutex; blogi::RedisStore::RedisStore(const char *host,int port,const char *password){ _host=host; _port=port; timeval retime; retime.tv_usec=100; struct timeval timeout = { 1, 0 }; // 1.5 seconds _RedisCTX=redisConnectWithTimeout(host,port,retime); _RedisCTX=redisConnectWithTimeout(host,port,timeout); if (_RedisCTX->err) { libhttppp::HTTPException exp; Loading @@ -52,78 +48,53 @@ blogi::RedisStore::RedisStore(const char *host,int port,const char *password){ } if(password){ _pw=password; redisReply *reply = (redisReply*)redisCommand(_RedisCTX, "AUTH %s", password); if (reply->type == REDIS_REPLY_ERROR) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); _RedisPassword=password; redisCommand(_RedisCTX,"AUTH %s", password); } } void blogi::RedisStore::save(const std::string key, const std::vector<char> value){ libhttppp::HTTPException exp; redisReply* reply = (redisReply*) redisCommand(_RedisCTX,"SET %s %b",key.c_str(),value.data(),value.size()); if (reply && reply->type==REDIS_REPLY_ERROR) { _reconnect(); freeReplyObject(reply); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; blogi::RedisStore::~RedisStore(){ redisFree(_RedisCTX); } freeReplyObject(reply); reply = (redisReply*) redisCommand(_RedisCTX, "save"); if (reply && reply->type==REDIS_REPLY_ERROR) { _reconnect(); freeReplyObject(reply); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } void blogi::RedisStore::save(const char *key, const char *data,size_t datalen){ redisCommand(_RedisCTX,"SET %s %b",key,data,datalen); redisCommand(_RedisCTX,"save"); } void blogi::RedisStore::load(const std::string key,std::vector<char> &value) { redisReply* reply = (redisReply*) redisCommand(_RedisCTX, "GET %s",key.c_str()); if(reply && reply->type!=REDIS_REPLY_ERROR){ std::copy(reply->str,reply->str+reply->len,std::inserter<std::vector<char>>(value,value.begin())); }else{ freeReplyObject(reply); _reconnect(); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); void blogi::RedisStore::load(libhttppp::HttpRequest *req,const char *key,const char *ctype) { if(strlen(ctype)>255){ libhttppp::HTTPException e; e[libhttppp::HTTPException::Error] << "media plugin err: " << "ctype to long nor more the 255 signs are allowed !"; throw e; } void blogi::RedisStore::_reconnect(){ const std::lock_guard<std::mutex> lock(recon_mutex); redisReconnect(_RedisCTX); std::thread t1([this,req,key,ctype](){ try{ redisReply *rep=(redisReply*)redisCommand(_RedisCTX,"GET %s",key); if (_RedisCTX->err) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; if(_RedisCTX->err!=REDIS_OK){ libhttppp::HTTPException e; e[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw e; } if(!_pw.empty()){ redisReply *reply = (redisReply*)redisCommand(_RedisCTX, "AUTH %s", _pw.c_str()); if (reply->type == REDIS_REPLY_ERROR) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); libhttppp::HttpResponse curres; curres.setContentType(ctype); curres.setState(HTTP200); curres.setContentLength(rep->len); curres.send(req,nullptr,-1); std::copy(rep->str,rep->str+rep->len,std::inserter<std::vector<char>>(req->SendData,req->SendData.end())); freeReplyObject(rep); req->sending(true); }catch(libhttppp::HTTPException e){ libhttppp::HttpResponse curres; curres.setContentType(ctype); curres.setState(HTTP501); curres.send(req,e.what(),strlen(e.what())); } }); t1.join(); } Loading
CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ find_package(Brotli REQUIRED) include_directories( ${NETPLUS_INCLUDE_DIRS} ${HTTPPP_INCLUDE_DIRS} ${CRYPTPLUS_INCLUDE_DIRS} ${PostgreSQL_INCLUDE_DIRS} ${SQLite3_INCLUDE_DIRS} Loading
plugins/media/backend.h +13 −9 Original line number Diff line number Diff line Loading @@ -25,30 +25,34 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #pragma once #include <string> #include <vector> #include <hiredis/hiredis.h> #include <httppp/http.h> namespace blogi { class Store { public: Store(){}; virtual ~Store(){}; virtual void save(const std::string key,const std::vector<char> value)=0; virtual void load(const std::string key,std::vector<char> &value) =0; virtual void save(const char *key, const char *data,size_t datalen)=0; virtual void load(libhttppp::HttpRequest *req,const char *key,const char *ctype) =0; }; class RedisStore : public Store { public: RedisStore(const char *host,int port,const char *password=nullptr); void save(const std::string key,const std::vector<char> value) override; void load(const std::string key,std::vector<char> &value) override; ~RedisStore(); void save(const char *key,const char *data,size_t datalen) override; void load(libhttppp::HttpRequest *req,const char *key,const char *ctype) override; private: void _reconnect(); redisContext *_RedisCTX; std::string _host; int _port; std::string _pw; std::string _RedisPassword; }; };
plugins/media/media.cpp +8 −16 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ namespace blogi { Args->database->exec(&sql,res); sql.clear(); _store->save(cfuuid,mediafile); _store->save(cfuuid,mediafile.data(),mediafile.size()); } Loading Loading @@ -512,13 +512,11 @@ namespace blogi { if(mlen-plen<0) return false; std::string suuid; std::vector<char> suuid; size_t tpos=std::string::npos; suuid.resize(mlen-plen); for(size_t i = mlen; i>plen; --i){ if(ccurl[i]=='.'){ tpos=i; Loading @@ -533,26 +531,20 @@ namespace blogi { blogi::SQL sql; blogi::DBResult res; sql << "SELECT media_type.ctype from media_items_files LEFT JOIN media_type ON media_type.id=media_type.id WHERE redis_uuid='"; sql.escaped(suuid.c_str()) <<"'"; sql << "SELECT media_type.ctype from media_items_files LEFT JOIN media_type ON media_type.id=media_type.id WHERE media_items_files.redis_uuid='"; sql.escaped(suuid.data()) <<"'"; int n = Args->database->exec(&sql,res); libhttppp::HttpResponse curres; curres.setVersion(HTTPVERSION(1.1)); std::vector<char> value; if(n>0){ _store->load(suuid,value); curres.setContentType(res[0][0]); curres.setState(HTTP200); _store->load(req,suuid.data(),res[0][0]); }else{ libhttppp::HttpResponse curres; curres.setVersion(HTTPVERSION(1.1)); curres.setState(HTTP404); curres.send(req,nullptr,0); curres.send(req,nullptr,-1); } curres.send(req, value.data(), value.size()); return true; } return false; Loading
plugins/media/redis.cpp +44 −73 Original line number Diff line number Diff line Loading @@ -26,24 +26,20 @@ *******************************************************************************/ #include <iostream> #include <algorithm> #include <cstring> #include <thread> #include <httppp/exception.h> #include <mutex> #include <httppp/httpd.h> #include "backend.h" std::mutex recon_mutex; blogi::RedisStore::RedisStore(const char *host,int port,const char *password){ _host=host; _port=port; timeval retime; retime.tv_usec=100; struct timeval timeout = { 1, 0 }; // 1.5 seconds _RedisCTX=redisConnectWithTimeout(host,port,retime); _RedisCTX=redisConnectWithTimeout(host,port,timeout); if (_RedisCTX->err) { libhttppp::HTTPException exp; Loading @@ -52,78 +48,53 @@ blogi::RedisStore::RedisStore(const char *host,int port,const char *password){ } if(password){ _pw=password; redisReply *reply = (redisReply*)redisCommand(_RedisCTX, "AUTH %s", password); if (reply->type == REDIS_REPLY_ERROR) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); _RedisPassword=password; redisCommand(_RedisCTX,"AUTH %s", password); } } void blogi::RedisStore::save(const std::string key, const std::vector<char> value){ libhttppp::HTTPException exp; redisReply* reply = (redisReply*) redisCommand(_RedisCTX,"SET %s %b",key.c_str(),value.data(),value.size()); if (reply && reply->type==REDIS_REPLY_ERROR) { _reconnect(); freeReplyObject(reply); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; blogi::RedisStore::~RedisStore(){ redisFree(_RedisCTX); } freeReplyObject(reply); reply = (redisReply*) redisCommand(_RedisCTX, "save"); if (reply && reply->type==REDIS_REPLY_ERROR) { _reconnect(); freeReplyObject(reply); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } void blogi::RedisStore::save(const char *key, const char *data,size_t datalen){ redisCommand(_RedisCTX,"SET %s %b",key,data,datalen); redisCommand(_RedisCTX,"save"); } void blogi::RedisStore::load(const std::string key,std::vector<char> &value) { redisReply* reply = (redisReply*) redisCommand(_RedisCTX, "GET %s",key.c_str()); if(reply && reply->type!=REDIS_REPLY_ERROR){ std::copy(reply->str,reply->str+reply->len,std::inserter<std::vector<char>>(value,value.begin())); }else{ freeReplyObject(reply); _reconnect(); libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); void blogi::RedisStore::load(libhttppp::HttpRequest *req,const char *key,const char *ctype) { if(strlen(ctype)>255){ libhttppp::HTTPException e; e[libhttppp::HTTPException::Error] << "media plugin err: " << "ctype to long nor more the 255 signs are allowed !"; throw e; } void blogi::RedisStore::_reconnect(){ const std::lock_guard<std::mutex> lock(recon_mutex); redisReconnect(_RedisCTX); std::thread t1([this,req,key,ctype](){ try{ redisReply *rep=(redisReply*)redisCommand(_RedisCTX,"GET %s",key); if (_RedisCTX->err) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; if(_RedisCTX->err!=REDIS_OK){ libhttppp::HTTPException e; e[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw e; } if(!_pw.empty()){ redisReply *reply = (redisReply*)redisCommand(_RedisCTX, "AUTH %s", _pw.c_str()); if (reply->type == REDIS_REPLY_ERROR) { libhttppp::HTTPException exp; exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr; throw exp; } freeReplyObject(reply); libhttppp::HttpResponse curres; curres.setContentType(ctype); curres.setState(HTTP200); curres.setContentLength(rep->len); curres.send(req,nullptr,-1); std::copy(rep->str,rep->str+rep->len,std::inserter<std::vector<char>>(req->SendData,req->SendData.end())); freeReplyObject(rep); req->sending(true); }catch(libhttppp::HTTPException e){ libhttppp::HttpResponse curres; curres.setContentType(ctype); curres.setState(HTTP501); curres.send(req,e.what(),strlen(e.what())); } }); t1.join(); }