add Session class;use pimpl in HttpAppFramework class

This commit is contained in:
an-tao 2018-05-09 16:14:21 +08:00
parent 4e4fc60b12
commit dacc5c555e
7 changed files with 178 additions and 62 deletions

View File

@ -41,7 +41,7 @@ if(Boost_FOUND)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=${CMAKE_CXX_STD_FLAGS} -fpermissive -g -ggdb")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=${CMAKE_CXX_STD_FLAGS} -g -ggdb -Wall")
#string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")

View File

@ -1,5 +1,6 @@
#include <drogon/HttpAppFramework.h>
#include <iostream>
#include <drogon/HttpAppFramework.h>
#include <trantor/utils/Logger.h>
static const char banner[]=" _ \n"
" __| |_ __ ___ __ _ ___ _ __ \n"
" / _` | '__/ _ \\ / _` |/ _ \\| '_ \\ \n"

View File

@ -6,42 +6,25 @@
#pragma once
#include <drogon/HttpRequest.h>
#include <drogon/HttpResponse.h>
#include <drogon/CacheMap.h>
//#include <drogon/HttpRequest.h>
//#include <drogon/HttpResponse.h>
//#include <drogon/CacheMap.h>
//#include <drogon/Session.h>
#include <trantor/utils/NonCopyable.h>
#include <memory>
#include <string>
#include <set>
namespace drogon
{
class HttpAppFramework:public trantor::NonCopyable
{
public:
HttpAppFramework()= delete;
HttpAppFramework(const std::string &ip,uint16_t port);
void run();
~HttpAppFramework();
private:
std::string _ip;
uint16_t _port;
void onAsyncRequest(const HttpRequest& req,std::function<void (HttpResponse &)>callback);
void readSendFile(const std::string& filePath,const HttpRequest& req, HttpResponse* resp);
#ifdef USE_UUID
//if uuid package found,we can use a uuid string as session id;
//set _sessionTimeout=0 to disable location session control based on cookies;
uint _sessionTimeout=0;
#endif
bool _enableLastModify=true;
std::set<std::string> _fileTypeSet={"html","jpg"};
std::string _rootPath;
//tool funcs
#ifdef USE_UUID
std::string getUuid();
std::string stringToHex(unsigned char* ptr, long long length);
#endif
bool _run;
std::unique_ptr<class HttpAppFrameworkImpl> _implPtr;
};
}

70
lib/inc/drogon/Session.h Executable file
View File

@ -0,0 +1,70 @@
//
// Copyright 2018, An Tao. All rights reserved.
//
// Use of this source code is governed by a MIT license
// that can be found in the License file.
#pragma once
#ifdef USE_STD_ANY
#include <any>
typedef std::any Any;
#define Any_cast std::any_cast
#elif USE_BOOST
#include <boost/any.hpp>
typedef boost::any Any;
#define Any_cast boost::any_cast
#else
#error,must use c++17 or boost
#endif
typedef std::map<std::string,Any> SessionMap;
class Session
{
public:
template <typename T> T get(const std::string &key) const{
std::lock_guard<std::mutex> lck(mutex_);
auto it=sessionMap_.find(key);
if(it!=sessionMap_.end())
{
return Any_cast<T>(it->second);
}
T tmp;
return tmp;
};
Any &operator[](const std::string &key){
std::lock_guard<std::mutex> lck(mutex_);
return sessionMap_[key];
};
void insert(const std::string& key,const Any &obj)
{
std::lock_guard<std::mutex> lck(mutex_);
sessionMap_[key]=obj;
};
void erase(const std::string& key)
{
std::lock_guard<std::mutex> lck(mutex_);
sessionMap_.erase(key);
}
bool find(const std::string& key)
{
std::lock_guard<std::mutex> lck(mutex_);
if(sessionMap_.find(key) == sessionMap_.end())
{
return false;
}
return true;
}
void clear()
{
std::lock_guard<std::mutex> lck(mutex_);
sessionMap_.clear();
}
protected:
SessionMap sessionMap_;
int timeoutInterval_;
mutable std::mutex mutex_;
};

View File

@ -4,6 +4,10 @@
// that can be found in the License file.
#include <drogon/HttpAppFramework.h>
#include <drogon/HttpRequest.h>
#include <drogon/HttpResponse.h>
#include <drogon/CacheMap.h>
#include <drogon/Session.h>
#include "HttpServer.h"
#include <sys/stat.h>
#include <iostream>
@ -11,41 +15,77 @@
#ifdef USE_UUID
#include <uuid/uuid.h>
#endif
namespace drogon
{
class HttpAppFrameworkImpl
{
public:
HttpAppFrameworkImpl(const std::string &ip,uint16_t port);
void run();
~HttpAppFrameworkImpl(){}
private:
std::string _ip;
uint16_t _port;
void onAsyncRequest(const HttpRequest& req,std::function<void (HttpResponse &)>callback);
void readSendFile(const std::string& filePath,const HttpRequest& req, HttpResponse* resp);
#ifdef USE_UUID
//if uuid package found,we can use a uuid string as session id;
//set _sessionTimeout=0 to disable location session control based on cookies;
uint _sessionTimeout=0;
#endif
bool _enableLastModify=true;
std::set<std::string> _fileTypeSet={"html","jpg"};
std::string _rootPath;
//tool funcs
#ifdef USE_UUID
std::string getUuid();
std::string stringToHex(unsigned char* ptr, long long length);
#endif
};
}
using namespace drogon;
using namespace std::placeholders;
HttpAppFramework::HttpAppFramework(const std::string &ip,uint16_t port):
_ip(ip),
_port(port)
HttpAppFrameworkImpl::HttpAppFrameworkImpl(const std::string &ip,uint16_t port):
_ip(ip),
_port(port)
{
}
void HttpAppFramework::run()
void HttpAppFrameworkImpl::run()
{
trantor::EventLoop loop;
HttpServer httpServer(&loop,InetAddress(_ip,_port),"");
httpServer.setHttpAsyncCallback(std::bind(&HttpAppFramework::onAsyncRequest,this,_1,_2));
httpServer.setHttpAsyncCallback(std::bind(&HttpAppFrameworkImpl::onAsyncRequest,this,_1,_2));
httpServer.start();
loop.loop();
}
void HttpAppFramework::onAsyncRequest(const HttpRequest& req,std::function<void (HttpResponse &)>callback)
void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequest& req,std::function<void (HttpResponse &)>callback)
{
LOG_TRACE << "Headers " << req.methodString() << " " << req.path();
#if 1
const std::map<std::string, std::string>& headers = req.headers();
for (std::map<std::string, std::string>::const_iterator it = headers.begin();
it != headers.end();
++it) {
LOG_TRACE << it->first << ": " << it->second;
}
const std::map<std::string, std::string>& headers = req.headers();
for (std::map<std::string, std::string>::const_iterator it = headers.begin();
it != headers.end();
++it) {
LOG_TRACE << it->first << ": " << it->second;
}
LOG_TRACE<<"cookies:";
auto cookies = req.cookies();
for(auto it=cookies.begin();it!=cookies.end();++it)
{
LOG_TRACE<<it->first<<"="<<it->second;
}
LOG_TRACE<<"cookies:";
auto cookies = req.cookies();
for(auto it=cookies.begin();it!=cookies.end();++it)
{
LOG_TRACE<<it->first<<"="<<it->second;
}
#endif
@ -154,20 +194,20 @@ void HttpAppFramework::onAsyncRequest(const HttpRequest& req,std::function<void
LOG_ERROR<<"can't find controller "<<ctrlName;
*/
HttpResponse resp;
HttpResponse resp;
resp.setStatusCode(HttpResponse::k404NotFound);
//resp.setCloseConnection(true);
resp.setStatusCode(HttpResponse::k404NotFound);
//resp.setCloseConnection(true);
#ifdef USE_UUID
if(needSetJsessionid)
if(needSetJsessionid)
resp.addCookie("JSESSIONID",session_id);
#endif
callback(resp);
// }
callback(resp);
// }
}
void HttpAppFramework::readSendFile(const std::string& filePath,const HttpRequest& req, HttpResponse* resp)
void HttpAppFrameworkImpl::readSendFile(const std::string& filePath,const HttpRequest& req, HttpResponse* resp)
{
//If-Modified-Since: Wed Jun 15 08:57:30 2016 GMT
std::ifstream infile(filePath, std::ifstream::binary);
@ -223,16 +263,15 @@ void HttpAppFramework::readSendFile(const std::string& filePath,const HttpReques
resp->setBody(str);
delete contents;
}
#ifdef USE_UUID
std::string HttpAppFramework::getUuid()
std::string HttpAppFrameworkImpl::getUuid()
{
uuid_t uu;
uuid_generate(uu);
return stringToHex(uu, 16);
}
std::string HttpAppFramework::stringToHex(unsigned char* ptr, long long length)
std::string HttpAppFrameworkImpl::stringToHex(unsigned char* ptr, long long length)
{
std::string idString;
for (long long i = 0; i < length; i++)
@ -258,3 +297,26 @@ std::string HttpAppFramework::stringToHex(unsigned char* ptr, long long length)
return idString;
}
#endif
HttpAppFramework::HttpAppFramework(const std::string &ip,uint16_t port):
_implPtr(new HttpAppFrameworkImpl(ip,port))
{
}
void HttpAppFramework::run()
{
_implPtr->run();
}
HttpAppFramework::~HttpAppFramework()
{
}

View File

@ -361,7 +361,7 @@ bool HttpContext::parseResponse(MsgBuffer *buf)
const char *crlf = buf->findCRLF();
if (crlf)
{
if (response_.current_chunk_length_ == crlf - buf->peek())
if (response_.current_chunk_length_ == (size_t)(crlf - buf->peek()))
{
//current chunk end crlf
response_.body_ += std::string(buf->peek(), response_.current_chunk_length_);
@ -369,7 +369,7 @@ bool HttpContext::parseResponse(MsgBuffer *buf)
response_.current_chunk_length_ = 0;
res_state_ = HttpResponseParseState::kExpectChunkLen;
}
else if (response_.current_chunk_length_ > crlf - buf->peek())
else if (response_.current_chunk_length_ > (size_t)(crlf - buf->peek()))
{
//current chunk body crlf
response_.body_ += std::string(buf->peek(), crlf - buf->peek() + 1);

View File

@ -19,13 +19,13 @@
#include <iostream>
static int urldecode(const char* encd,char* decd)
{
int j,i;
int j;
char *cd =(char*) encd;
char p[2];
unsigned int num;
j=0;
for( i = 0; i < strlen(cd); i++ )
for( size_t i = 0; i < strlen(cd); i++ )
{
memset( p,0,2);
if( cd[i] != '%' )