application.h   application.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_APPLICATION_H #ifndef CPPCMS_APPLICATION_H
#define CPPCMS_APPLICATION_H #define CPPCMS_APPLICATION_H
#include "worker_thread.h"
#include "manager.h" #include <cppcms/defs.h>
#include <booster/noncopyable.h>
#include <booster/hold_ptr.h>
#include <booster/atomic_counter.h>
#include <booster/intrusive_ptr.h>
#include <booster/shared_ptr.h>
#include <string>
namespace cppcms { namespace cppcms {
class application;
}
struct application { namespace booster {
void CPPCMS_API intrusive_ptr_add_ref(cppcms::application *p);
void CPPCMS_API intrusive_ptr_release(cppcms::application *p);
}
// Data namespace cppcms {
worker_thread &worker;
url_parser &url;
manager const &app;
Cgicc *&cgi;
CgiEnvironment const *&env;
cgicc_connection *&cgi_conn;
cache_iface &cache; class service;
session_interface &session; class url_dispatcher;
class applications_pool;
class application;
class base_content;
class cache_interface;
class session_interface;
ostream &cout; namespace http {
class request;
class response;
class context;
}
namespace json {
class value;
}
boost::signal<void()> &on_start; ///
boost::signal<void()> &on_end; /// \brief application class is the base class for all user created
applications.
///
/// This class is the base for all user actions required for web pag
e generation.
/// User application classes are created upon web page request and t
hen cached in \a application_pool.
///
/// Applications can be bundled to hierarchies. You may add a sub ap
plication to hierarchy,
/// and they will always be connected with topmost application and t
heir lifetime would be binded to them.
///
/// application class is reference counted and may be used with \a i
ntrusive_ptr. But reference count
/// semantics is very different form an ordinary semantics for other
classes derived from \a cppcms::refcounted.
///
/// 1. All hierarchy share the counter of the topmost application.
Thus, when all bundle is counted
/// as a single unit allowing passing intrusive_ptr to itself to
the central service safely.
/// When the topmost application is destroyed, it destroys all i
ts children application classes.
/// 2. When reference count goes to 0, the application is not destr
oyed but rather recycled to the
/// application pool for future use.
/// 3. The above hold only for synchronous applications, asynchrono
us one are destroyed when all
/// reference count goes to 0.
///
/// There two ways to add sub-applications to hierarchy:
///
/// 1. Using member function family \a add, usually used with direc
t members of the parent class.
/// Such child are not destroyed explicitly.
/// 2. Using member function family \a attach. The ownership on the
application is moved to the
/// parent class and it destroys an attached class with delete.
///
// Construction class CPPCMS_API application : public booster::noncopyable {
application(worker_thread &w); public:
virtual ~application(); ///
// API /// Create a new application running on service \a srv, with
a parent \a parent
///
application(cppcms::service &srv);
void set_header(HTTPHeader *h) { worker.set_header(h); } ///
void add_header(string s) { worker.add_header(s); } /// Destroys an application and all assigned application chi
void set_cookie(cgicc::HTTPCookie const &c) { worker.set_cookie(c); ldren.
} ///
void set_user_io() { worker.set_user_io(); } virtual ~application();
void no_gzip() { worker.no_gzip(); }
HTTPHeader &header() { return worker.header(); } ///
/// Get the main service
///
cppcms::service &service();
void set_lang() { worker.set_lang(); } ///
void set_lang(string const &s) { worker.set_lang(s) ; } /// Get global service settings
///
json::value const &settings();
void use_template(string s="") { worker.use_template(s); } ///
/// Get a context of the single HTTP request/response.
///
http::context &context();
void render(string n,base_content &c) { worker.render(n,c); } ///
void render(string t,string n,base_content &c) { worker.render(t,n,c /// Get a HTTP request information class, same as context().
); } request();
void render(string n,base_content &c,ostream &o) { worker.render(n,c ///
,o); } http::request &request();
void render(string t,string n,base_content &c,ostream &o) { worker.r
ender(t,n,c,o); }
virtual void on_404(); ///
/// Get a HTTP response information class, same as context()
.response();
///
http::response &response();
inline char const *gettext(char const *s) { return worker.gettext(s) ///
; }; /// Get a dispatched class -- class that responsible on mapp
inline char const *ngettext(char const *s,char const *p,int n) { ret ing between URLs and a member
urn worker.ngettext(s,p,n); } /// functions of application class. This member function is
application specific and not
/// Connection specific.
///
url_dispatcher &dispatcher();
transtext::trans const *domain_gettext(string const &d) { return wor ///
ker.domain_gettext(d); } /// Get a cache_interface instance. Same as context().cache(
);
///
cache_interface &cache();
virtual void main(); ///
/// Get current session_interface instance. Same as context(
).session();
///
session_interface &session();
template<typename SQL> ///
void dbixx_load(SQL &sql) /// Render a template \a template_name of default skin using
{ content \a content.
using std::string; ///
string driver=app.config.sval("dbixx.driver"); /// Side effect requires: output stream for response class,
sql.driver(driver); causes all updated session
/// data be saved and all headers be written. You can't chan
ge headers after calling this function.
///
void render(std::string template_name,base_content &content)
;
///
/// Render a template \a template_name of \a skin skin using
content \a content.
///
/// Side effect requires: output stream for response class,
causes all updated session
/// data be saved and all headers be written. You can't chan
ge headers after calling this function.
///
void render(std::string skin,std::string template_name,base_
content &content);
cppcms_config::range_t range=app.config.prefix(driver); ///
size_t len=driver.size()+1; /// Render a template \a template_name of default skin using
for(cppcms_config::data_t::const_iterator p=range.first;p!=r content \a content to an output
ange.second;++p){ /// stream \a out. Note: You are responsible to imbue suitab
string param=p->first.substr(len); le locale to the stream.
if(p->second.type()==typeid(string)) { ///
string val=boost::any_cast<string>(p->second /// You should use context().locale() or service().generator
); () to create such locales.
sql.param(param,val); ///
} void render(std::string template_name,std::ostream &out,base
else if(p->second.type()==typeid(int)) { _content &content);
int val=boost::any_cast<int>(p->second);
sql.param(param,val);
}
}
sql.connect();
}
template<typename SQL> ///
void soci_load(SQL &sql) /// Render a template \a template_name of a skin \a skin usi
{ ng content \a content to an output
string tmp; /// stream \a out. Note: You are responsible to imbue suitab
if(!(tmp=app.config.sval("soci.conn","")).empty()) { le locale to the stream.
sql.open(app.config.sval("soci.conn")); ///
} /// You should use context().locale() or service().generator
else { () to create such locales.
sql.open(app.config.sval("soci.driver"),app.config.s ///
val("soci.params")); void render(std::string skin,std::string template_name,std::
} ostream &out,base_content &content);
}
}; ///
/// Register an application \a app as child. Ownership of ap
p is not transfered to parent, however
/// it would shared it's parent reference count.
///
void add(application &app);
template<typename T> ///
class application_worker : public worker_thread { /// Register an application \a app as child. Ownership of ap
T app; p is not transfered to parent, however
public: /// it would shared it's parent reference count.
application_worker(manager const &m) : ///
worker_thread(m), /// All URL that match regular expression \a regex would be
app(*this) passed to the child for match. Matched part
{ /// \a part would be used by child for matching.
} ///
virtual void main() /// For example:
{ ///
app.main(); /// \code
} /// add(users,"^/users(.*)$",1")
}; /// \endcode
///
/// For URL /users/moshe would pass only "/moshe" to URL dis
patched of \a users object
///
void add(application &app,std::string regex,int part);
template<typename T> ///
class application_factory : public simple_factory<application_worker<T> > /// Register an application \a app as child. Ownership of ap
{ p is transfered to parent
}; ///
void attach(application *app);
///
/// Register an application \a app as child. Ownership of ap
p is transfered to parent
///
/// All URL that match regular expression \a regex would be
passed to the child for match. Matched part
/// \a part would be used by child for matching.
///
/// For example:
///
/// \code
/// add(users,"^/users(.*)$",1")
/// \endcode
///
/// For URL /users/moshe would pass only "/moshe" to URL dis
patched of \a users object
///
void attach(application *app,std::string regex,int part);
} ///
/// Get the parent of the application, if the application is
the topmost class in hierarchy,
/// it would return \a this, So, if you want to check if the
application has any parent test
/// app->parent()!=app;
///
application *parent();
///
/// Get the root application of the hierarchy. Note, if the
application is the topmost one,
/// \a this pointer would be returned
///
application *root();
///
/// Request from an application give-up on ownership of the
http::context class and give it
/// to the user control. Usually it is required for processi
ng asynchronous requests.
///
/// Note: because application hierarchy shared same context,
it affects all classes in it.
///
booster::shared_ptr<http::context> release_context();
///
/// Get reference counted pointer to the http::context
///
booster::shared_ptr<http::context> get_context();
///
/// Set context to the application. The application gets sha
red ownership on the context.
///
/// Note: because application hierarchy shared same context,
it affects all classes in it.
///
void assign_context(booster::shared_ptr<http::context> conn)
;
///
/// Returns true if current application was created as async
hronous application.
///
bool is_asynchronous();
///
/// This is main function of the application that is called
when it is matched
/// according to the regular expression in the applications_
pool class.
///
/// By default, main calls dispatcher().dispatch(url). And i
f the last fails, it
/// creates 404 Error page. This allows developers to create
its own hooks for
/// reaction on incoming URL as, initialization and cleanup
of general resources,
/// Custom 404 and error handlers etc.
///
virtual void main(std::string url);
private:
void recycle();
void parent(application *parent);
void pool_id(int id);
int pool_id();
struct _data; // future use
booster::hold_ptr<_data> d;
application *parent_;
application *root_;
booster::atomic_counter refs_;
friend class applications_pool;
friend void booster::intrusive_ptr_add_ref(application *p);
friend void booster::intrusive_ptr_release(application *p);
};
} // cppcms
#endif #endif
 End of changes. 25 change blocks. 
99 lines changed or deleted 322 lines changed or added


 base64.h   base64.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_BASE64_H #ifndef CPPCMS_BASE64_H
#define CPPCMS_BASE64_H #define CPPCMS_BASE64_H
#include <cppcms/defs.h>
#include <string> #include <string>
namespace cppcms { namespace cppcms {
///
/// \brief this namespace provides functions useful for modified Bas
e64 encoding for URL.
/// This encoding does not insert newline characters, do not pad the
text with = character and
/// use "_" and "-" instead of "+" and "/" characters reserved by UR
L format for special purposes.
///
namespace b64url { namespace b64url {
ssize_t encoded_size(size_t s);
ssize_t decoded_size(size_t s); ///
unsigned char *encode(unsigned char const *begin,unsigned char const /// Calculate required buffer size of base64-url compatible encoding
*end,unsigned char *target); for source of size \a s
unsigned char *decode(unsigned char const *begin,unsigned char const ///
*end,unsigned char *target); int CPPCMS_API encoded_size(size_t s);
///
/// Calculate required buffer size of base64-url compatible decoding
for source of size \a s
///
/// Note, if original size is invalid, negative value is returned
///
int CPPCMS_API decoded_size(size_t s);
///
/// Perform base64 URL encoding of the binary data in range [\a begi
n,\a end), and store it to output buffer
/// \a target. The size of target storage should have a capacity cal
culated with encoded_size(end-begin).
///
/// Pointer to the first character directly after text string ends i
s returned.
///
unsigned char CPPCMS_API *encode(unsigned char const *begin,unsigned
char const *end,unsigned char *target);
///
/// Perform base64 URL decoding of the binary data in range [\a begi
n,\a end), and store it to output buffer
/// \a target. The size of target storage should have a capacity cal
culated with encoded_size(end-begin).
///
/// Pointer to the first character directly after text string ends i
s returned. Invalid codes are substituted
/// by 0 values.
///
///
unsigned char CPPCMS_API *decode(unsigned char const *begin,unsigned
char const *end,unsigned char *target);
} }
} }
#endif #endif
 End of changes. 4 change blocks. 
