@@ -156,7 +156,6 @@ else(${CMAKE_HOST_WIN32}) | |||
endif(${CMAKE_HOST_WIN32}) | |||
configure_file(config.cmake.h config.h) | |||
if(CPPCMS_USE_EXTERNAL_BOOST) | |||
if(WIN32) | |||
add_definitions(-DBOOST_ALL_NO_LIB) | |||
@@ -234,7 +233,7 @@ find_library(LIB_GCRYPT gcrypt) | |||
if(LIB_GCRYPT) | |||
set(CPPCMS_SOURCES ${CPPCMS_SOURCES} aes_encryptor.cpp) | |||
set(HAVE_GCRYPT) | |||
set(HAVE_GCRYPT 1) | |||
else(LIB_GCRYPT) | |||
message("GNU Gcrypt library not found, disabling aes_encryptor") | |||
endif(LIB_GCRYPT) | |||
@@ -383,4 +382,5 @@ endif(WIN32 AND NOT DISABLE_SHARED) | |||
set_target_properties(${CPPCMS_LIBS} PROPERTIES CLEAN_DIRECT_OUTPUT 1) | |||
set_target_properties(${CPPCMS_LIBS} PROPERTIES OUTPUT_NAME "cppcms") | |||
configure_file(config.cmake.h config.h) | |||
@@ -190,6 +190,11 @@ cache_interface &application::cache() | |||
return context().cache(); | |||
} | |||
session_interface &application::session() | |||
{ | |||
return context().session(); | |||
} | |||
void application::recycle() | |||
{ | |||
@@ -16,6 +16,7 @@ namespace cppcms { | |||
class application; | |||
class base_content; | |||
class cache_interface; | |||
class session_interface; | |||
namespace locale { | |||
class environment; | |||
@@ -44,6 +45,7 @@ namespace cppcms { | |||
http::response &response(); | |||
url_dispatcher &dispatcher(); | |||
cache_interface &cache(); | |||
session_interface &session(); | |||
void render(std::string template_name,base_content &content); | |||
void render(std::string skin,std::string template_name,base_content &content); | |||
@@ -54,11 +54,28 @@ | |||
}, | |||
"session" : { | |||
"expire" : "browser", | |||
"timeout" : 10, | |||
"cookies_prefix" : "cppcms_session", | |||
"cookies_domain" : "", | |||
"cookies_path" : "/", | |||
"cookies_secure" : false | |||
"timeout" : 10, // seconds | |||
"cookies" : { | |||
"prefix" : "cppcms_session", | |||
"domain" : "", | |||
"path" : "/", | |||
"secure" : false | |||
}, | |||
"location" : "server", | |||
"client_size_limit" : 64, | |||
"gc" : 10, | |||
"client" : { | |||
"encryptor" : "aes", | |||
// aes or hmac -- hmac -- signature only, aes -- encryption and signature | |||
"key" : "261965ba80a79c034c9ae366a19a2627" | |||
// 32 digit hexadecimal secret number | |||
}, | |||
"server" : { | |||
"storage" : "files", | |||
"dir" : "./cppcms_sessions", | |||
"shared" : true | |||
} | |||
}, | |||
"views" : { | |||
"default_skin" : "skin1", | |||
@@ -12,6 +12,7 @@ | |||
#include "intrusive_ptr.h" | |||
#include "form.h" | |||
#include "cache_interface.h" | |||
#include "session_interface.h" | |||
#include <sstream> | |||
#include <stdexcept> | |||
#include <stdlib.h> | |||
@@ -211,12 +212,21 @@ public: | |||
dispatcher().assign("^/forward$",&hello::forward,this); | |||
dispatcher().assign("^/form$",&hello::form,this); | |||
dispatcher().assign("^/cache/?$",&hello::cached,this); | |||
dispatcher().assign("^/session/?$",&hello::session_test,this); | |||
dispatcher().assign(".*",&hello::hello_world,this); | |||
} | |||
~hello() | |||
{ | |||
} | |||
void session_test() | |||
{ | |||
if(!session().is_set("first_visit")) | |||
session().set("first_visit",::time(0)); | |||
response().out() << cppcms::locale::format("<html><body> Your first visit was at {1,datetime=l} </body></html>") | |||
% session().get<time_t>("first_visit"); | |||
} | |||
void cached() | |||
{ | |||
if(cache().fetch_page("test")) | |||
@@ -287,6 +287,7 @@ void service::after_fork(util::callback0 const &cb) | |||
void service::run() | |||
{ | |||
generator(); | |||
session_pool().init(); | |||
start_acceptor(); | |||
if(settings().get("file_server.enable",false)) | |||
@@ -286,14 +286,14 @@ void session_interface::set_session_cookie(int64_t age,string const &data,string | |||
{ | |||
if(data.empty()) | |||
age=-1; | |||
std::string cookie_name=context_->settings().get("session.cookies_prefix","cppcms_session"); | |||
std::string cookie_name=context_->settings().get("session.cookies.prefix","cppcms_session"); | |||
if(!key.empty()) { | |||
cookie_name+="_"; | |||
cookie_name+=key; | |||
} | |||
std::string domain = context_->settings().get("session.cookies_domain",""); | |||
std::string path = context_->settings().get("session.cookies_path","/"); | |||
bool secure = context_->settings().get("session.cookies_secure",0); | |||
std::string domain = context_->settings().get("session.cookies.domain",""); | |||
std::string path = context_->settings().get("session.cookies.path","/"); | |||
bool secure = context_->settings().get("session.cookies.secure",0); | |||
http::cookie the_cookie(cookie_name,util::urlencode(data),path,domain); | |||
@@ -317,7 +317,7 @@ void session_interface::set_session_cookie(string const &data) | |||
string session_interface::get_session_cookie() | |||
{ | |||
check(); | |||
string name=context_->settings().get("session.cookies_prefix","cppcms_session"); | |||
string name=context_->settings().get("session.cookies.prefix","cppcms_session"); | |||
http::request::cookies_type const &cookies = context_->request().cookies(); | |||
http::request::cookies_type::const_iterator p=cookies.find(name); | |||
if(p==cookies.end()) | |||
@@ -35,9 +35,9 @@ public: | |||
void hide(std::string const &key); | |||
std::string &operator[](std::string const &); | |||
void set(std::string const &key,std::string const &v); | |||
std::string get(std::string const &key); | |||
void set(std::string const &key,std::string const &v); | |||
template<typename T> | |||
T get(std::string const &key) | |||
@@ -57,7 +57,7 @@ public: | |||
std::ostringstream ss; | |||
ss.imbue(std::locale::classic()); | |||
ss<<value; | |||
set(key,value); | |||
set(key,ss.str()); | |||
} | |||
@@ -135,7 +135,6 @@ private: | |||
void load_data(std::map<std::string,entry> &data,std::string const &s); | |||
}; | |||
} // cppcms | |||
@@ -22,7 +22,7 @@ | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#ifndef HAVE_GCRYPT | |||
#ifdef HAVE_GCRYPT | |||
#include "aes_encryptor.h" | |||
#endif | |||
@@ -150,49 +150,49 @@ private: | |||
}; | |||
session_pool::session_pool(service &srv) : | |||
service_(&srv) | |||
void session_pool::init() | |||
{ | |||
service &srv=*service_; | |||
if(backend_.get()) | |||
return; | |||
std::string location=srv.settings().get("session.location","none"); | |||
if(location == "client" || location=="both") { | |||
std::string enc=srv.settings().get("session.cookies_encryptor",""); | |||
if(location == "client" || location=="both" && !encryptor_.get()) { | |||
std::string enc=srv.settings().get<std::string>("session.client.encryptor"); | |||
std::auto_ptr<cppcms::sessions::encryptor_factory> factory; | |||
if(enc=="hmac") { | |||
std::string key = srv.settings().get<std::string>("session.cookies_key"); | |||
std::string key = srv.settings().get<std::string>("session.client.key"); | |||
factory.reset(new enc_factory<cppcms::sessions::impl::hmac_cipher>(key)); | |||
} | |||
#ifdef HAVE_GCRYPT | |||
else if(enc=="aes") { | |||
std::string key = srv.settings().get<std::string>("session.cookies_key"); | |||
std::string key = srv.settings().get<std::string>("session.client.key"); | |||
factory.reset(new enc_factory<cppcms::sessions::impl::aes_cipher>(key)); | |||
} | |||
#endif | |||
else if(enc.empty()) | |||
; // Nothing to do | |||
else | |||
throw cppcms_error("Unknown encryptor: "+enc); | |||
encryptor(factory); | |||
} | |||
if(location == "server" || location == "both" ) { | |||
std::string storage=srv.settings().get("session.backend",""); | |||
if(storage == "files") { | |||
std::auto_ptr<sessions::session_storage_factory> tmp; | |||
std::string dir = srv.settings().get("session.files.dir",""); | |||
if(location == "server" || location == "both" && !storage_.get()) { | |||
std::string stor=srv.settings().get<std::string>("session.server.storage"); | |||
std::auto_ptr<sessions::session_storage_factory> factory; | |||
if(stor == "files") { | |||
std::string dir = srv.settings().get("session.server.dir",""); | |||
#ifdef CPPCMS_WIN_NATIVE | |||
tmp.reset(new session_file_storage_factory(dir)); | |||
factory.reset(new session_file_storage_factory(dir)); | |||
#else | |||
bool sharing = srv.settings().get("session.files.shared",true); | |||
bool sharing = srv.settings().get("session.server.shared",true); | |||
int threads = srv.threads_no(); | |||
int procs = srv.procs_no(); | |||
if(procs == 0) procs=1; | |||
tmp.reset(new session_file_storage_factory(dir,threads*procs,procs,sharing)); | |||
#endif | |||
factory.reset(new session_file_storage_factory(dir,threads*procs,procs,sharing)); | |||
#endif | |||
} | |||
else if(storage.empty()) | |||
; /// Nothing to do | |||
else | |||
throw cppcms_error("Unknown server side storage:"+storage); | |||
throw cppcms_error("Unknown server side storage:"+stor); | |||
storage(factory); | |||
} | |||
if(location == "server") { | |||
std::auto_ptr<session_api_factory> f(new sid_factory(this)); | |||
@@ -215,6 +215,11 @@ session_pool::session_pool(service &srv) : | |||
service_->after_fork(boost::bind(&session_pool::after_fork,this)); | |||
} | |||
session_pool::session_pool(service &srv) : | |||
service_(&srv) | |||
{ | |||
} | |||
void session_pool::after_fork() | |||
{ | |||
if(backend_.get() && backend_->requires_gc()) { | |||
@@ -21,6 +21,8 @@ namespace cppcms { | |||
session_pool(service &srv); | |||
~session_pool(); | |||
void init(); | |||
intrusive_ptr<session_api> get(); | |||
void backend(std::auto_ptr<session_api_factory> b); | |||