CppCMS configuration file is used to define different |
aspects of the process that may be changes without recompiling |
an application. |
|
- [Server API](#server-api) |
- [CppCMS Server Mod](#server-mod) |
- [Gzip Compression](#gzip) |
- [Cache](#cache) |
- [Sessions](#sessions) |
- [Templates](#templates) |
- [Localization](#locale) |
|
## <span id="server-api"></span>CppCMS Server API -- `server.api` |
|
### Setting API |
|
This parameter is mandatory. CppCMS supports three most popular web server APIs: FastCGI, SCGI and CGI. Values of `server.api` are "fastcgi", "scgi", and "cgi" accordingly. |
|
For example: |
|
server.api = "fastcgi" |
|
### Choosing API |
|
[FastCGI](http://www.fastcgi.com) is the most reliable and recommended API. It has best web servers support and usually has most stable implementations. |
|
_Notes:_ `libcppcms` should be compiled with fastcgi library. |
|
[SCGI](http://python.ca/scgi/protocol.txt) is simple alternative to FastCGI. It is quite common due to very simple specifications that allow easy implementation. |
|
However it has it's own drawbacks: |
|
- Many web servers do not support connection via UNIX domain sockets and auto start. |
- SCGI web server implementation are usually more buggy in comparison to FastCGI. |
|
It should be used if no FastCGI API is available, or libcppcms compiled without fastcgi support. |
|
[CGI](http://www.w3.org/CGI/) -- may be used only in three cases: |
|
- Web server do not support fastcgi and scgi and there is no option to use `cgi-fcgi` "connector" |
- Debugging |
- CppCMS application is heavy CPU bounded, thus the time required for fork+exec is negligible. |
|
### API Parameters |
|
- `server.socket` -- FastCGI or SCGI socket. For Unix Domain socket, specify path |
|
server.socket="/tmp/myapp.fcgi-socket" |
|
For TCP sockets specify "[IP]:port" for example |
|
server.socket="127.0.0.1:6001" |
server.socket=":6001" |
|
Default socket is Standard Input -- 0. It is used when web server starts |
FastCGI/SCGI application. |
|
- `server.buffer` -- How many requests can be "on-hold" -- actually parameters for listen(2) |
it is also used for internal buffer size of "mod-thread" |
|
server.buffer = 100 |
|
Default is 1. |
|
## <span id="server-mod"></span>CppCMS Server Mod -- `server.mod` |
|
Unless `server.api` is CGI, this parameter is mandatory. Three modes are availible: "process", "thread" and "prefork". For example |
|
server.mod = "prefork" |
|
- **`process`** -- CppCMS application runs in single thread, this is the simplest and quite safe mod. If application crashes, only one session is aborted. However, every shared data should pass through IPC -- cache, sessions etc. |
- **`thread`** -- CppCMS runs as single process, all application instances run in thread pool. This can be used for best performance. Drawbacks -- in case of crash, all CppCMS server goes down. |
|
Parameters: `server.threads` --- the size of thread pool. Default is 5 threads. |
|
- **`prefork`** -- CppCMS spawns process pool that execute queries, when "parent" process controls |
this poll. Every application run in its own process as single thread. |
|
If application crashes, missing process is automatically "reforked" by parent providing |
best degree of safety. Also, the iterations limit can be set to force processes die and |
prevent memory and resources leaks in "hard way". |
|
Parameters: |
|
- `server.iterations_limit` -- the number of interations that each process can procced before |
respawning. Default: unlimited. |
- `server.procs` -- the size of workers pool. Default: 5 worker processes. |
|
## <span id="gzip"></span>GZip Compression |
|
Today, most of browsers accept gzip compressed pages sending header "Accept-Encoding: gzip". If |
the browser supports "gzip", the output page is automatically compressed and sent do it, saving |
server bandwith. More then that, when caching is enabled, the cached page is storred in both compressed |
and uncompressed formats. This allows send cached page much faster --- without recompressing |
their content. |
|
Gzip compression is enabled by default. To disable it (not recommended) use: |
|
gzip.enable = 0 |
|
|
|
Compression level has significant impact on the performacne of the system. Thus, if your |
application does not use cache or has high cache miss ratio, reducing compression level to |
minimal would significanly increase performance (up to twice), while the size of output would chagne in |
about 10%. |
|
gzip.level = 1 # Minimal |
|
Compression buffer size can be defined as well using `gzip.buffer`. The size in bytes. |
|
## <span id="cache"></span>Cache |
|
There are several backends for caching in CppCMS. They are defined by parameter `cache.backend`" |
|
1. **`threaded`** -- cache for an application that runs in single process, usually mod-thread. All |
its internal data placed in single process. |
|
Parameters: `cache.limit` -- number of entries that are stored in cache. Default 100. |
|
For example |
|
cache.backed = "threaded" |
cache.limit = 10000 |
|
2. **`fork`** -- cache for an application that runs in mod-prefork. The data is placed in shared |
memory available for forked processes. |
|
Parameters: `cache.memsize` -- the size of shared |
memory region in KB. |
|
_Note:_ Entries bigger than 5% of the size are not |
stored. |
|
For example: |
|
cache.backend = "fork" |
cache.memsize = 65536 # 64 MB |
|
3. **`tcp`** -- distributed cache system. It can be used with all available working modes. It works similarly to |
[memcached](http://www.danga.com/memcached/), but provides |
more powerful feature, like dependencies tracking. |
|
Parameters: |
|
- `cache.ips` -- the list of IPs of cache servers. |
- `cache.ports` -- the list of ports of cache servers. |
|
For example: |
|
cache.backend = "tcp" |
cache.ips = { "192.168.2.101" "192.168.2.102" } |
cache.ports = { 6010 6010 } |
|
_Note_: All entries are equally distributed over all |
servers. It is important to define same order of |
of parameters for each CppCMS server running in the |
network, because each key has unique mapping to specific |
server. |
|
## <span id="sessions"></span>Sessions |
|
### Configure location of session storage |
|
CppCMS supports three major variants of session storage: client, server and both. They are defined by setting parameter `session.location` |
|
1. **`client`** -- store session information entirely at client side using cookies. |
2. **`server`** -- store session information entirely at server side, when client sides holds only session ID in the cookies. |
3. **`both`** -- combination of both methods depending on the size of the data that should be stored. If the data size is behind certain threshold, use server side storage, otherwise use client side. |
|
This threshold is controlled by `session.client_size_limit` configuration parameter. The default value us 2048 bytes. |
|
4. **`none`** -- sessions backend is disabled -- default. |
|
For example: |
|
session.location = "both" |
session.client_size_limit = 512 |
|
_Note:_ This limit represents the size of actual data. The real cookies size is about 4/3 bigger, because of base64 encoding. |
|
### Default session expiration |
|
Session expiration is controlled by `session.expire` parameters. There are three ways the session can expire: |
|
1. **`browser`** -- the session expires when the browser is closed. This is the default expiration method. |
2. **`renew`** -- the session is stored for certain time period. If user visits the site again, its expiration period is extended. |
3. **`fixed`** -- once the session is created it will expire after limited period of time, whether user visits the site and whether not. It is useful to force user re-login each fixed period of time. |
|
The expiration time is defined by parameter `session.timeout` (in seconds). The default is 24 hours --- 24*3600 seconds. |
|
#### Notes: |
|
- Timeout is valid even for "browser" session expiration. If user does not close the browser, it behaves like "renew" period. |
- Session expiration period is accurate up to 10% of time. |
|
_Rationale:_ if the information withing the session is not changed, the data is not updated in order to reduce database updates that only require update of expiration timestamp. Thus, if the data is not updated, the expiration timestamp is updated only if more then 1/10 of the time had passed. |
- Expiration period is stored as a part of session data, even if cookies storage is used. |
|
_Example_: |
|
session.expire = "fixed" |
session.timeout = 1209600 # two weeks in seconds |
|
|
### Cookies options |
|
- `session.cookies_prefix` -- the prefix used for session cookies name. The default one is "cppcms\_session". |
|
Note: Exposed fields would have additional underscore "_" symbol. For example if you defined: |
|
session["username"]="Moshe Rabinovich"; |
session.expose("username"); |
|
Then the cookies are: |
|
cppcms_session=58b536a0d5b6f7dea2df70277482e536 |
cppcms_session_username=Moshe%20Rabinovich |
|
- `session.cookies_domain` -- the domain of the cookies. Default --- none. |
- `session.cookies_path` -- the path of cookies. Default is "/". |
- `session.cookies_secure` -- use secure cookies. Default 0 -- cookies are not secure --- meaning, browser would send them over HTTP, no-encrypted connection. |
|
### Client side storage configuration. |
|
Client side storage has two options for securing information in cookies: |
|
- **`aes`** -- AES encryption using private key and consistency check using md5. This is default option, unless CppCMS was compiled without libgcrypt. |
|
This is the recommended mode -- it provides both consistency and hides the information from user. |
|
- **`hmac`** -- MD5-HMAC digital signature that uses private key. |
|
This method works slightly faster and creates in about 32 bytes shorter cookies, but the user can see the information that was stored in its session. |
|
This method does not require libgcrypt as well. |
|
The encryption method is defined by parameter `session.cookies_encryptor`. |
|
Each of this method uses private key of 128 bits long. It should be defined as 32 hexadecimal digits number in parameter `session.cookies_key`. |
|
CppCMS provides utility `cppcms_make_key` that creates such key for you using `/dev/random` OS interface. |
|
For example: |
|
session.cookies_encryptor = "hmac" |
session.cookies_key = "29b6f071ad58703b8c6a2115d88d3b2e" |
|
### Server side storage configuration |
|
There are four server side backends for session management. The backend defined in parameter `session.backend`: |
|
1. **`files`** -- store session information in files. This is default server side storage. |
2. **`tcp`** -- use distributed session storage that is accessed via TCP/IP |
2. **`sqlite`** -- store session in Sqlite3 database. |
3. **`cache`** -- use cache as session information storage. |
|
Thare is an option to use CppCMS cache system to improve performance of session storage. Additional cache layer can |
be turned on for `file` and `sqlite` backends by setting parameter: |
|
session.server_enable_cache = 1 |
|
You have an option to use it, but in most of cases it |
is not really required. |
|
#### Files backend options |
|
- `session.files_dir` --- defines the directory where sessions are stored. The default is defined by value of: |
|
getenv("TEMP")+"/cppcms_sessions" |
|
In generally it is recommended define directory for each |
cppcms application. You should make sure that it is |
write accessible by it. |
|
- `session.files_gc_frequency` -- the frequency of "garbage collection" in seconds. |
|
The garbage collection required to remove files of expired sessions. By default GC is disabled. |
|
- `session.files_comp` -- serialization compatibility mode. |
|
CppCMS have several options for serialization of access to session files: |
|
- **`thread`** --- for thread safe access, default for mod-thread. |
- **`prefork`** --- for inter process safe access, assuming that all processes are forked from same father, default for mod-prefork. It uses shared memory for serialization. |
- **`nfs`** --- this serialization method uses fcntl and should be safe to use over NFS that **supports** locking. This mode is default for mod-process. |
- **`nfs`** --- this serialization method should be safe to use over NFS with all available worker modes. This mode is default for mod-process. |
|
If you use this mode make sure: |
|
1. Your OS supports locking over NFS using fcntl. |
2. NFS server itself supports locking. |
|
If `session.files_comp` is not defined, the default for existring mod is used. |
|
|
For example: |
|
session.backend = "files" |
session.files_dir = "/var/data/cms/sessions" |
session.files_comp = "thread" |
session.files_gc_frequency = 600 # 10 minutes |
|
#### Sqlite3 Backend Options |
|
- `session.sqlite_db` -- the database file used for storage. |
|
_Note:_ In generally user should define `session.sqlite_db` paremeter only. Most of other parameters are preconfigured with default values suitable for most of applications. They are still accessable for advanced users for fine performance tuning. |
|
- `session.sqlite_db_num` -- the number of database files that are used: 0 for 1 file, 1 for 2 files, 2 for 4 files, 3 for 8 etc. It is possible to use up to 256 DB files. Separation of all information to several databases improves concurrency. Default is 4 -- 16 database files. |
- `session.sqlite_mod` -- compatibility mode -- `thread` or `prefork` according to server mode. If "mod thread" is used the default value is `thread`, otherwise `prefork`. |
|
When sqlite database is accessed form several threads of single process, some performance optimizations can be used. It is possible to gather a set of write operations to single transaction: |
|
- `session.sqlite_commits` --- maximal number of write operations merged to single transaction. Default --- 1000. |
- `session.sqlite_commit_timeout` --- maximal time the transaction may be not complete. Default --- 5 seconds. |
|
- ` session.sqlite_sync` -- turn on/off flushing data to the disk after commit. |
|
This option has strong impact on the performace and survivabiliy of the database in case of hardware fault. When it is turned on, the database would be safe, however every commit may take long time. If it is turned off, the write operations become significantly faster but the data may be damaged in case power fault. |
|
This option is turned on by default for mod-thread because other optimizations can be used to improve the performance, but it is turned off for mod-prefork in order to improve performance. |
|
For example |
|
session.backend="sqlite" |
session.sqlite_db="/var/data/app/sessions.db" |
|
#### Cache backend storage |
|
It is very simple and unreliable backend because the data may be removed from the cache when it becomes full. Also the data is lost when application stops. |
|
It can be used mostly for testing and debugging purposes. When using this backend, cache should be turned on. |
|
#### Distributed over TCP storage |
|
It has only two parameters: |
|
- `session.tcp_ips` -- the list if IPs of session servers. |
- `session.tcp_ports` -- the list of the ports session servers are listening on. |
|
Its configuration is very similar to TCP cache backend. |
|
_Note:_ Make sure that the order of the servers and their number is the same for all CppCMS servers. Otherwise different application would try to look for same session on different TCP servers. |
|
_For example_: |
|
session.backend="tcp" |
session.tcp_ips = { "192.168.10.1" "192.168.10.2" } |
session.tcp_ports = { 3000 3000 } |
|
|
## <span id="templates"></span>Templates |
|
If your application loads templates dynamicly from shared objects, you should define, the list |
of directories where the lookup should be performed. For example: |
|
templates.dirs = { "/usr/local/lib/blog/" "/opt/views" } |
|
CppCMS would look in this directories for files ending with ".so" under various UNIXes or ".dll" |
under Cygwin and try to load the templates. |
|
If on your OS uses different extension, you may specify it with: `templates.ext`. For example: |
|
templates.ext = ".dlib" |
|
## <span id="locale"></span>Localization |
|
CppCMS uses it's own implementation of [gettext](http://www.gnu.org/software/gettext/) that allows |
using different locales withing same process. |
|
It has following parameters |
|
- `locale.dir` -- the path to directory with dictionaries. |
|
For example if your dictionary is stored under |
`/usr/share/locale/he/LC_MESSAGES/wiki.mo` |
then you need specify: |
|
locale.dir = "/usr/share/locale" |
|
- `locale.lang_list` -- the list of supported languages. Locale "en" is the "default" -- inline code without dictionary. |
- `locale.lang_default` -- the default language. If not specified the first language in the list "lang\_list" is the default one. |
- `locale.domain_list` -- the list of supported domains. |
- `locale.domain_default` -- the default domain. If not specified, the first in `domain_list` is used. |
|
For example: |
|
locale.dir = "/usr/share/locale" |
locale.lang_list = { "en" "ru" "he" } |
locale.lang_default = "he" |
locale.domain_list = { "wiki" "wiki_views" } |
locale.domain_default = "wiki" |
|
|