6 lines changed or deleted 70 lines changed or added


 base_view.h   base_view.h 
#ifndef CPPCMS_BASEVIEW_H ///////////////////////////////////////////////////////////////////////////
#define CPPCMS_BASEVIEW_H ////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_BASE_VIEW_H
#define CPPCMS_BASE_VIEW_H
#include <cppcms/defs.h>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <cstring>
#include <map> #include <map>
#include <memory>
#include <ctime> #include <ctime>
#include <boost/format/format_fwd.hpp> #include <memory>
#include "cppcms_error.h"
#include "config.h"
namespace cppcms { #include <booster/hold_ptr.h>
using namespace std; #include <cppcms/base_content.h>
#include <booster/noncopyable.h>
#include <cppcms/config.h>
// Just simple polimorphic class namespace cppcms {
class base_content {
public:
virtual ~base_content() {};
};
namespace transtext { class trans; } ///
/// \brief This class is base class for all views (skins) rendered by CppCM
S template engine.
///
/// Users are not expected to derive from this class or use it directly. Cp
pCMS template compiler
/// create skins that are usable with template engine and each template is
derived from the \a base_view
/// class.
///
class format { class CPPCMS_API base_view : booster::noncopyable {
mutable std::auto_ptr<boost::format> impl;
friend ostream &operator<<(ostream &,format &);
public: public:
format(std::string const &s); ///
format(format const &f); /// The main rendering function -- render the main HTML page. It is
format &operator % (int n); usually overridden in template engine.
format &operator % (string const &); ///
format &operator % (char const *); virtual void render();
string str(); virtual ~base_view();
~format();
};
ostream &operator<<(ostream &,format &);
class worker_thread;
class base_view {
public:
struct settings {
worker_thread *worker;
ostream *output;
settings(worker_thread *w);
settings(worker_thread *w,ostream *o);
};
protected: protected:
worker_thread &worker;
ostream &cout;
transtext::trans const *tr;
base_view(settings s) : /// \cond INTERNAL
worker(*s.worker),
cout(*s.output)
{
}
::cppcms::format format(std::string const &s)
{
return ::cppcms::format(s);
}
void set_domain(char const *);
char const *gettext(char const *);
char const *ngettext(char const *,char const *,int n);
template<typename T>
string escape(T const &v)
{
ostringstream s;
s<<v;
return s.str();
};
string escape(string const &s);
inline string raw(string s) { return s; };
string intf(int val,string f);
string strftime(std::tm const &t,string f);
string date(std::tm const &t) { return strftime(t,"%Y-%m-%d"); };
string time(std::tm const &t) { return strftime(t,"%H:%M"); };
string timesec(std::tm const &t) { return strftime(t,"%T"); };
string escape(std::tm const &t) { return strftime(t,"%Y-%m-%d %T");
}
string urlencode(string const &s);
public:
virtual void render() {};
virtual ~base_view() {};
};
namespace details { base_view(std::ostream &out);
std::ostream &out();
template<typename T,typename VT> /// \endcond
base_view *view_builder(base_view::settings s,base_content *c) {
VT *p=dynamic_cast<VT *>(c);
if(!p) throw cppcms_error("Incorrect content type");
return new T(s,*p);
};
class views_storage {
public:
typedef base_view *(*view_factory_t)(base_view::settings s,base_cont
ent *c);
private: private:
typedef map<string,view_factory_t> template_views_t; struct _data;
typedef map<string,template_views_t> templates_t; booster::hold_ptr<_data> d;
templates_t storage;
public:
void add_view( string template_name,
string view_name,
view_factory_t);
void remove_views(string template_name);
base_view *fetch_view(string template_name,string view_name,base_vie
w::settings ,base_content *c);
static views_storage &instance();
}; };
}; // DETAILS } // cppcms
}; // CPPCMS
#define cppcms_view(X) \
do { \
void X##_symbol(); \
X##_symbol(); \
} while(0)
#if defined(HAVE_CPP_0X_AUTO) #if defined(CPPCMS_HAVE_CPP_0X_AUTO)
# define CPPCMS_TYPEOF(x) auto # define CPPCMS_TYPEOF(x) auto
#elif defined(HAVE_CPP_0X_DECLTYPE) #elif defined(CPPCMS_HAVE_CPP_0X_DECLTYPE)
# define CPPCMS_TYPEOF(x) decltype(x) # define CPPCMS_TYPEOF(x) decltype(x)
#elif defined(HAVE_GCC_TYPEOF) #elif defined(CPPCMS_HAVE_GCC_TYPEOF)
# define CPPCMS_TYPEOF(x) typeof(x) # define CPPCMS_TYPEOF(x) typeof(x)
#elif defined(HAVE_UNDERSCORE_TYPEOF) #elif defined(CPPCMS_HAVE_UNDERSCORE_TYPEOF)
# define CPPCMS_TYPEOF(x) __typeof__(x) # define CPPCMS_TYPEOF(x) __typeof__(x)
#elif defined(HAVE_WORKING_BOOST_TYPEOF)
# include <boost/typeof/typeof.hpp>
# define CPPCMS_TYPEOF(x) BOOST_TYPEOF(x)
#else #else
# error "No useful C++0x auto/decltype/typeof method for this compiler " # define CPPCMS_TYPEOF(x) automatic_type_identification_is_not_support ed_by_this_compiler
#endif #endif
#endif #endif
 End of changes. 24 change blocks. 
119 lines changed or deleted 61 lines changed or added


 cache_interface.h   cache_interface.h 
#ifndef CACHE_IFACE_H ///////////////////////////////////////////////////////////////////////////
#define CACHE_IFACE_H ////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_CACHE_INTERFACE_H
#define CPPCMS_CACHE_INTERFACE_H
#include <string> #include <string>
#include <set> #include <set>
#include "archive.h"
#include "base_cache.h"
namespace cppcms { #include <cppcms/defs.h>
#include <cppcms/serialization_classes.h>
#include <booster/noncopyable.h>
#include <booster/intrusive_ptr.h>
#include <booster/hold_ptr.h>
#include <cppcms/cstdint.h>
using namespace std; namespace cppcms {
class worker_thread; namespace impl {
class cache_iface { class base_cache;
worker_thread *cms;
set<string> triggers;
public:
void reset() { triggers.clear(); };
cache_iface(worker_thread *w) : cms (w) {};
bool fetch_page(string const &key);
void store_page(string const &key,int timeout=-1);
void rise(string const &trigger);
void add_trigger(string const &trigger);
bool fetch_frame(string const &key,string &result,bool notriggers=fa
lse);
void store_frame(string const &key,
string const &frame,
set<string> const &triggers=set<string>(),
int timeout=-1,
bool notriggers=false);
void store_frame(string const &key,
string const &frame,
int timeout,
bool notriggers=false)
{
store_frame(key,frame,set<string>(),timeout,notriggers);
}
bool fetch_data(string const &key,serializable &data,bool notriggers
=false);
void store_data(string const &key,serializable const &data,
set<string> const &triggers=set<string>(),
int timeout=-1,bool notriggers=false);
void store_data(string const &key,serializable const &data,int timeo
ut,bool notriggers=false)
{
store_data(key,data,set<string>(),timeout,notriggers);
} }
void clear(); namespace http {
bool stats(unsigned &keys,unsigned &triggers); class context;
};
}; ///
/// \brief This class is the major gateway of the application to Cpp
CMS caching abilities. Any access too cache
/// would be done via this class.
///
/// CppCMS cache model supports following concepts:
///
/// - \a key the unique identification of the object in cache
/// - \a timeout -- the maximal time the cached object remains valid
/// - \a trigger -- special key that allows fast invalidation of mul
tiple cache objects.
///
/// The first two concepts are quite popular and available in most o
f Web framework, but the last one is very
/// unique to CppCMS that gives fine grained cache invalidation tool
s.
///
/// Each time the page is created it automatically receives some tri
ggers during the process of creation.
/// When some object is fetched from the cache or stored into it, it
adds triggers to the major page. This provides
/// semi-automatic triggers management.
///
/// For example:
///
/// \code
/// if(cache().fetch_page("main_page"))
/// return;
/// if(!cache().fetch_frame("article_"+id,article)) {
/// article=generate_article_from_data_base(id);
/// cache.store_frame("article_"+id,article);
/// }
/// // Generate some HTML here using article
/// cache.store_page("main");
/// \endcode
///
/// Let's assume that "main_page" wasn't found in cache, then we try
to fetch a frame that holds only a single
/// article "article_123", if it is fetched, the result is stored in
a string article and the trigger "article_123"
/// is automatically added to set of triggers that "main_page" depen
ds on them.
///
/// When the article updated, and "article_123" key is risen, it wou
ld automatically invalidate "main_page" as well.
///
/// CppCMS cache_interface allows storing arbitrary object in cache,
For this purpose they should be "serializable".
/// This can be done by specializing a class cppcms::setialization_t
raits
///
void deflate(string const &text,ostream &stream,long level,long length); class CPPCMS_API cache_interface : public booster::noncopyable {
string deflate(string const &text,long level,long length); public:
class cache_factory { ///
public: /// \cond INTERNAL
virtual base_cache *get() const { return NULL; }; ///
virtual void del(base_cache *p) const { }; /// Internal API, don't use it
virtual ~cache_factory() {}; ///
}; cache_interface(http::context &context);
~cache_interface();
/// \endcond
///
/// Rise a trigger \a trigger. All cached objects that depen
d on this trigger would be invalidated
///
void rise(std::string const &trigger);
///
/// Add a trigger \a trigger to the list of dependencies of
current page.
///
void add_trigger(std::string const &trigger);
///
/// Clear all CppCMS cache - use carefully
///
void clear();
///
/// Remove all triggers added to current page so far
///
void reset();
///
/// Get statistics about items stored in cache. May require
O(n) complexity, use with care.
///
/// \param keys -- the number of items stored in cache
/// \param triggers -- the number of various triggers existi
ng in the cache.
///
/// Returns false if caching system is disabled.
///
bool stats(unsigned &keys,unsigned &triggers);
///
/// Returns true if caching system is enabled
///
bool has_cache();
///
/// Opposite of \a has_cache
///
bool nocache();
///
/// Fetch a page from the cache with a key \a key. If the pa
ge exists, it is written to output
/// and true is returned. Otherwise false is returned.
///
bool fetch_page(std::string const &key);
///
/// Store page with key \a akey in cache, with timeout \a ti
meout.
///
/// This function stores a page with dependencies on all tri
ggers that were added so far.
///
/// \param key -- the key that defines the cache.
/// \param timeout -- maximal valid time of the page. \a tim
eout=-1 means infinite. Use with care.
///
/// Note: store_page does not rise the trigger \a key, only
replaces the value.
///
void store_page(std::string const &key,int timeout=-1);
///
/// Fetch a string (usually some HTML part) from the cache.
///
/// \param key -- the key that uniquely defines the frame.
/// \param result -- string to store fetched value
/// \param notriggers -- if true, no triggers that a frame i
s dependent on would be added to dependencies of
/// the current page, otherwise (false, default), the
all triggers that page is dependent on, including
/// the \a key itself would be added as dependent trig
gers to current rendered page.
/// \return returns true if the entry was found.
///
bool fetch_frame(std::string const &key,std::string &result,
bool notriggers=false);
///
/// Store a string (usually some HTML part) to the cache.
///
/// \param key -- the key that uniquely defines the frame.
/// \param frame -- the actual value
/// \param triggers -- the set of triggers that the key sho
uld depend on (\a key is added automatically)
/// \param timeout -- maximal object lifetime, -1 is infinit
y
/// \param notriggers -- if \a notriggers is true no frame d
ependent triggers would be added to the current
/// page trigger set. Otherwise (default) current page w
ould depend on the \a key and \a triggers as its
/// dependent triggers.
///
void store_frame(std::string const &key,
std::string const &frame,
std::set<std::string> const &triggers=std::
set<std::string>(),
int timeout=-1,
bool notriggers=false);
///
/// Store a string (usually some HTML part) to the cache.
///
/// \param key -- the key that uniquely defines the frame.
/// \param frame -- the actual value
/// \param timeout -- maximal object lifetime, -1 is infinit
y
/// \param notriggers -- if \a notriggers is true \a key add
ed to the current
/// page trigger set. Otherwise (default) current page w
ould depend on the \a key
///
void store_frame(std::string const &key,
std::string const &frame,
int timeout,
bool notriggers=false);
///
/// Fetch a serializeable object from the cache.
///
/// \param key -- the key that uniquely defines the frame.
/// \param data -- an object store fetched data
/// \param notriggers -- if true, no triggers that an object
is dependent on would be added to dependencies of
/// the current page, otherwise (false, default), the
all triggers that the object is dependent on, including
/// the \a key itself would be added as dependent trig
gers to current rendered page.
/// \return returns true if the entry was found.
///
template<typename Serializable>
bool fetch_data(std::string const &key,Serializable &data,bo
ol notriggers=false)
{
std::string buffer;
if(!fetch(key,buffer,notriggers))
return false;
serialization_traits<Serializable>::load(buffer,data
);
return true;
}
///
/// Store a serializeable object to the cache.
///
/// \param key -- the key that uniquely defines the object.
/// \param data -- the actual object
/// \param triggers -- the set of triggers that the key sho
uld depend on (\a key is added automatically)
/// \param timeout -- maximal object lifetime, -1 is infinit
y
/// \param notriggers -- if \a notriggers is true no frame d
ependent triggers would be added to the current
/// page trigger set. Otherwise (default) current page w
ould depend on the \a key and \a triggers as its
/// dependent triggers.
///
template<typename Serializable>
void store_data(std::string const &key,Serializable const &d
ata,
std::set<std::string> const &triggers=std::s
et<std::string>(),
int timeout=-1,bool notriggers=false)
{
std::string buffer;
serialization_traits<Serializable>::save(data,buffer
);
store(key,buffer,triggers,timeout,notriggers);
}
///
/// Store a serializeable object to the cache.
///
/// \param key -- the key that uniquely defines the object.
/// \param data -- the actual object
/// \param timeout -- maximal object lifetime, -1 is infinit
y
/// \param notriggers -- if \a notriggers is true \a key add
ed to the current
/// page trigger set. Otherwise (default) current page w
ould depend on the \a key
///
template<typename Serializable>
void store_data(std::string const &key,Serializable const &d
ata,int timeout,bool notriggers=false)
{
store_data<Serializable>(key,data,std::set<std::stri
ng>(),timeout,notriggers);
}
private:
void store( std::string const &key,
std::string const &data,
std::set<std::string> const &triggers,
int timeout,
bool notriggers);
bool fetch( std::string const &key,
std::string &buffer,
bool notriggers);
struct _data;
booster::hold_ptr<_data> d;
http::context *context_;
std::set<std::string> triggers_;
booster::intrusive_ptr<impl::base_cache> cache_module_;
uint32_t page_compression_used_ : 1;
uint32_t reserved : 31;
};
} }
#endif #endif
 End of changes. 9 change blocks. 
51 lines changed or deleted 318 lines changed or added


 config.h   config.h 
/* config.h. Generated from config.h.in by configure. */ //
/* config.h.in. Generated from configure.in by autoheader. */ // Copyright (c) 2010 Artyom Beilis (Tonkikh)
//
/* "Make embedded version of cppcms library" */ // Distributed under the Boost Software License, Version 1.0. (See
/* #undef CPPCMS_EMBEDDED */ // accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/* "Embedded with threads" */ //
/* #undef CPPCMS_EMBEDDED_THREAD */ #ifndef BOOSTER_CONFIG_H
#define BOOSTER_CONFIG_H
/* "Enable encrypted sessions" */
#define EN_ENCR_SESSIONS
/* "Fastcgi headers in fastcgi dir" */
/* #undef EN_FASTCGI_LONG_PATH */
/* "Enable fastcgi backend" */
#define EN_FCGI_BACKEND
/* "Enable fork cache" */
#define EN_FORK_CACHE
/* "Enable sqlite sessions" */
#define EN_SQLITE_SESSIONS
/* "Enable tcp cache" */
#define EN_TCP_CACHE
/* "Have C++0x auto" */
/* #undef HAVE_CPP_0X_AUTO */
/* "Have C++0x decltype" */
/* #undef HAVE_CPP_0X_DECLTYPE */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* "Can use $ in indentifiers" */
#define HAVE_DOLLAR_SIGN
/* "Have g++ typeof" */
#define HAVE_GCC_TYPEOF
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* "Have Pshared" */
#define HAVE_PTHREADS_PSHARED
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* "Have g++ typeof" */ #if defined(__WIN32) || defined(_WIN32) || defined(WIN32) || defined(__CYGW
#define HAVE_UNDERSCORE_TYPEOF IN__)
# if defined(DLL_EXPORT)
# if defined(BOOSTER_SOURCE)
# define BOOSTER_API __declspec(dllexport)
# else
# define BOOSTER_API __declspec(dllimport)
# endif
# else
# define BOOSTER_API
# endif
#else // ELF BINARIES
# if defined(BOOSTER_SOURCE) && defined(BOOSTER_VISIBILITY_SUPPORT)
# define BOOSTER_API __attribute__ ((visibility("default")))
# else
# define BOOSTER_API
# endif
#endif
/* Define to 1 if you have the <unistd.h> header file. */ #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__C
#define HAVE_UNISTD_H 1 YGWIN__)
#define BOOSTER_WIN_NATIVE
#endif
/* "Have working BOOST_TYPEOF" */ #if defined(__CYGWIN__)
#define HAVE_WORKING_BOOST_TYPEOF #define BOOSTER_CYGWIN
#endif
/* Name of package */ #if defined(BOOSTER_WIN_NATIVE) || defined(BOOSTER_CYGWIN)
#define PACKAGE "cppcms" #define BOOSTER_WIN32
#endif
/* Define to the address where bug reports for this package should be sent. #if !defined(BOOSTER_WIN_NATIVE)
*/ #define BOOSTER_POSIX
#define PACKAGE_BUGREPORT "artyomtnk@yahoo.com" #endif
/* Define to the full name of this package. */ #if defined(_MSC_VER)
#define PACKAGE_NAME "cppcms" #define BOOSTER_MSVC
// This warning is really not revevant
#pragma warning (disable: 4275 4251)
#endif
/* Define to the full name and version of this package. */ #undef BOOSTER_HAS_CHAR16_T
#define PACKAGE_STRING "cppcms 0.0.8" #undef BOOSTER_HAS_CHAR32_T
#undef BOOSTER_NO_STD_WSTRING
#undef BOOST_NO_SWPRINTF
/* Define to the one symbol short name of this package. */ #ifdef __GNUC__
#define PACKAGE_TARNAME "cppcms" # define BOOSTER_GCC
#endif
/* Define to the version of this package. */ #if defined(__GNUC__) && __GNUC__ < 4
#define PACKAGE_VERSION "0.0.8" # define BOOSTER_GCC3
#endif
/* Define to 1 if you have the ANSI C header files. */ #if defined(__CYGWIN__) || (defined(BOOSTER_WIN32) && defined(BOOSTER_GCC3)
#define STDC_HEADERS 1 )
# define BOOSTER_NO_STD_WSTRING
#endif
/* "Use boost::asio" */ #if defined(BOOSTER_WIN32) && defined(BOOSTER_GCC)
/* #undef USE_BOOST_ASIO */ # define BOOST_NO_SWPRINTF
#endif
/* Version number of package */ #endif /// BOOSTER_CONFIG_H
#define VERSION "0.0.8"
 End of changes. 13 change blocks. 
91 lines changed or deleted 62 lines changed or added


 cppcms_error.h   cppcms_error.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_ERROR_H #ifndef CPPCMS_ERROR_H
#define CPPCMS_ERROR_H #define CPPCMS_ERROR_H
#include <cppcms/defs.h>
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
namespace cppcms { namespace cppcms {
class cppcms_error : public std::runtime_error { ///
/// \brief Exception thrown by CppCMS framework.
///
/// Every exception that is thrown from CppCMS modules derived from this ex
ception.
///
class CPPCMS_API cppcms_error : public std::runtime_error {
std::string strerror(int err); std::string strerror(int err);
public: public:
///
/// Create an object with error code err (errno) and a message \a er
ror
///
cppcms_error(int err,std::string const &error); cppcms_error(int err,std::string const &error);
///
/// Create an object with message \a error
///
cppcms_error(std::string const &error) : std::runtime_error(error) { }; cppcms_error(std::string const &error) : std::runtime_error(error) { };
}; };
} }
#endif /* _HTTP_ERROR_H */ #endif /* _HTTP_ERROR_H */
 End of changes. 5 change blocks. 
1 lines changed or deleted 38 lines changed or added


 form.h   form.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_FORM_H #ifndef CPPCMS_FORM_H
