⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session_interface.cpp

📁 C++ web POSIX framewark
💻 CPP
字号:
#include "worker_thread.h"#include "session_interface.h"#include "session_api.h"#include "manager.h"#include "util.h"#include <sstream>namespace cppcms {class cookie : public cgicc::HTTPCookie {	bool del;public:	cookie() :	 del(false)	{	}	cookie(string const &name,string const &val) :		cgicc::HTTPCookie(name,val),		del(false)	{	}	cookie(	const std::string& name,		const std::string& value,		const std::string& comment,		const std::string& domain,		unsigned long maxAge,		const std::string& path,		bool secure) :			HTTPCookie(name,value,comment,domain,maxAge,path,secure),			del(false)	{	}	void remove() { del=true; }	virtual void render(std::ostream& out) const	{		if(!del) {			cgicc::HTTPCookie::render(out);		}		else {			out <<"Set-Cookie:"<<getName()<<"=";			string domain=getDomain();			if(!domain.empty()) {				out<<"; Domain="<<domain;			}			string path=getPath();			if(!path.empty()) {				out<<"; Path="<<path;			}			if(isSecure()) {				cout<<"; Secure";			}			out<<"; Expires=Fri, 01-Jan-1971 01:00:00 GMT; Version=1";		}	}};session_interface::session_interface(worker_thread &w) :	worker(w){	timeout_val_def=w.app.config.ival("session.timeout",24*3600);	string s_how=w.app.config.sval("session.expire","browser");	if(s_how=="fixed") {		how_def=fixed;	}	else if(s_how=="renew") {		how_def=renew;	}	else if(s_how=="browser") {		how_def=browser;	}	else {		throw cppcms_error("Unsupported `session.expire' type `"+s_how+"'");	}	storage=w.app.sessions(w);}worker_thread &session_interface::get_worker(){	return worker;}void session_interface::set_api(boost::shared_ptr<session_api> s){	storage=s;}bool session_interface::load(){	data.clear();	data_copy.clear();	timeout_val=timeout_val_def;	how=how_def;	string ar;	saved=false;	if(!storage.get() || !storage->load(this,ar,timeout_in)) {		return false;	}	load_data(data,ar);	data_copy=data;	if(is_set("_t"))		timeout_val=get<int>("_t");	if(is_set("_h"))		how=get<int>("_h");	return true;}int session_interface::cookie_age(){	if(how==browser)		return 0;	if(how==renew || ( how==fixed && new_session ))		return timeout_val;	return timeout_in - time(NULL);}time_t session_interface::session_age(){	if(how==browser || how==renew || (how==fixed && new_session))		return timeout_val + time(NULL);	return timeout_in;}namespace {struct packed {        unsigned key_size  : 10;        unsigned exposed   :  1;        unsigned data_size : 21;	packed() {}	packed(unsigned ks,bool exp, unsigned ds)	{		if(ks >=1024) 			throw cppcms_error("session::save key too long");		if(ds >= 1024 * 1024 * 2)			throw cppcms_error("session::save value too long");		key_size=ks;		exposed = exp ? 1 : 0;		data_size=ds;	}	packed(char const *start,char const *end)	{		if(start + 4 <= end ) {			memcpy(this,start,4);		}		else			throw cppcms_error("session::format violation -> pack");	}};}void session_interface::save_data(data_t const &data,std::string &s){	s.clear();	data_t::const_iterator p;	for(p=data.begin();p!=data.end();++p) {		packed header(p->first.size(),p->second.exposed,p->second.value.size());		char *ptr=(char *)&header;		s.append(ptr,ptr+sizeof(header));		s.append(p->first.begin(),p->first.end());		s.append(p->second.value.begin(),p->second.value.end());	}}void session_interface::load_data(data_t &data,std::string const &s){	data.clear();	char const *begin=s.data(),*end=begin+s.size();	while(begin < end) {		packed p(begin,end);		begin +=sizeof(p);		if(end - begin >= int(p.key_size + p.data_size)) {			string key(begin,begin+p.key_size);			begin+=p.key_size;			string val(begin,begin+p.data_size);			begin+=p.data_size;			entry &ent=data[key];			ent.exposed = p.exposed;			ent.value.swap(val);		}		else {			throw cppcms_error("sessions::format violation data");		}	}}void session_interface::update_exposed(){	for(data_t::iterator p=data.begin();p!=data.end();++p) {		data_t::iterator p2=data_copy.find(p->first);		if(p->second.exposed && (p2==data_copy.end() || !p2->second.exposed || p->second.value!=p2->second.value)){			set_session_cookie(cookie_age(),p->second.value,p->first);		}		else if(!p->second.exposed && p2!=data_copy.end() && p2->second.exposed) {			set_session_cookie(-1,"",p->first);		}	}	for(data_t::iterator p=data_copy.begin();p!=data_copy.end();++p) {		if(p->second.exposed && data.find(p->first)==data.end()) {			set_session_cookie(-1,"",p->first);		}	}}void session_interface::save(){	if(saved)		return;	check();	new_session  = data_copy.empty() && !data.empty();	if(data.empty()) {		if(get_session_cookie()!="")			storage->clear(this);		update_exposed();		return;	}	time_t now = time(NULL);	if(data==data_copy) {		if(how==fixed) {			return;		}		if(how==renew || how==browser) {			int64_t delta=now + timeout_val - timeout_in;			if(delta < timeout_val * 0.1) {// Less then 10% -- no renew need				return;			}		}	}	string ar;	save_data(data,ar);		temp_cookie.clear();	storage->save(this,ar,session_age(),new_session);	set_session_cookie(cookie_age(),temp_cookie);	temp_cookie.clear();	update_exposed();		saved=true;}void session_interface::on_start(){	load();}void session_interface::on_end(){	if(storage.get()!=NULL)		save();}void session_interface::check(){	if(storage.get()==NULL)		throw cppcms_error("Session storage backend is not loaded\n");}string &session_interface::operator[](string const &key){	return data[key].value;}void session_interface::del(string const &key){	data.erase(key);}bool session_interface::is_set(string const &key){	return data.find(key)!=data.end();}void session_interface::clear(){	data.clear();}void session_interface::clear_session_cookie(){	if(get_session_cookie()!="")		set_session_cookie(-1,"");}void session_interface::set_session_cookie(int64_t age,string const &data,string const &key){	if(data.empty())		age=-1;	string cookie_name=worker.app.config.sval("session.cookies_prefix","cppcms_session");	if(!key.empty()) {		cookie_name+="_";		cookie_name+=key;	}	if(age < 0) {		cookie cook(cookie_name,"","",			worker.app.config.sval("session.cookies_domain",""),			0,			worker.app.config.sval("session.cookies_path","/"),			worker.app.config.ival("session.cookies_secure",0));		cook.remove();		ostringstream out;		out<<cook;		worker.add_header(out.str());	}	else {		cgicc::HTTPCookie cook(			cookie_name, // name			(age >= 0 ? urlencode(data) : ""), // value			"",   // comment			worker.app.config.sval("session.cookies_domain",""), // domain			( age < 0 ? 0 : age ),			worker.app.config.sval("session.cookies_path","/"),			worker.app.config.ival("session.cookies_secure",0));		worker.set_cookie(cook);	}}void session_interface::set_session_cookie(string const &data){	temp_cookie=data;}string session_interface::get_session_cookie(){	string name=worker.app.config.sval("session.cookies_prefix","cppcms_session");	vector<cgicc::HTTPCookie> const &cookies=worker.env->getCookieList();	for(unsigned i=0;i<cookies.size();i++) {		if(cookies[i].getName()==name)			return cookies[i].getValue();	}	return string("");}	void session_interface::get(std::string const &key,serializable &s){	s=(*this)[key];}void session_interface::set(std::string const &key,serializable const &s){	(*this)[key]=s;}bool session_interface::is_exposed(std::string const &key){	data_t::iterator p=data.find(key);	if(p!=data.end()) 		return p->second.exposed;	return false;}void session_interface::expose(string const &key,bool exp){	data[key].exposed=exp;}void session_interface::hide(string const &key){	expose(key,false);}void session_interface::set_age(int t){	timeout_val=t;	set("_t",t);}void session_interface::set_age(){	del("_t");	timeout_val=timeout_val_def;}void session_interface::set_expiration(int h){	how=h;	set("_h",h);}void session_interface::set_expiration(){	del("_h");	how=how_def;}};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -