Commit 03547621 authored by jan.koester's avatar jan.koester
Browse files

redis can reconnect

parent 0df7dd28
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
find_package(Hiredis REQUIRED)

add_library(media SHARED media.cpp)
add_library(media SHARED media.cpp redis.cpp)

target_include_directories(media PUBLIC
    ${Hiredis_INCLUDE_DIRS}
+50 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Copyright (c) 2024, Jan Koester jan.koester@gmx.net
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

#include <string>

#include <hiredis/hiredis.h>

namespace blogi {
    class Store {
    public:
        Store(){};
        virtual ~Store(){};
        virtual void save(const std::string key,const std::string value)=0;
        virtual void load(const std::string key,std::string &value)=0;
    };

    class RedisStore : public Store {
    public:
        RedisStore(const char *host,int port,const char *password=nullptr);
        void save(const std::string key,const std::string value) override;
        void load(const std::string key,std::string &value) override;
    private:
        bool reconnect();
        redisContext *_RedisCTX;
    };
};
+18 −32
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
 *******************************************************************************/

#include <uuid/uuid.h>
#include <hiredis/hiredis.h>

#include <htmlpp/html.h>
#include <httppp/http.h>
@@ -35,12 +34,19 @@

#include "icon.webp.h"
#include "types.h"
#include "backend.h"

namespace blogi {
    class Media : public PluginApi {
    public:
        Media(){
            _store=nullptr;
        }

        ~Media(){
            delete _store;
        }

        const char* getName(){
            return "media";
        }
@@ -147,7 +153,7 @@ namespace blogi {

        void uploadMedia(int id,libhttppp::HttpForm::MultipartFormData *dat,libhttppp::HttpRequest * req, libhtmlpp::HtmlString & setdiv){
            char url[512];
            std::string mediafile,mediafilename;
            std::string mediafilename,mediafile;

            if(dat){
                for (libhttppp::HttpForm::MultipartFormData *curformdat = dat; curformdat; curformdat = curformdat->nextMultipartFormData()) {
@@ -213,12 +219,7 @@ namespace blogi {
                    Args->database->exec(&sql,res);
                    sql.clear();

                    std::string rediscmd;

                    redisCommand(_RedisCTX,"SET %s %b",cfuuid,
                                 mediafile.c_str(),
                                 mediafile.length());
                    redisCommand(_RedisCTX, "save");
                    _store->save(cfuuid,mediafile);
                }

            }
@@ -473,24 +474,11 @@ namespace blogi {

            Args->edit->addIcon(icondata,icondatalen,"selimage","webp","Insert Image from media albums");

            _RedisCTX=redisConnect(Args->config->getRedisHost(),Args->config->getRedisPort());

            if (_RedisCTX->err) {
                libhttppp::HTTPException exp;
                exp[libhttppp::HTTPException::Warning] << "media plugin err: " << _RedisCTX->errstr;
                throw exp;
            }

            if(Args->config->getRedisPassword()){
                redisReply *reply = (redisReply*)redisCommand(_RedisCTX, "AUTH %s", Args->config->getRedisPassword());
                if (reply->type == REDIS_REPLY_ERROR) {
                    libhttppp::HTTPException exp;
                    exp[libhttppp::HTTPException::Warning] << "media plugin err: " << _RedisCTX->errstr;
                    throw exp;
                }
                freeReplyObject(reply);
                _store = new RedisStore(Args->config->getRedisHost(),Args->config->getRedisPort(),Args->config->getRedisPassword());
            }else{
                _store = new RedisStore(Args->config->getRedisHost(),Args->config->getRedisPort());
            }

        }

        bool Controller(netplus::con *curcon,libhttppp::HttpRequest *req,libhtmlpp::HtmlElement page){
@@ -522,16 +510,14 @@ namespace blogi {
                if(n>0){
                    curres.setContentType(res[0][0]);
                    curres.setState(HTTP200);
                    redisReply* reply = (redisReply*) redisCommand(_RedisCTX, "GET %s",suuid.c_str());
                    int state = 0;
                    if(!reply->str){
                        freeReplyObject(reply);
                    try{
                        std::string value;
                        _store->load(suuid,value);
                        curres.send(curcon, value.c_str(), value.length());
                    }catch(...){
                        curres.setState(HTTP404);
                        curres.send(curcon,nullptr,0);
                        return true;
                    }
                    curres.send(curcon, reply->str, reply->len);
                    freeReplyObject(reply);
                }else{
                    curres.setState(HTTP404);
                    curres.send(curcon,nullptr,0);
@@ -541,7 +527,7 @@ namespace blogi {
            return false;
        }
    private:
        redisContext *_RedisCTX;
        Store *_store;
    };
};

+83 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Copyright (c) 2024, Jan Koester jan.koester@gmx.net
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

#include <httppp/exception.h>

#include "backend.h"

blogi::RedisStore::RedisStore(const char *host,int port,const char *password){
    _RedisCTX=redisConnect(host,port);

    if (_RedisCTX->err) {
        libhttppp::HTTPException exp;
        exp[libhttppp::HTTPException::Error] << "media plugin err: " << _RedisCTX->errstr;
        throw exp;
    }

    if(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);
    }

}
void blogi::RedisStore::save(const std::string key, const std::string value){
REDISSAVE:
    redisCommand(_RedisCTX,"SET %s %b",key.c_str(),value.c_str(),value.length());
    redisCommand(_RedisCTX, "save");
    if (_RedisCTX->err) {
        if(reconnect())
            goto REDISSAVE;
    }
}

void blogi::RedisStore::load(const std::string key,std::string &value){
REDISLOAD:
    redisReply* reply = (redisReply*) redisCommand(_RedisCTX, "GET %s",key.c_str());
    int state = 0;
    if(reply->str){
        value.resize(reply->len);
        value=reply->str;
    }else{
        if(reconnect())
            goto REDISLOAD;
        freeReplyObject(reply);
        libhttppp::HTTPException exp;
        exp[libhttppp::HTTPException::Warning] << "media plugin err: " << _RedisCTX->errstr;
        throw exp;
    }
    freeReplyObject(reply);
}

bool blogi::RedisStore::reconnect(){
    return redisReconnect(_RedisCTX);
}