#define CPPCMS_FORM_H #define CPPCMS_FORM_H
#include <cppcms/defs.h>
#include <booster/noncopyable.h>
#include <string> #include <string>
#include <set> #include <set>
#include <map> #include <map>
#include <list> #include <list>
#include <vector> #include <vector>
#include <boost/regex_fwd.hpp> #include <stack>
#include <boost/noncopyable.hpp>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
#include <cppcms/http_context.h>
namespace cgicc { class Cgicc; } #include <cppcms/http_request.h>
#include <cppcms/http_response.h>
#include <booster/copy_ptr.h>
#include <booster/perl_regex.h>
#include <booster/shared_ptr.h>
#include <cppcms/cppcms_error.h>
#include <cppcms/util.h>
#include <cppcms/localization.h>
namespace cppcms { namespace cppcms {
using namespace std;
class base_form {
public:
virtual ~base_form();
enum { as_html = 0,
as_xhtml= 1,
as_p = 0,
as_table= 1<<1,
as_ul = 2<<1,
as_dl = 3<<1,
as_space= 4<<1,
as_mask = 7<<1,
error_with = 0,
error_no = 0x10,
error_mask = 0x10, };
virtual string render(int how) = 0; namespace http {
virtual void load(cgicc::Cgicc const &cgi) = 0; class file;
inline void load(cgicc::Cgicc const *cgi) { if(cgi) load(*cgi); } }
virtual bool validate() = 0;
virtual void clear() = 0;
};
class form : public boost::noncopyable , public base_form { namespace widgets {
protected: class base_widget;
list<base_form *> elements; }
public:
void append(base_form *ptr);
inline form &operator & (base_form &f) { append(&f); return *this; }
virtual string render(int how);
virtual void load(cgicc::Cgicc const &cgi);
virtual bool validate();
virtual void clear();
};
namespace widgets { ///
/// \brief this struct holds various flags for HTML generation contr
ol
///
struct form_flags {
///
/// This enum represents HTML/XHTML switch
///
typedef enum {
as_html = 0, ///< render form/widget as ordinary
HTML
as_xhtml= 1, ///< render form/widget as XHTML
} html_type;
class base_widget : public base_form { ///
public: /// This enum represents the style of widgets generation
bool is_set; ///
base_widget(string name="",string msg=""); typedef enum {
string id; as_p = 0 , ///< Render each widget using paragrap
string name; hs
string msg; as_table= 1 , ///< Render each widget using table
string error_msg; as_ul = 2 , ///< Render each widget using unordere
string help; d list
bool is_valid; as_dl = 3 , ///< Render each widget using definiti
virtual string render(int how); ons list
virtual string render_input(int ) = 0; as_space= 4 ///< Render each widget using simple b
virtual string render_error(); lank space separators
virtual void clear(); } html_list_type;
virtual bool validate();
void not_valid() { is_valid=false; }
};
class text : public base_widget { ///
protected: /// This is special flag for partial generation of widget's
string type; HTML
unsigned low; ///
int high; typedef enum {
public: first_part = 0, ///< Render part 1; HTML attributes
string value; can be inserted after it
text(string name="",string msg="") : base_widget(name,msg) , type("t second_part = 1 ///< Render part 2 -- compete part
ext"){ low=0,high=-1; }; 1.
void set_limits(int min,int max) { low=min,high=max; } } widget_part_type;
void set_nonempty() { low = 1, high=-1;}; };
void set_limits(string e,int min,int max) { error_msg=e; set_limits(
min,max); }
void set_nonempty(string e){ error_msg=e; set_nonempty(); };
virtual string render_input(int how);
void set(string const &s);
string &str();
string const &get();
virtual bool validate();
virtual void load(cgicc::Cgicc const &cgi);
};
template<typename T> ///
class number: public text { /// \brief This class represent the context required for generation
T min,max,value; of HTML for the widgets
bool check_low,check_high; ///
public: class CPPCMS_API form_context : public form_flags
number(string name="",string msg="") :
text(name,msg),
value(0),check_low(false),check_high(false)
{};
void set_low(T a)
{
min=a;
check_low=true;
set_nonempty();
}
void set_high(T b)
{
max=b;
check_high=true;
set_nonempty();
}
void set_range(T a,T b)
{ {
min=a; max=b; public:
check_low=check_high=true; ///
set_nonempty(); /// Default constructor
} ///
virtual bool validate() form_context();
///
/// Copy-constructor
///
form_context(form_context const &other);
///
/// Assignment
///
form_context const &operator = (form_context const &other);
///
/// Create a rendering context
///
/// \param output the output std::ostream to write HTML to
/// \param ht flags representing the type of HTML that shoul
d be generated
/// \param hlt flag that defines the style of widgets genera
tion
///
form_context( std::ostream &output,
html_type ht = form_flags::as_html,
html_list_type hlt=form_flags::as_p);
///
/// Destructor
///
~form_context();
///
/// Set an HTML/XHTML flag
///
void html(html_type t);
///
/// Set widgets rendering style
///
void html_list(html_list_type t);
///
/// Set flag for rendering of partial widget
///
void widget_part(widget_part_type t);
///
/// Set the output stream
///
void out(std::ostream &out);
///
/// Set an HTML/XHTML flag - default as_html
///
html_type html() const;
///
/// Get widgets rendering style - default as_p
///
html_list_type html_list() const;
///
/// Get the part of widget that should be generated, see wid
get_part_type, default first_part
///
widget_part_type widget_part() const;
///
/// Get the output stream
///
std::ostream &out() const;
private:
uint32_t html_type_;
uint32_t html_list_type_;
uint32_t widget_part_type_;
std::ostream *output_;
uint32_t reserved_1;
uint32_t reserved_2;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// \brief This class is base class of any form or form-widget used
in CppCMS.
///
/// It provides abstract basic operations that every widget or form
should implement
///
class CPPCMS_API base_form : public form_flags {
public:
///
/// Render the widget to std::ostream \a output with control
flags \a flags.
/// Usually this function is called directly by template ren
dering functions
///
virtual void render(form_context &context) = 0;
///
/// Load the information of form from the provided http::con
text \a context.
/// User calls this function for loading all information fro
m the raw POST/GET
/// form to internal widget representation.
///
virtual void load(http::context &context) = 0;
///
/// Validate the form according to defined rules. If all che
cks are OK
/// true is returned. If some widget or form fails, false is
returned.
///
virtual bool validate() = 0;
///
/// Clear the form from all user provided data.
///
virtual void clear() = 0;
///
/// Set parent of this form. Used internaly, should not be u
sed
///
virtual void parent(base_form *subform) = 0;
///
/// Get parent of this form. If this is topmost form, NULL i
s returned
///
virtual base_form *parent() = 0;
base_form();
virtual ~base_form();
};
///
/// \brief The \a form is a container that used to collect other wid
gets and forms to single unit
///
/// Generally various widgets and forms are combined into single for
m in order to simplify rendering
/// and validation of forms that include more then one widget
///
class CPPCMS_API form : public booster::noncopyable,
public base_form
{ {
if(!text::validate()) public:
return false;
if(!str().empty()) { form();
std::istringstream ss(str()); virtual ~form();
ss>>value;
if(ss.fail() || !ss.eof()) ///
is_valid=false; /// Render all widgets and sub-forms to \a output, using
/// base_form \a flags
///
virtual void render(form_context &context);
///
/// Load all information from widgets from http::context \a
cont
///
virtual void load(http::context &cont);
///
/// validate all subforms and widgets. If at least one of th
em fails,
/// false is returned. Otherwise, true is returned.
///
virtual bool validate();
///
/// Clear all subforms and widgets for all loaded data.
///
virtual void clear();
///
/// adds \a subform to form, the ownership is not transferre
d to
/// to the parent
///
void add(form &subform);
///
/// add \a subform to form, the ownership is transferred to
/// the parent and subform will be destroyed together with
/// the parent
///
void attach(form *subform);
///
/// adds \a widget to form, the ownership is not transferred
to
/// to the parent
///
void add(widgets::base_widget &widget);
///
/// add \a widget to form, the ownership is transferred to
/// the parent the widget will be destroyed together with
/// the parent form
///
void attach(widgets::base_widget *widget);
///
/// Shortcut to \a add
///
inline form &operator + (form &f)
{
add(f);
return *this;
} }
if((check_low || check_high) && str().empty())
return (is_valid=false);
if(check_low && value<min)
return (is_valid=false);
if(check_high && value>max)
return (is_valid=false);
return (is_valid=true);
}
T get() const { return value; };
void set(T v)
{
value=v;
std::ostringstream ss;
ss<<v;
text::set(ss.str());
}
};
class password: public text { ///
password *other; /// Shortcut to \a add
public: ///
password(string name="",string msg="") : text(name,msg),other(0) {} inline form &operator + (widgets::base_widget &f)
; {
void set_equal(password &p2) { other=&p2; } ; add(f);
virtual bool validate(); return *this;
virtual string render_input(int how); }
}; ///
class textarea: public text { /// Set parent of this form. Used internaly, should not be u
public: sed. It is called
int rows,cols; /// when the form is added or attached to other form.
textarea(string name="",string msg="") : text(name,msg) { rows=cols= ///
-1; };
virtual string render_input(int how);
};
class regex_field : public text { virtual void parent(base_form *subform);
boost::regex const *exp;
public:
regex_field() : exp(0) {}
regex_field(boost::regex const &e,string name="",string msg="") : te
xt(name,msg),exp(&e) {}
virtual bool validate();
};
class email : public regex_field { ///
public: /// Get parent of this form. If this is topmost form, NULL i
email(string name="",string msg=""); s returned
}; /// It is assumed that the parent is always form.
///
virtual form *parent();
class checkbox: public base_widget { ///
public: /// \brief Input iterator that is used to iterate over all w
string input_value; idgets of the form
bool value; ///
checkbox(string name="",string msg="") : base_widget(name,msg),input /// This class is mainly used by templates framework for wid
_value("1") gets rendering. It
{ /// walks on all widgets and subforms recursively.
set(false); ///
}; /// Note: it walks over widgets only:
virtual string render_input(int how); ///
void set(bool v) { value=v; is_set=true; }; /// \code
void set(string const &s) { input_value=s; }; /// iterator p=f.begin();
bool get() { return value; }; /// if(p!=f.end())
virtual void load(cgicc::Cgicc const &cgi); /// if p!=f.end() --> *p is derived from widgets::base_wid
}; get.
/// \endcode
///
class select_multiple : public base_widget { class CPPCMS_API iterator : public std::iterator<std::input_
int min; iterator_tag,widgets::base_widget>
public: {
int size; public:
select_multiple(string name="",int s=0,string msg="") : base_widget( ///
name,msg),min(-1),size(s) {}; /// End iterator
set<string> chosen; ///
map<string,string> available;
void add(string val,string opt,bool selected=false);
void add(int val,string opt,bool selected=false);
void add(string v,bool s=false) { add(v,v,s); }
void add(int v,bool s=false) {
ostringstream ss;
ss<<v;
add(v,ss.str(),s);
}
set<string> &get() { return chosen; };
set<int> geti();
void set_min(int n) { min=n; };
virtual string render_input(int how);
virtual bool validate();
virtual void load(cgicc::Cgicc const &cgi);
virtual void clear();
};
class select_base : public base_widget { iterator();
public:
string value; ///
struct option { /// Create widgets iterator
string value; ///
string option; iterator(form &);
///
/// Destructor
///
~iterator();
///
/// Copy the iterator, this is not cheap operation.
///
iterator(iterator const &other);
///
/// Assign the iterator, this is not cheap operation
.
///
iterator const &operator = (iterator const &other);
///
/// Returns the underlying widget. Condition: *this!
=iterator()
///
widgets::base_widget *operator->() const
{
return get();
}
///
/// Returns the underlying widget. Condition: *this!
=iterator()
///
widgets::base_widget &operator*() const
{
return *get();
}
///
/// Check if two iterators pointing to same element
///
bool operator==(iterator const &other) const
{
return equal(other);
}
///
/// Check if two iterators pointing to different ele
ment
///
bool operator!=(iterator const &other) const
{
return !equal(other);
}
///
/// Post Increment operator, it forward the iterator
no text widget.
/// Note it does not point to higher level form cont
ainer.
///
/// Note: prefer using ++i then i++ as copying itera
tor is not cheap.
///
iterator operator++(int unused)
{
iterator tmp(*this);
next();
return tmp;
}
///
/// Increment operator. It forward the iterator no t
ext widget.
/// Note it does not point to higher level form cont
ainer
///
iterator &operator++()
{
next();
return *this;
}
private:
friend class form;
bool equal(iterator const &other) const;
void zero();
void next();
widgets::base_widget *get() const;
std::stack<unsigned> return_positions_;
form *current_;
unsigned offset_;
struct _data;
booster::copy_ptr<_data> d;
};
///
/// Returns an iterator to the first widget.
///
iterator begin();
///
/// Returns the end-iterator for walking over all widgets.
///
iterator end();
private:
friend class iterator;
struct _data;
// Widget and ownership true mine
typedef std::pair<base_form *,bool> widget_type;
std::vector<widget_type> elements_;
form *parent_;
booster::hold_ptr<_data> d;
}; };
list<option> select_list;
select_base(string name="",string msg="") : base_widget(name,msg){};
void add(string value,string option);
void add(string v) { add(v,v); }
void add(int value,string option);
void add(int v) {
ostringstream ss;
ss<<v;
add(v,ss.str());
}
void set(string value);
void set(int value);
string get();
int geti();
virtual bool validate();
virtual void load(cgicc::Cgicc const &cgi);
};
class select : public select_base { ///
int size; /// \brief This namespace includes all widgets (html-forms) supporte
public: d by cppcms
select(string n="",string m="") : select_base(n,m),size(-1) {}; ///
void set_size(int n) { size=n;} namespace widgets {
virtual string render_input(int how);
};
class radio : public select_base { ///
bool add_br; /// \brief this class is the base class of all renderable wi
public: dgets that can be
radio(string name="",string msg="") : select_base(name,msg),add_br(f /// used together with forms
alse) {} ///
void set_vertical() { add_br=true; } /// All cppcms widgets are derived from this class. User, wh
virtual string render_input(int how); o want to create
}; /// its own custom widgets must derive them from this class
///
class hidden : public text { class CPPCMS_API base_widget :
public: public base_form,
hidden(string n="",string msg="") : text(n,msg) { set_nonempty(); }; public booster::noncopyable
virtual string render(int how); {
}; public:
class submit : public base_widget { ///
public: /// Default constructor
string value; ///
bool pressed; base_widget();
submit(string name="",string button="",string msg="") : base_widget(
name,msg), value(button),pressed(false) {};
virtual string render_input(int);
virtual void load(cgicc::Cgicc const &cgi);
};
} // widgets virtual ~base_widget();
class widgetset { ///
public: /// Check if a value was assigned to widget. Usually
typedef vector<widgets::base_widget*> widgets_t; becomes true
widgets_t widgets; /// when user assignees value to widget or the widge
inline widgetset &operator<<(widgets::base_widget &w) { widgets.push t is loaded.
_back(&w); return *this; } ///
widgetset(); bool set();
virtual string render(int how);
virtual ~widgetset(); ///
}; /// After executing validation, each widget can be t
ested for validity
///
bool valid();
///
/// Get html id attribute
///
std::string id();
///
/// Get html name attribute
///
std::string name();
///
/// Get short message that would be displayed near t
he widget
///
locale::message message();
///
/// Check if message is set
///
bool has_message();
///
/// Get associated error message that would be displ
ayed near the widget
/// if widget validation failed.
///
locale::message error_message();
///
/// Check if error message is set
///
bool has_error_message();
///
/// Get long description for specific widget
///
locale::message help();
///
/// Check if help message is set
///
bool has_help();
///
/// Get disabled html attribute
///
bool disabled();
///
/// Set/Unset disabled html attribute
///
void disabled(bool);
///
/// Get the general user defined attributes string t
hat can be added to widget
///
std::string attributes_string();
///
/// Set the existence of content for widget. By defa
ult the widget is not set.
/// Any value fetch from "unset" widget by conventio
n should throw an exception
/// Calling set with true -- changes state to "set"
and with false to "unset"
///
void set(bool);
///
/// Set validity state of widget. By default the wid
get is valid. When it
/// passes validation its validity state is changed
by calling this function
///
/// Note: widget maybe not-set but still valid and i
t may be set but not-valid
///
void valid(bool);
///
/// Set html id attribute of the widget
///
void id(std::string);
///
/// Set html name attribute of the widget. Note: if
this attribute
/// is not set, the widget would not be able to be l
oaded from POST/GET
/// data.
///
void name(std::string);
///
/// Set short description for the widget. Generally
it is good idea to
/// define this value.
///
/// Short message can be also set using base_widget
constructor
///
void message(std::string);
///
/// Set short translatable description for the widge
t. Generally it is good idea to
/// define this value.
///
/// Short message can be also set using base_widget
constructor
///
void message(locale::message const &);
///
/// Set error message that is displayed for invalid
widgets.
///
/// If it is not set, simple "*" is shown
///
void error_message(std::string);
///
/// Set translatable error message that is displayed
for invalid widgets.
///
/// If it is not set, simple "*" is shown
///
void error_message(locale::message const &);
///
/// Set longer help message that describes this widg
et
///
void help(std::string);
///
/// Set translatable help message that describes thi
s widget
///
void help(locale::message const &msg);
///
/// Set general html attributes that are not support
ed
/// directly. For example:
///
/// \code
/// my_widget.attributes_string("style='direction:r
tl' onclick='return foo()'");
/// \endcode
///
/// This string is inserted as-is just behind render
_input_start
///
void attributes_string(std::string v);
///
/// Render full widget with error messages and decor
ations as paragraphs
/// or table elements to \a output
///
virtual void render(form_context &context);
///
/// This is a virtual member function that should be
implemented by each widget
/// It executes actual rendering of the input HTML f
orm
///
virtual void render_input(form_context &context) = 0
;
///
/// Clean the form. Calls set(false) as well
///
virtual void clear();
///
/// Validate form. If not overridden it sets widget
to valid
///
virtual bool validate();
///
/// Render standard common attributes like id, name,
disabled etc.
///
virtual void render_attributes(form_context &context
);
///
/// Set parent of this widget. Used internaly, shoul
d not be used. It is called
/// when the form is added or attached to other form
.
///
virtual void parent(base_form *subform);
///
/// Get parent of this form. If this is topmost form
, NULL is returned
/// Note widget is assumed to be assigned to forms o
nly
///
virtual form *parent();
protected:
///
/// This function should be called by overloaded loa
d/render methods
/// before rendering/loading starts
///
void auto_generate(form_context *context = 0);
private:
void generate(int position,form_context *context = 0
);
std::string id_;
std::string name_;
locale::message message_;
locale::message error_message_;
locale::message help_;
std::string attr_;
form *parent_;
uint32_t is_valid_ : 1;
uint32_t is_set_ : 1;
uint32_t is_disabled_ : 1;
uint32_t is_generation_done_ : 1;
uint32_t has_message_ : 1;
uint32_t has_error_ : 1;
uint32_t has_help_ : 1;
uint32_t reserverd_ : 25;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// \brief this is the widget that is used as base for text
input field representation
///
/// This widget is used as base class for other widgets that
are used for
/// text input like: text, textarea, etc.
///
/// This widget does much more then reading simple filed dat
a from the POST
/// or GET form, it performs charset validation and if requi
red conversion
/// to and from Unicode charset to locale charset.
///
class CPPCMS_API base_text : virtual public base_widget {
public:
base_text();
virtual ~base_text();
///
/// Get the string that contains input value of the
widget.
///
std::string value();
///
/// Set the widget content before rendering, the val
ue \a v
///
void value(std::string v);
///
/// Acknowledge the validator that this text widget
should contain some text.
/// similar to limits(1,-1)
///
void non_empty();
///
/// Set minimum and maximum limits for text size. No
te max == -1 indicates that there
/// is no maximal limit, min==0 indicates that there
is no minimal limit.
///
/// Note: these numbers represent the length in Unic
ode code points (even if the encoding
/// is not Unicode). If character set validation is
disabled, then these number represent
/// the number of octets in the string.
///
void limits(int min,int max);
///
/// Get minimal and maximal size limits,
///
std::pair<int,int> limits();
///
/// Acknowledge the validator if it should not check
the validity of the charset.
/// Default -- enabled
///
/// Generally you should not use this option unless
you want to load some raw data as
/// form input, or the character set is different fr
om the defined in locale.
///
void validate_charset(bool );
///
/// Returns true if charset validation is enabled.
///
bool validate_charset();
///
/// Validate the widget content according to rules a
nd charset encoding.
///
/// Notes:
///
/// - The charset validation is very efficient for
variable length UTF-8 encoding,
/// and most popular fixed length ISO-8859-*, win
dows-125* and koi8* encodings, for other
/// encodings iconv conversion is used for actual
validation.
/// - Special characters (that not allowed in HTML)
are assumed as forbidden, even if they are
/// valid code points (like NUL = 0 or DEL=127).
///
virtual bool validate();
///
/// Load the widget for http::context. It used the l
ocale given in the context for
/// validation of text.
///
virtual void load(http::context &);
private:
std::string value_;
int low_;
int high_;
bool validate_charset_;
size_t code_points_;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// This class represents a basic widget that generates html
for common widgets
/// that use <input \/> HTML tag.
///
/// It allows you creating your own widgets easier as it doe
s most of job required for
/// generating the HTML and user is required only to generat
e actual value like
/// value="10.34" as for numeric widget.
///
class CPPCMS_API base_html_input : virtual public base_widge
t {
public:
///
/// Creates new instance, \a type is HTML type tag o
f the input element, for example "text" or
/// "password".
///
base_html_input(std::string const &type);
///
/// Virtual destructor...
///
virtual ~base_html_input();
///
/// This function is actual HTML generation function
that calls render_value where needed.
///
virtual void render_input(form_context &context);
protected:
///
/// This is what user actually expected to implement
. Write actual value HTML tag.
///
virtual void render_value(form_context &context) = 0
;
private:
struct _data;
booster::hold_ptr<_data> d;
std::string type_;
};
///
/// \brief This class represents html input of type text
///
class CPPCMS_API text : public base_html_input, public base_
text
{
public:
///
/// Create text field widget
///
text();
///
/// This constructor is provided for use by derived
classes where it is required
/// to change the type of widget, like text, passwor
d, etc.
///
text(std::string const &type);
~text();
///
/// Set html attribute size of the widget
///
void size(int n);
///
/// Get html attribute size of the widget, -1 undefi
ned
///
int size();
virtual void render_attributes(form_context &context
);
virtual void render_value(form_context &context);
private:
int size_;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// This widget represents hidden input form type. It is use
d to provide
/// some invisible to user information.
///
/// I has same properties that text widget has but it does n
ot render any HTML
/// related to message(), help() and other informational typ
es.
///
/// When your render the form in templates it is good idea t
o render it separately
/// to make sure that no invalid HTML would be created.
///
class CPPCMS_API hidden : public text
{
public:
hidden();
~hidden();
///
/// Actual rendering function that is redefined
///
virtual void render(form_context &context);
private:
struct _data;
booster::hold_ptr<_data> d;
};
///
/// This text widget behaves similarly to text widget but us
es rather HTML
/// textarea and not input HTML tags
///
class CPPCMS_API textarea : public base_text
{
public:
textarea();
~textarea();
///
/// Get number of rows in textarea -- default -1 --
undefined
///
int rows();
///
/// Get number of columns in textarea -- default -1
-- undefined
///
int cols();
///
/// Set number of rows in textarea
///
void rows(int n);
///
/// Set number of columns in textarea
///
void cols(int n);
virtual void render_input(form_context &context);
private:
int rows_,cols_;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// \brief Widget for number input. It is template class tha
t assumes that T is number
///
template<typename T>
class numeric: public base_html_input {
public:
numeric() :
base_html_input("text"),
check_low_(false),
check_high_(false),
non_empty_(false)
{
}
///
/// Defines that this widget should have some value
///
void non_empty()
{
non_empty_=true;
}
///
/// Get loaded widget value
///
T value()
{
if(!set())
throw cppcms_error("Value not loaded
");
return value_;
}
///
/// Set widget value
///
void value(T v)
{
set(true);
value_=v;
}
///
/// Set minimal input number value
///
void low(T a)
{
min_=a;
check_low_=true;
non_empty();
}
///
/// Set maximal input number value
///
void high(T b)
{
max_=b;
check_high_=true;
non_empty();
}
///
/// Same as low(a); high(b);
///
void range(T a,T b)
{
low(a);
high(b);
}
///
/// Render first part of widget
///
virtual void render_value(form_context &context)
{
if(set())
context.out()<<"value=\""<<value_<<"
\" ";
else
context.out()<<"value=\""<<util::esc
ape(loaded_string_)<<"\" ";
}
virtual void clear()
{
base_html_input::clear();
loaded_string_.clear();
}
///
/// Load widget data
///
virtual void load(http::context &context)
{
auto_generate();
loaded_string_.clear();
set(false);
valid(true);
http::request::form_type::const_iterator p;
http::request::form_type const &request=cont
ext.request().post_or_get();
p=request.find(name());
if(p==request.end()) {
return;
}
else {
loaded_string_=p->second;
if(loaded_string_.empty())
return;
std::istringstream ss(loaded_string_
);
ss.imbue(context.locale());
ss>>value_;
if(ss.fail() || !ss.eof())
valid(false);
else
set(true);
}
}
///
/// Validate widget
///
virtual bool validate()
{
if(!valid())
return false;
if(!set()) {
if(non_empty_) {
valid(false);
return false;
}
return true;
}
if(check_low_ && value_ <min_) {
valid(false);
return false;
}
if(check_high_ && value_ > max_) {
valid(false);
return false;
}
return true;
}
private:
T min_,max_,value_;
bool check_low_;
bool check_high_;
bool non_empty_;
std::string loaded_string_;
};
///
/// \brief The password widget is a simple text widget with
some different
//
class CPPCMS_API password: public text {
public:
password();
~password();
///
/// Set equality constraint to password widget -- th
is password should be
/// equal to other one \a p2. Usefull for creation o
f new passwords -- if passwords
/// are not equal, validation would fail
///
void check_equal(password &p2);
virtual bool validate();
private:
struct _data;
booster::hold_ptr<_data> d;
password *password_to_check_;
};
///
/// \brief This class is extinction of text widget that vali
dates it using additional regular expression
///
class CPPCMS_API regex_field : public text {
public:
regex_field();
///
/// Create widget using regular expression \a e
///
regex_field(booster::regex const &e);
///
/// Create widget using regular expression \a e
///
regex_field(std::string const &e);
///
/// Set regular expression
///
void regex(booster::regex const &e);
~regex_field();
virtual bool validate();
private:
booster::regex expression_;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// \brief widget that checks that input is valid e-mail
///
class CPPCMS_API email : public regex_field {
public:
email();
~email();
private:
struct _data;
booster::hold_ptr<_data> d;
};
///
/// This class represent an html checkbox input widget
///
class CPPCMS_API checkbox: public base_html_input {
public:
///
/// The constructor that allows you to specify other
type like "radio"
///
checkbox(std::string const &type);
///
/// Default constructor, type checkbox
///
checkbox();
virtual ~checkbox();
///
/// Returns true of box was checked (selected)
///
bool value();
///
/// Set checked state
///
void value(bool is_set);
///
/// Get unique identification of the checkbox
///
std::string identification();
///
/// Set unique identification to the checkbox, usefu
l when you want to
/// have many options with same name
///
void identification(std::string const &);
virtual void render_value(form_context &context);
virtual void load(http::context &context);
private:
struct _data;
booster::hold_ptr<_data> d;
std::string identification_;
bool value_;
};
///
/// Select multiple elements widget
///
class CPPCMS_API select_multiple : public base_widget {
public:
select_multiple();
~select_multiple();
///
/// Add a new option to list with display name \a ms
g, and specify if it is initially
/// selected, default false
///
void add(std::string const &msg,bool selected=false)
;
///
/// Add a new option to list with display name \a ms
g, and specify if it is initially
/// selected, default false, providing unique identi
fication for the element \a id
///
void add(std::string const &msg,std::string const &i
d,bool selected=false);
///
/// Add a new option to list with localized display
name \a msg, and specify if it is initially
/// selected, default false
///
void add(locale::message const &msg,bool selected=fa
lse);
///
/// Add a new option to list with localized display
name \a msg, and specify if it is initially
/// selected, default false, providing unique identi
fication for the element \a id
///
void add(locale::message const &msg,std::string cons
t &id,bool selected=false);
///
/// Get the mapping of all selected items according
to the order they where added to the list
///
std::vector<bool> selected_map();
///
/// Get all selected items ids according to the orde
r they where added to the list, if no
/// specific id was given, strings "0", "1"... would
be used
///
std::set<std::string> selected_ids();
///
/// Get minimal amount of options that should be cho
sen, default = 0
///
unsigned at_least();
///
/// Set minimal amount of options that should be cho
sen, default = 0
///
void at_least(unsigned v);
///
/// Get maximal amount of options that should be cho
sen, default unlimited
///
unsigned at_most();
///
/// Set maximal amount of options that should be cho
sen, default unlimited
///
void at_most(unsigned v);
///
/// Same as at_least(1)
///
void non_empty();
///
/// Get the number of rows used for widget, default
0 -- undefined
///
unsigned rows();
///
/// Set the number of rows used for widget, default
0 -- undefined
///
void rows(unsigned n);
virtual void render_input(form_context &context);
virtual bool validate();
virtual void load(http::context &context);
virtual void clear();
private:
struct _data;
booster::hold_ptr<_data> d;
struct element {
element();
element(std::string const &v,locale::message
const &msg,bool sel);
element(std::string const &v,std::string con
st &msg,bool sel);
uint32_t selected : 1;
uint32_t need_translation : 1;
uint32_t original_select : 1;
uint32_t reserved : 29;
std::string id;
std::string str_option;
locale::message tr_option;
friend std::ostream &operator<<(std::ostream
&out,element const &el);
};
std::vector<element> elements_;
unsigned low_;
unsigned high_;
unsigned rows_;
};
///
/// This is the base class for "select" like widgets which i
ncludes dropdown list
/// and radio buttons set.
///
class CPPCMS_API select_base : public base_widget {
public:
select_base();
virtual ~select_base();
///
/// Add new entry to selection list
///
void add(std::string const &string);
///
/// Add new entry to selection list giving the uniqu
e entry identification \a id
///
void add(std::string const &string,std::string const
&id);
///
/// Add new localized entry to selection list
///
void add(locale::message const &msg);
///
/// Add new localized entry to selection list giving
the unique entry identification \a id
///
void add(locale::message const &msg,std::string cons
t &id);
///
/// Return the selected entry number in the list sta
rting from 0. -1 indicates that nothing
/// was selected.
///
int selected();
///
/// Return the identification string of the selected
entry, empty string indicates that
/// nothing was selected
///
std::string selected_id();
///
/// Select entry number \a no in the list for render
ing
///
void selected(int no);
///
/// Select entry with identification \a id in the li
st for rendering
///
void selected_id(std::string id);
///
/// Require that item should be selected (for valida
tion)
///
void non_empty();
virtual void render_input(form_context &context) = 0
;
virtual bool validate();
virtual void load(http::context &context);
virtual void clear();
protected:
struct CPPCMS_API element {
element();
element(std::string const &v,locale::message
const &msg);
element(std::string const &v,std::string con
st &msg);
element(element const &);
element const &operator=(element const &);
~element();
uint32_t need_translation : 1;
uint32_t reserved : 31;
std::string id;
std::string str_option;
locale::message tr_option;
private:
struct _data;
booster::copy_ptr<_data> d;
};
std::vector<element> elements_;
private:
struct _data;
booster::hold_ptr<_data> d;
int selected_;
int default_selected_;
uint32_t non_empty_ : 1;
uint32_t reserverd : 32;
};
///
/// Select widget that uses drop-down list
///
class CPPCMS_API select : public select_base {
public:
select();
virtual ~select();
virtual void render_input(form_context &context);
private:
struct _data;
booster::hold_ptr<_data> d;
};
///
/// Select widget that uses a set of radio buttons
///
class CPPCMS_API radio : public select_base {
public:
radio();
virtual ~radio();
virtual void render_input(form_context &context);
///
/// Return the rendering order
///
bool vertical();
///
/// Set rendering order of the list one behind other
(default) or in same line.
///
void vertical(bool);
private:
uint32_t vertical_ : 1;
uint32_t reserved_ : 31;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// Class that represents file upload form entry
///
class CPPCMS_API file : public base_html_input {
public:
///
/// Ensure that file is uploaded.
///
void non_empty();
///
/// Set minimum and maximum limits for file size. No
te max == -1 indicates that there
/// is no maximal limit, min==0 indicates that there
is no minimal limit.
///
///
void limits(int min,int max);
///
/// Get minimal and maximal size limits,
///
std::pair<int,int> limits();
///
/// Set filename validation pattern. For example ".*
\\.(jpg|jpeg|png)"
///
/// Please, note that it is good idea to check magic
number as well.
///
void filename(booster::regex const &fn);
///
/// Get regular expression for filename validation
///
booster::regex filename();
///
/// Validate the filename's charset (default is on)
///
void validate_filename_charset(bool);
///
/// Get validation option for filename's charset
///
bool validate_filename_charset();
///
/// Get uploaded file
///
booster::shared_ptr<http::file> value();
///
/// Set required file mime type
///
void mime(std::string const &);
///
/// Set regular expression that checks for valid mim
e type
///
void mime(booster::regex const &expr);
///
/// Add a string that represents a valid magic numbe
r that shoud exist on begging of file
///
/// By default no tests are performed
///
void add_valid_magic(std::string const &);
virtual void load(http::context &context);
virtual void render_value(form_context &context);
virtual bool validate();
file();
~file();
private:
int size_min_;
int size_max_;
std::vector<std::string> magics_;
std::string mime_string_;
booster::regex mime_regex_;
booster::regex filename_regex_;
uint32_t check_charset_ : 1;
uint32_t check_non_empty_ : 1;
uint32_t reserved_ : 30;
booster::shared_ptr<http::file> file_;
struct _data;
booster::hold_ptr<_data> d;
};
///
/// Submit button widget
///
class CPPCMS_API submit : public base_html_input {
public:
submit();
~submit();
///
/// Returns true if this specific button was pressed
///
bool value();
///
/// Sets the text on button
///
void value(std::string val);
///
/// Sets the text on button
///
void value(locale::message const &msg);
virtual void render_value(form_context &context);
virtual void load(http::context &context);
private:
struct _data;
booster::hold_ptr<_data> d;
bool pressed_;
locale::message value_;
};
} // widgets
} //cppcms } //cppcms
#endif // CPPCMS_FORM_H #endif // CPPCMS_FORM_H
 End of changes. 27 change blocks. 
256 lines changed or deleted 1714 lines changed or added


 session_api.h   session_api.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_API_H #ifndef CPPCMS_SESSION_API_H
#define CPPCMS_SESSION_API_H #define CPPCMS_SESSION_API_H
#include <boost/noncopyable.hpp>
#include <cppcms/defs.h>
#include <booster/noncopyable.h>
#include <booster/shared_ptr.h>
#include <string> #include <string>
namespace cppcms { namespace cppcms {
class worker_thread;
class session_interface; class session_interface;
class session_api : private boost::noncopyable { ///
/// \brief This class represents the most generic implementation of session
storage device
///
/// This classes are created using session_api_factory and are designed to
be reimplemented by users
/// to provide an additional backends.
///
/// This class is most generic that does not provide any goodies with excep
tion of setting or getting session cookie,
/// the user should generally take a look on sessions::session_storage or s
essions::encryptor for easier implementation of session storage
///
/// Note: these objects must be thread safe.
///
class session_api : public booster::noncopyable
{
public: public:
virtual void save(session_interface *,std::string const &data,time_t ///
timeout, bool new_data) = 0; /// Save session's data:
virtual bool load(session_interface *,std::string &data,time_t &time ///
out) = 0; /// \param iface - the session_interface object that allows set sess
virtual void clear(session_interface *) = 0; ion cookie
virtual ~session_api(){}; /// \param data - the data that should be stored in the session
/// \param timeout - the absolute expiration POSIX time
/// \param new_data - flag that marks that new session object should
be created regardless of current cookie value
/// \param on_server - flag that marks that the data must be stored
on the server and not in cookies only
///
virtual void save(session_interface &iface,std::string const &data,t
ime_t timeout, bool new_data, bool on_server) = 0;
///
/// Load session's data
///
/// \param iface - the session_interface object that allows read and
set session cookie
/// \param data - the string that should be filled with session data
/// \param timeout - the expiration time of this session object
/// \return true of session was loaded, false otherwise
virtual bool load(session_interface &iface,std::string &data,time_t
&timeout) = 0;
///
/// Remove the session object
///
/// \param iface - the session_interface object that allows read and
set session cookie
///
virtual void clear(session_interface &iface) = 0;
///
/// Destructor
///
virtual ~session_api() {}
};
///
/// \brief the factory object that generates custom implemented session_api
objects
///
class session_api_factory {
public:
///
/// Return true if this session API requires Garbage collection: i.e
. execution of special function time to time
/// to clear expired sessions from the memory
///
virtual bool requires_gc() = 0;
///
/// The actual garbage collection job (may do nothing).
///
virtual void gc() = 0;
///
/// Return a pointer to the session_api object. Note it may be share
d between multiple requests or may be created each time per request
///
virtual booster::shared_ptr<session_api> get() = 0;
///
/// Destructor and cleanup function
///
virtual ~session_api_factory() {}
}; };
} // cppcms } // cppcms
#endif #endif
 End of changes. 5 change blocks. 
9 lines changed or deleted 109 lines changed or added


 session_cookies.h   session_cookies.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_COOKIES_H #ifndef CPPCMS_SESSION_COOKIES_H
#define CPPCMS_SESSION_COOKIES_H #define CPPCMS_SESSION_COOKIES_H
#include "session_api.h" #include <cppcms/session_api.h>
#include <booster/hold_ptr.h>
#include <booster/noncopyable.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include "session_backend_factory.h"
namespace cppcms { namespace cppcms {
class encryptor;
class worker_thread;
class session_interface; class session_interface;
class session_cookies : public session_api { ///
worker_thread &worker; /// \brief this namespace keeps various session storage backends
std::auto_ptr<encryptor> encr; ///
public: namespace sessions {
static session_backend_factory factory();
session_cookies(worker_thread &w); ///
session_cookies(worker_thread &w,std::auto_ptr<encryptor>); /// \brief This is an interface to generic session cookies encryptio
virtual void save(session_interface *,std::string const &data,time_t n or signing API.
timeout,bool ); ///
virtual bool load(session_interface *,std::string &data,time_t &time /// Note for users implementing their own ecryptor classes:
out); ///
virtual void clear(session_interface *); /// - Be super paranoid and extremely careful in what you are doing.
}; /// - Take in mind that this object are created and destroyed much f
requently then they are actually
/// accessed, so lazy initialization is your best friend.
///
/// Note this class does not have to be thread safe to use from mult
iple threads.
///
class encryptor : public booster::noncopyable {
public:
///
/// Encrypt or sign the plain text \a plain together with \a
timeout and return the encrypted value for a cookie.
/// Don't forget to use base64 encoding in order to create a
string that is valid for cookie
///
virtual std::string encrypt(std::string const &plain,time_t
timeout) = 0;
///
/// Decrypt the \a cipher text or check the signature and re
turn the \a plain text and the session expiration value: \a timeout.
///
/// If signature checks or decryption failed return false.
///
virtual bool decrypt(std::string const &cipher,std::string &
plain,time_t *timeout = 0) = 0;
///
/// Destructor
///
virtual ~encryptor() {}
};
///
/// \brief This is an interface for an object that creates new encry
ptors
///
/// This class must be thread safe.
///
class encryptor_factory {
public:
///
/// Return a pointer to a newly created encryptor.
///
virtual std::auto_ptr<encryptor> get() = 0;
///
/// Destructor - cleanup everything
///
virtual ~encryptor_factory() {}
};
///
/// The implementation of session_api using encrypted or signed cook
ies
///
class CPPCMS_API session_cookies : public session_api {
public:
///
/// Create a new object passing it a pointer ecryptor as par
ameter
///
session_cookies(std::auto_ptr<encryptor> encryptor);
///
/// Destroy it and destroy an encryptor it was created with
///
~session_cookies();
///
/// Save session to cookies, see session_api::save
///
virtual void save(session_interface &,std::string const &dat
a,time_t timeout,bool newone ,bool on_server);
///
/// Load session from cookies, see session_api::load
///
virtual bool load(session_interface &,std::string &data,time
_t &timeout);
///
/// Delete session, see session_api::clear
///
virtual void clear(session_interface &);
private:
struct _data;
booster::hold_ptr<_data> d;
std::auto_ptr<encryptor> encryptor_;
};
} // sessions
} // cppcms } // cppcms
#endif #endif
 End of changes. 6 change blocks. 
19 lines changed or deleted 122 lines changed or added


 session_dual.h   session_dual.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_DUAL_H #ifndef CPPCMS_SESSION_DUAL_H
#define CPPCMS_SESSION_DUAL_H #define CPPCMS_SESSION_DUAL_H
#include "session_api.h" #include <cppcms/session_api.h>
#include "session_backend_factory.h" #include <cppcms/defs.h>
#include <boost/shared_ptr.hpp> #include <booster/hold_ptr.h>
#include <booster/shared_ptr.h>
#include <memory>
namespace cppcms { namespace cppcms {
namespace sessions {
class session_dual : public session_api { class session_storage;
boost::shared_ptr<session_api> client; class session_sid;
boost::shared_ptr<session_api> server; class session_cookies;
size_t limit; class encryptor;
public:
static session_backend_factory factory(session_backend_factory c,ses
sion_backend_factory s,size_t l);
session_dual(boost::shared_ptr<session_api> c,boost::shared_ptr<sess
ion_api> s,size_t l) :
client(c),
server(s),
limit(l)
{
}
virtual void save(session_interface *,std::string const &data,time_t
timeout,bool new_session);
virtual bool load(session_interface *,std::string &data,time_t &time
out);
virtual void clear(session_interface *);
///
/// \brief Client and Server side storage implementation of session_api
///
class CPPCMS_API session_dual : public session_api {
public:
///
/// Create a new object using encryptor \a enc and session_storage \
a storage.
/// \a data_size_limit represents the maximal data size that can be
stored on client side, if the data size is bigger then that
/// the session data will be stored on server
///
session_dual( std::auto_ptr<encryptor> enc,
booster::shared_ptr<session_storage> storage,
size_t data_size_limit);
///
/// Destroy the object: release pointer to \a storage and delete an
encryptor it was created with.
///
virtual ~session_dual();
///
/// See session_api::save
///
virtual void save(session_interface &,std::string const &data,time_t
timeout,bool new_session,bool on_server);
///
/// See session_api::load
///
virtual bool load(session_interface &,std::string &data,time_t &time
out);
///
/// See session_api::clear
///
virtual void clear(session_interface &);
private:
struct _data;
booster::hold_ptr<_data> d;
booster::shared_ptr<session_cookies> client_;
booster::shared_ptr<session_sid> server_;
size_t data_size_limit_;
}; };
} } // sessions
} // cppcms
#endif #endif
 End of changes. 6 change blocks. 
23 lines changed or deleted 74 lines changed or added


 session_interface.h   session_interface.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_INTERFACE_H #ifndef CPPCMS_SESSION_INTERFACE_H
#define CPPCMS_SESSION_INTERFACE_H #define CPPCMS_SESSION_INTERFACE_H
#include <boost/noncopyable.hpp> #include <cppcms/defs.h>
#include <boost/lexical_cast.hpp> #include <booster/noncopyable.h>
#include <boost/shared_ptr.hpp> #include <booster/hold_ptr.h>
#include <booster/shared_ptr.h>
#include <cppcms/cstdint.h>
#include <cppcms/serialization_classes.h>
#include <string> #include <string>
#include <map> #include <map>
#include <memory>
#include <sstream>
#include <typeinfo>
namespace cppcms { namespace cppcms {
namespace http {
class context;
class request;
class response;
}
class session_api; class session_api;
class worker_thread;
class serializable;
class session_interface : private boost::noncopyable { ///
struct entry { /// \brief This class provides an access to an application for session mana
std::string value; gement
bool exposed; ///
entry(std::string v="",bool exp=false) : value(v) , exposed( /// Usually it is accessed via application::session member function.
exp) {} ///
bool operator==(entry const &other) const /// Note, when the application is asynchronous, the sessions should be load
{ ed manually as
return value==other.value && exposed==other.exposed; /// fetching information from session may be not so cheap
} ///
bool operator!=(entry const &other) const /// Generally, session data is represented as a map of key-value strings th
{ at can be read
return !(*this==other); /// and written. All changes in session should be done before headers are w
} ritten to the output
}; /// (before requesting an output stream from http::response object)
typedef std::map<std::string,entry> data_t; ///
data_t data,data_copy; /// Each of the values in session may be also exposed to client as cookie.
worker_thread &worker; For example if
/// you want to disclose "foo" session key to the client side (Java Script)
// Cached defaults and session
int timeout_val_def; /// cookie is cppcms_session=S231abc23c34ca242352a then a cookie with name
int how_def; /// cppcms_session_foo will be created caring the value of this key.
///
// User Values /// Notes:
int timeout_val; /// - Be careful with values you pass, cookies can carry quite a limited ra
int how; nge of strings
/// so it is your responsibility to make sure that these values are actual
// Information from session data ly legal.
time_t timeout_in; /// - Of course the client side can alter these cookies but this would not
bool new_session; have an effect
bool saved; /// on the actual values fetched using session object. But still remember y
ou should not
/// relay on cookies values on server side for obvious security reasons.
///
class CPPCMS_API session_interface : private booster::noncopyable {
public:
int cookie_age(); /// \cond INTERNAL
time_t session_age(); session_interface(http::context &);
~session_interface();
/// \endcond
void check(); ///
bool load(); /// Check if a \a key is set (assigned some value to it) in the sess
void update_exposed(bool force=false); ion
///
bool is_set(std::string const &key);
///
/// Erase specific \a key from the session
///
void erase(std::string const &key);
///
/// Remove all keys from the session and delete the session at all.
(i.e. empty session is automatically deleted)
///
void clear();
std::string temp_cookie; ///
/// Returns true if specific \a key is exposed to client via cookies
///
bool is_exposed(std::string const &key);
///
/// Set exposition of the \a key to client side, if val is true the
value will be exposed, otherwise hidden and cookie
/// will be deleted.
///
void expose(std::string const &key,bool val=true);
///
/// Disable exposition of a \a key. Same as expose(key,false);
///
void hide(std::string const &key);
boost::shared_ptr<session_api> storage; ///
void set_session_cookie(int64_t age,std::string const &data,std::str /// Get the reference to a value for a \a key. Note if \a key is not
ing const &key=std::string()); exist, empty string is created in session object
/// and reference to it returned (similarly to std::map's operator[]
)
///
std::string &operator[](std::string const &key);
///
/// Set value \a v for a session key \a key
///
void set(std::string const &key,std::string const &v);
void save_data(data_t const &data,std::string &s); ///
void load_data(data_t &data,std::string const &s); /// Get a value for a session \a key. If it is not set, throws cppcm
s_error. It is good idea to call is_set before
/// you call this function.
///
std::string get(std::string const &key);
public: ///
session_interface(worker_thread &w); /// Get convert the value that is set for a key \a key to type T usi
bool is_set(std::string const &key); ng std::iostream. For example you can
void del(std::string const &key); /// read a number using int n=session().get<int>("number").
std::string &operator[](std::string const &); ///
/// - it throws cppcms_error if a key \a key not set/
/// - it throws std::bad_cast of the conversion using std::iostream
fails
///
/// Note: the conversion is locale independent (uses C locale)
///
template<typename T> template<typename T>
T get(std::string const &key) { T get(std::string const &key)
return boost::lexical_cast<T>((*this)[key]); {
std::istringstream ss(get(key));
ss.imbue(std::locale::classic());
T value;
ss>>value;
if(ss.fail() || !ss.eof())
throw std::bad_cast();
return value;
} }
///
/// Assign a \a value of type \a T to \a key converting it to string
using std::iostream.
/// For example session().set("num",100);
/// Note: the conversion is locale independent (uses C locale)
///
template<typename T> template<typename T>
void set(std::string const &key,T const &val) { void set(std::string const &key,T const &value)
(*this)[key]=boost::lexical_cast<std::string>(val); {
std::ostringstream ss;
ss.imbue(std::locale::classic());
ss<<value;
set(key,ss.str());
} }
void get(std::string const &key,serializable &); ///
void set(std::string const &key,serializable const &); /// Serialize an \a object and store it under a \a key.
bool is_exposed(std::string const &key); ///
void expose(std::string const &key,bool val=true); /// The serialization is done using cppcms::serialization_traits
void hide(std::string const &key); ///
template<typename Serializable>
void store_data(std::string const &key,Serializable const &object)
{
std::string buffer;
serialization_traits<Serializable>::save(object,buffer);
set(key,buffer);
}
void clear(); ///
/// Fetch an \a object under \a key from the session deserializing i
t.
///
/// The serialization is done using cppcms::serialization_traits
///
/// Throws cppcms_error if the key is not set, may throw archive_err
or if deserialization fails
/// (assuming that serialization uses cppcms::archive.
///
template<typename Serializable>
void fetch_data(std::string const &key,Serializable &object)
{
std::string buffer=get(key);
serialization_traits<Serializable>::load(buffer,object);
}
enum { fixed, renew, browser }; ///
void set_age(int t); /// This enum defines the way session timeout is managed
void set_expiration(int h); ///
void set_age(); enum {
void set_expiration(); fixed, ///< Once the session is created it will expire in a
void save(); ge() second from the moment it created
renew, ///< Once the session expires in age() seconds of in
activity, once user sends an HTTP request again
///< it is renewed
browser ///< The session is kept as long as browser keeps it
(does not get closed). In addition the "renew" expiration
///< policy is valid. So if user does not close his
browser but is not active, it will expire in age() seconds.
};
// Special interface ///
/// Get the maximal age of the session in seconds
///
int age();
///
/// Set the maximal age of the session in seconds
///
void age(int t);
///
/// Reset the maximal age of the session to default (session.timeout
settings value or 24 hours if not set)
///
void default_age();
///
/// Get the expiration policy of the session: renew, fixed or browse
r
///
int expiration();
///
/// Set the expiration policy of the session: renew, fixed or browse
r
///
void expiration(int h);
///
/// Reset the expiration policy to the default (session.expire setti
ngs value or browser if not set)
///
void default_expiration();
///
/// Set store on server side option for session. If srv is true then
the session will be always stored on server
/// side and not in cookies only (required "server" or "both" type s
torage in session.location setting
///
/// Rationale: client side storage using encrypted or signed cookies
is very efficient, however it lacks of one
/// important security feature: there is no other way to control the
ir expiration but using timeout.
/// So user may just revert the cookie to the old state to get back
in time and restore its own session.
///
/// So it is recommended to use server side storage in such critical
cases, like soling captcha or playing a game
/// where you can't return to previous status when storing the data
in the session object.
///
void on_server(bool srv);
///
/// Get on_server session property
///
bool on_server();
///
/// Set the cookie that represents the current session (the value of
the cookie)
///
/// This function should be used only by user implementations of ses
sion storage
///
void set_session_cookie(std::string const &data); void set_session_cookie(std::string const &data);
///
/// Remove the cookie of the current session
///
/// This function should be used only by user implementations of ses
sion storage
///
void clear_session_cookie(); void clear_session_cookie();
///
/// Get the value of the cookie that represents session on the clien
t
///
/// This function should be used only by user implementations of ses
sion storage
///
std::string get_session_cookie(); std::string get_session_cookie();
void set_api(boost::shared_ptr<session_api>);
void on_start(); ///
void on_end(); /// Load the session, should be called one when dealing with session
worker_thread &get_worker(); s on asynchronous API where sessions
/// are not loaded by default. This function returns true if any dat
a was loaded.
///
bool load();
///
/// Save the session data, generally should not be called as it is s
aved automatically. However when
/// writing asynchronous application and using custom slow storage d
evices like SQL it may be useful to control
/// when and how save() is called.
///
void save();
private:
friend class http::response;
friend class http::request;
struct entry;
typedef std::map<std::string,entry> data_type;
data_type data_,data_copy_;
http::context *context_;
// Cached defaults
int timeout_val_def_;
int how_def_;
// User Values
int timeout_val_;
int how_;
// Information from session data
time_t timeout_in_;
uint32_t new_session_ : 1;
uint32_t saved_ : 1;
uint32_t on_server_ : 1;
uint32_t loaded_ : 1;
uint32_t reserved_ : 28;
std::string temp_cookie_;
// storage itself
booster::shared_ptr<session_api> storage_;
struct _data;
booster::hold_ptr<_data> d; // for future use
int cookie_age();
time_t session_age();
void check();
void update_exposed(bool);
void set_session_cookie(int64_t age,std::string const &data,std::str
ing const &key=std::string());
void save_data(std::map<std::string,entry> const &data,std::string &
s);
void load_data(std::map<std::string,entry> &data,std::string const &
s);
}; };
} // cppcms } // cppcms
#endif #endif
 End of changes. 23 change blocks. 
73 lines changed or deleted 337 lines changed or added


 session_sid.h   session_sid.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_SID_H #ifndef CPPCMS_SESSION_SID_H
#define CPPCMS_SESSION_SID_H #define CPPCMS_SESSION_SID_H
#include <sys/time.h> #include <cppcms/session_api.h>
#include <boost/shared_ptr.hpp> #include <cppcms/defs.h>
#include "session_api.h" #include <booster/hold_ptr.h>
#include <booster/shared_ptr.h>
#include <stdint.h> #include <cppcms/session_storage.h>
#include <stdio.h>
namespace cppcms { namespace cppcms {
namespace sessions {
class session_server_storage; namespace impl { class sid_generator; }
class session_interface;
namespace details { ///
class sid_generator : public boost::noncopyable { /// \brief An implementation of session_api that stores the data usi
struct for_hash { ng session_storage and unique session id.
char uid[16]; ///
uint64_t session_counter; class CPPCMS_API session_sid : public session_api {
struct timeval tv; public:
} hashed; ///
public: /// Create a new session_sid with a pointer \a s to session_
sid_generator(); storage
std::string operator()(); ///
}; session_sid(booster::shared_ptr<session_storage> s);
} ///
/// Delete an object and release a session_storage it used.
///
~session_sid();
///
/// See session_api::save
///
virtual void save(session_interface &,std::string const &dat
a,time_t timeout,bool,bool);
///
/// See session_api::load
///
virtual bool load(session_interface &,std::string &data,time
_t &timeout);
///
/// See session_api::clear
///
virtual void clear(session_interface &);
private:
class session_sid : public session_api { bool valid_sid(std::string const &cookie,std::string &id);
details::sid_generator sid; std::string key(std::string sid);
boost::shared_ptr<session_server_storage> storage;
bool cache;
std::string key(std::string sid);
public:
bool valid_sid(std::string const &str);
session_sid(boost::shared_ptr<session_server_storage> s,bool c=false
) :
storage(s),
cache(c)
{
}
virtual void save(session_interface *,std::string const &data,time_t
timeout,bool);
virtual bool load(session_interface *,std::string &data,time_t &time
out);
virtual void clear(session_interface *);
}; struct _data;
} booster::hold_ptr<_data> d;
booster::shared_ptr<session_storage> storage_;
};
} // sessions
} // cppcms
#endif #endif
 End of changes. 7 change blocks. 
40 lines changed or deleted 68 lines changed or added


 session_storage.h   session_storage.h 
#ifndef SESSION_STORAGE_H ///////////////////////////////////////////////////////////////////////////
#define SESSION_STORAGE_H ////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_SESSION_STORAGE_H
#define CPPCMS_SESSION_STORAGE_H
#include <boost/noncopyable.hpp> #include <cppcms/defs.h>
#include <boost/function.hpp> #include <booster/noncopyable.h>
#include <booster/shared_ptr.h>
#include <string> #include <string>
namespace cppcms { namespace cppcms {
namespace sessions {
class session_server_storage : private boost::noncopyable { ///
public: /// \a session_server_storage is an abstract class that allows user
virtual void save(std::string const &sid,time_t timeout,std::string to implements
const &in) = 0; /// custom session storage device like, database storage device
virtual bool load(std::string const &sid,time_t *timeout,std::string ///
&out) = 0; /// Note: if the member functions save/load/remove are thread safe -
virtual void remove(std::string const &sid) = 0; - can be called
virtual ~session_server_storage() /// from different threads, than you may create a single session and
{ return \a shared_ptr
} /// to a single instance, otherwise you have to create multiple inst
}; ances of object
///
class empty_session_server_storage :public session_server_storage class session_storage : public booster::noncopyable
{
public:
void save(std::string const &sid,time_t timeout,std::string const &i
n)
{
}
bool load(std::string const &sid,time_t *timeout,std::string &out)
{
return false;
}
void remove(std::string const &sid)
{ {
} public:
}; ///
/// Save session with end of life time at \a timeout using s
ession id \a sid and content \a in
///
virtual void save(std::string const &sid,time_t timeout,std:
:string const &in) = 0;
///
/// Load session with \a sid, put its end of life time to \a
timeout and return its
/// value to \a out
///
virtual bool load(std::string const &sid,time_t &timeout,std
::string &out) = 0;
///
/// Remove a session with id \a sid from the storage
///
virtual void remove(std::string const &sid) = 0;
///
/// Destroy an object
///
virtual ~session_storage()
{
}
};
///
/// \brief The factory is an interface to a factory that creates ses
sion_storage objects, it should be thread safe.
///
class session_storage_factory {
public:
///
/// Get a pointer to session_storage. Note if the returned p
ointer is same for different calls
/// session_storage implementation should be thread safe.
///
virtual booster::shared_ptr<session_storage> get() = 0;
///
/// Return true if session_storage requires garbage collecti
on - removal of expired session time-to-time
///
virtual bool requires_gc() = 0;
///
/// Actual garbage collection job (if required). If requires
_gc returns true it will be called once-in-a-while to remove
/// all expired objects from the DB.
///
virtual void gc_job() {}
///
/// Delete the object, cleanup
///
virtual ~session_storage_factory() {}
};
} // sessions
} // cppcms } // cppcms
#endif #endif
 End of changes. 7 change blocks. 
29 lines changed or deleted 102 lines changed or added


 util.h   util.h 
///////////////////////////////////////////////////////////////////////////
////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as publishe
d by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public Licens
e
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////
////
#ifndef CPPCMS_UTIL_H #ifndef CPPCMS_UTIL_H
#define CPPCMS_UTIL_H #define CPPCMS_UTIL_H
#include <cppcms/defs.h>
#include <string> #include <string>
namespace cppcms { namespace cppcms {
std::string escape(std::string const &s);
std::string urlencode(std::string const &s); ///
/// \brief This namespace holds various useful helper functions for
we developer
///
namespace util {
///
/// Escape string for inclusion in HTML page, i.e.
///
/// - < - \&lt;
/// - > - \&gt;
/// - \& - \&amp;
/// - &quot; - \&quot;
///
/// Note, this function does not deal with encodings, so it'
s up to you to
/// provide valid text encoding
///
std::string CPPCMS_API escape(std::string const &s);
///
/// Encode string for URL (percent encoding)
///
std::string CPPCMS_API urlencode(std::string const &s);
///
/// Decode string from URL-encoding (percent-encoding)
///
std::string CPPCMS_API urldecode(std::string const &s);
///
/// Decode text in range [begin,end) from URL-encoding (perc
ent-encoding)
///
std::string CPPCMS_API urldecode(char const *begin,char cons
t *end);
///
/// Make MD5 hash of string \a input converting into binary
string of 16 bytes
///
std::string CPPCMS_API md5(std::string const &input);
///
/// Make MD5 hash of string \a input converting it into hexa
decimal string representing this hash
///
std::string CPPCMS_API md5hex(std::string const &input);
}
} }
#endif #endif
 End of changes. 4 change blocks. 
2 lines changed or deleted 71 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/