Copyright © 2002 by The Caudium Group.
Revision History | ||
---|---|---|
Revision 2.2 | 2002-09-20 | Revised by: dg |
Few more fixes, document now contains images and icons. See revision history for more information. | ||
Revision 2.1 | 2002-06-14 | Revised by: dg |
Document is now well-formed XML, one more example. See revision history for more information. | ||
Revision 2.0 | 2002-06-14 | Revised by: Tab |
Converted to DocBook XML 4.1.2. See revision history for more information. | ||
Revision 1.0 | 2002-06-06 | Revised by: dg |
Initial release | ||
Revision 0.91 | ||
Indentation of the SGML document and one more paragraph. See revision history for more. | ||
Revision 0.9 | ||
This Howto is going into stable state. See the revision history for more information. | ||
Revision 0.05 | 2002-04-04 | |
This HOWTO is in the DocBook format. See the revision history for more information. | ||
Revision 0.04 | ||
Added Introduction and license. See the revision history for more information. | ||
Revision 0.03 | ||
Added some useful corrections. See the revision history for more information. | ||
Revision 0.02 | ||
Minor correction in other answers. See the revision history for more information. | ||
Revision 0.01 | 2002-03-11 | |
Initial revision. See the revision history for more information. |
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published as by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license can be found in Appendix A.
This document is a volunteer effort. Feel free to improve and make changes. If you catch any mistakes, please correct them.
Caudium is a Web server based on a fork of the Roxen Challenger 1.3 WebServer. Like Roxen, Caudium is written in Pike with parts written in C for performance reasons. Pike is an interpreted language developed by Frederik Hübinette and Roxen Internet Software (RIS), a Swedish company which also created the Roxen Web Server. Caudium, like Pike, is distributed under the terms of the GPL license; several companies and people are involved in its development.
Caudium features include:
Single-process architecture.
Optional multi-threaded mode.
Backwards compatible with Roxen 1.3 on the API and RXML level.
Runs on many Unix-like systems (GNU/Linux, FreeBSD, OpenBSD, NetBSD, Solaris, AIX, Darwin/MacOS X).
Web based interface for easy administration.
Built in SSL capabilities. Enabling SSL on Caudium is as easy as filing a web form.
Written in Pike. Unlike most web servers, you don't need to learn C or C++ and those pesky details like memory allocation to enhance the server's capabilities.
Extensible with custom modules.
Powerful API.
Lots of standard modules distributed with the server, including an FTP server, the CAMAS web mail application, and the UltraLog log analysis tool. The "module" directory in Caudium 1.2 with CAMAS contains 192 code-only files. Most of the modules are in a single file.
RXML language. RXML stands for Roxen eXtensible Markup Language and is a set of tags, containers and simple programming language constructs that you put in your HTML source. Those tags and containers will be interpreted at run-time by Caudium. This allows non-programmers to do development.
XML language. Using Sablotron, Caudium can render XML pages processed with XSLT, DOM and XPath. You can find more information on Sablotron on http://www.gingerall.com/. It allows you to use pages designed for Apache mod_xslt in Caudium without modifications. Also the output of these generated pages can also be parsed by our RXML parser before sending the result to the client.
Stable multi-threaded programming (Roxen has been multi-threaded since 1994).
Mostly written in an interpreted, object-oriented, language - Pike:
No buffer overflows, segmentation faults or any other problems of that nature.
RealNetworks is still using Roxen 1.3 as their main web platform for its stability and speed.
RIS (Roxen Internet Software) owns Pike, but this is likely to change in the not-so-distant future.
Too little documentation. One example is the lack of documentation about FastCGI support.
Webmasters like to use mod_rewrite in the .htaccess files to protect their sites from leeching, etc. Yes, there is referrerdeny and browserdeny, but these are accessible to the System Administrator, not the casual web user. On Apache, one can easily specify rules on a per directory basis. This isn't easy in Caudium, however, it is rare that someone would have more than two or three different conditions.
Now, for people that are running their own server, many of these issues disappear. Administration and adding servers is much easier. I'm not sure I agree with the templates, but perhaps an Apache Template could be tweaking beyond that to the System Administrator. In most cases, Apache has SSI turned on for shtml files -- getting the exec command enabled to mimic this in Caudium is not a task for the beginner. The maze of options to find that one setting will certainly frustrate anyone getting started.
deb http://grendel.firewall.com/debian/caudium/1.2 unstable main |
deb http://ftp.oav.net/caudium unstable main deb ftp://ftp.oav.net/caudium unstable main |
If you want php4 Debian package for Caudium, you can do:
# su - # apt-get update # apt-get install -f caudium caudium-modules \ caudium-ultralog caudium-pixsl caudium-dev |
# exit $ cd /usr/src; apt-get source -d php4; apt-get build-dep php4 |
$ debuild binary |
![]() | Caudium 1.2 and Pike 7.2 are available as ports tarballs at ftp://ftp.oav.net/pkg_freebsd/ports.tar.gz. If you take the latest ports from this site use the following command:
Another note, since Caudium and Pike have been added recently to FreeBSD port tree, you must have an up to date port tree. See the FreeBSD handbook at http://www.freebsd.org/handbook/cvsup.html about cvsup handling. |
Here is the current Pike / Caudium options supported by the current port :
WITH_OPTIMIZED_CFLAGS : Add some performance flags to the compiler.
WITH_UNIXODBC : Install UnixODBC support (incompatible option with WITH_IODBC).
WITH_IODBC : Install iODBC support (incompatible option with WITH_UNIXODBC).
A little example on how to install Caudium on FreeBSD :
# cd /usr/ports/www/caudium12 # make WITH_MOST=yes WITH_MYSQL=yes WITH_OPTIMIZED_CFLAGS=yes install clean ===> Extracting for caudium-1.2.6 >> Checksum OK for caudium-1.2.6.tar.gz. ===> caudium-1.2.6 depends on executable: pike - found ===> caudium-1.2.6 depends on executable: gmake - found ===> caudium-1.2.6 depends on shared library: sablot.67 - found [...] ===> Generating temporary packing list *************************************************************** If this is the first installation of Caudium, please go the caudium's directory and execute the server/install script to finish the Caudium installation. If your are upgrading, just start caudium as usual. NOTE: there is an automatic starting script in etc/rc.d/ *************************************************************** ===> Registering installation for caudium-1.2.6 ===> SECURITY NOTE: This port has installed the following startup scripts which may cause network services to be started at boot time. /usr/local/etc/rc.d/caudium.sh.sample If there are vulnerabilities in these programs there may be a security risk to the system. FreeBSD makes no guarantee about the security of ports included in the Ports Collection. Please type 'make deinstall' to deinstall the port if this is a concern. For more information, and contact details about the security status of this software, see the following webpage: http://caudium.net/ ===> Cleaning for libiconv-1.7_5 ===> Cleaning for gdbm-1.8.0 ===> Cleaning for mird-1.0.7 ===> Cleaning for mysql-client-3.23.49 ===> Cleaning for autoconf-2.53 ===> Cleaning for autoconf213-2.13.000227_1 ===> Cleaning for automake14-1.4.5 ===> Cleaning for bison-1.35_1 ===> Cleaning for gettext-0.11.1_3 ===> Cleaning for gmake-3.79.1_1 ===> Cleaning for libtool-1.3.4_3 ===> Cleaning for m4-1.4_1 ===> Cleaning for nasm-0.98,1 ===> Cleaning for jpeg-6b_1 ===> Cleaning for tiff-3.5.7 ===> Cleaning for pexts-20020121 ===> Cleaning for pike72cvs-7.2.356_5 ===> Cleaning for libgmp-4.0.1 ===> Cleaning for freetype-1.3.1_2 ===> Cleaning for freetype2-2.0.9 ===> Cleaning for libmcrypt-2.5.0 ===> Cleaning for mhash-0.8.14 ===> Cleaning for expat-1.95.2 ===> Cleaning for Sablot-0.81_1 ===> Cleaning for caudium-1.2.6 # |
Bill Welliver has made some packages. They are available on Riverweb and mirrored to Oav.net.
To get CAMAS from the CVS, go to the CAMAS web site and follow the link.
![]() | To take a CVS source snapshot of Pike 7.2+, you will need to have a preinstalled Pike (any version) on your system in order to compile the fresh CVS checkout. This is because the CVS sources need to pre-process certain parts of the sources with some special Pike scripts. Downloading a tarball from the RIS site (always outdated) will free you from the requirement of having the Pike installed before compiling the CVS snapshot. |
For more information, see the quick start guide at http://caudium.net/.
The first time you install Caudium from the sources, you will need to type the following commands:
# su - # cd /usr/local/caudium # ./install |
--with-threads: Run Caudium with threads (run better on *BSD and Solaris)
![]() | Currently, the keep-alive option doesn't work with CAMAS (I use CAMAS-1.1.7-DEV, Caudium 1.2RC1). Generally speaking, it is also not ready for production use. Here is a comment from Xavier Beaudouin: |
![]() | The location of files may be different on your system if you are using a prepackaged version of the software. |
There are two ways to stop Caudium:
![]() | In both cases Caudium will stop only after a few moments. |
On Debian GNU/Linux, you can use the following commands to manipulate the server status:
# /etc/init.d/caudium stop # /etc/init.d/caudium start # /etc/init.d/caudium restart |
Contains useful information such as debug log, virtual server logs, start/stop status. See also Section 4.2.
readme:
It's all in the name.
server:
This directory contains the actual server.
base_server:
Contains the server core Pike code: API, CIF., etc. Newbies should not modify these files.
bin:
First binary code that is run when you use the start script. There are also some Pike scripts running as CGIs and without Caudium API.
caudium-images:
This directory contains Caudium static images from the Caudium Group, such as the "powered by" series.
config_actions:
These are files used in the Action tab on the CIF.. You may use some of these functions in your code.
etc:
Caudium includes files used by the Caudium core and its modules. For example, it contains .html files for error messages. Two directories are important for a module developer:
include:
Put your .h files here.
module:
Put your module files here (.pmod). Pike module files are used to provide two-level functions/class/methods for your modules. When you modify any of these files, you must restart the server.
fonts:
Contains some compatibility fonts with some older versions. The new directory is nfonts.
languages:
Some basic language translations for time/date.
lib:
Some of the C code used to speed Caudium up. This code is a set of dynamic libraries (.so).
modules:
Contains Caudium modules. These are all the modules you see when you click Add Module after you have selected one of your servers in the CIF.. Browsing this directory will be useful to understand Caudium.
3rdparty:
This special directory contains third party modules for Caudium. These may be useful but are provided without any warranty and will not be maintained by the Caudium Group but they may be by the individuals who wrote them.
more_modules:
Some modules that meet a specific need, are not up-to-date, or are humorous.
nfonts:
Fonts for graphical things like <gtext> and <gbutton>. You can have several types of properties like bold or italic for the same font name.
Perl:
Needed to run Perl scripts within Caudium. At the time of writing this document, Perl support is broken, and we will be pleased to get help on this issue.
protocols:
Contains protocol modules (for handling HTTP, FTP and the like).
server_templates:
The templates you can choose from when you create a new a virtual server.
unfinished_modules:
For modules in development.
You can also see readme/README relative to /usr/local/caudium in our example.
If you use a package system, just use the upgrading features of your packaging system.
The CIF. is where the administrator manages the server. When you first login it looks like this.
In the CIF, you'll find four tabs:
One of these controls is the button that you will have when you are in a module. This button will allow developers to check the new code of their modules without restarting Caudium. You should also know that very few options in some modules will not be activated unless you reload the module. So always reload a module when you think an option has not been read by Caudium.
![]() | A virtual server allows you to have several servers running on the same port. For example you can have www.foo.com and www.foo.org running on the same port and machine. This is why it is called virtual server. |
To create your first server, log into the web based CIF.. Click on the tab, then the button.
Here, you are prompted for the server name:
Type in an easily identifiable name. You also have to select the configuration type. Depending on the configuration you choose, your server will have a different set of modules. In other words, your server will have different capabilities. For your first server, choose Basic server, and click .Now you'll see the Virtual Servers page again. As you can see, you have two different folders to work on: (Figure 4-1) and (Figure 4-2).
Server variables contain the URL of your site, and the port on which it will be available. File system describes the files/directories containing the .html and other files you want Caudium to serve.In server variables, go into
and choose . Use the default values, choose , and click . Now select the URL of your site, and select . You can now go back to the page displaying all of your modules, that is, where you were before you had gone into Server Variables.Under your server name, you'll see the status of your server. If it contains the word "Open" in blue everything is okay, and you can continue with configuring the file system.
If it contains the words "Not open" in red, there is a problem. You can go
into the Event Log via the CIF. tab to investigate. If you have an error
Failed to open socket on 0:80 (already bound ?), you may have another
program or Caudium itself already running on this port. To fix the problem,
identify the program which is using this port, and restart Caudium
[1].
To restart Caudium, go into -> -> -> . Wait a few seconds, and when prompted, select . Now select your
server, and you should have the word "Open" in blue.
![]() | In the CIF. you may wonder what are those two different protocols http and http2? |
---|---|
The difference is that http2 uses Caudium's internal memory cache while http is plain Pike http subsystem. So http2 is faster than http as you might expect. However, there are some issues on some specific sites. |
Example 4-1. Your user filesystem.
/home/customers/customer1 /home/customers/customer2 /home/customers/bigcustomer3 /home/friends/franck /home/friends/bertrand /home/friends/didier |
And suppose your URL is http://www.iteam.org/.
You can now launch your favorite browser to the URL of your site and enjoy.
.www_browsable - the directory will always be browsable .www_not_browsable - the directory will never be browsable |
The Figure 4-3 shows the output you should have.
![]() | If you created these files/directories after you point Caudium to your site, it is safe to go in the Actions tab, then to Cache -> Cache status -> Flush caches. |
Example 4-2. A simple virtual hosting regular expression.
www\.virtualhost\.com www.virtualhost.com |
Example 4-3. A better and quicker regular expression.
^www\.virtualhost\.com$|^virtualhost\.com$ www.virtualhost.com |
# echo "127.0.0.1 www.virtualhost.com" >> /etc/hosts. |
Change the file system root and /tmp in File system -> NONE/ mounted on / -> Paths -> Search path.
If you have an error telling you www.virtualhost.com is unknown check your host file.
For more information about virtual hosting, see the Virtual-Web Mini-HOWTO available at the LDP or in /usr/share/doc/HOWTO or /usr/doc/HOWTO under Debian GNU/Linux.
Find a good user name. This user name should be a normal user with the least privileges. Lots of distributions already have a special account for this. Common names include "www", "www-data", "httpd", "nobody" (Caudium on Debian GNU/Linux runs as www-data:www-data by default). We don't recommend "nobody" though; to quote Theo de Raadt:
Change the owner of the files which Caudium needs to write to. These include:
On a Caudium source install the following command should do the job:
# chown -R www-data.www-data logs/ var/ argument_cache/ bgcache/ configurations/ server/*.pem server |
$ ls -l total 32 drwxr-sr-x 6 www-data www-data 4096 Feb 13 23:17 argument_cache drwxr-sr-x 2 www-data www-data 4096 Feb 19 09:27 bgcache drwxr-sr-x 2 www-data www-data 4096 Mar 4 22:28 configurations drwxr-sr-x 4 root staff 4096 Feb 13 23:16 local drwxr-sr-x 7 www-data www-data 4096 Mar 3 11:50 logs drwxr-sr-x 2 root staff 4096 Feb 13 23:16 readme drwxr-sr-x 19 www-data www-data 4096 Feb 19 20:13 server drwxr-sr-x 2 www-data www-data 4096 Mar 3 19:28 var $ id www-data uid=33(www-data) gid=33(www-data) groups=33(www-data) |
I will now speak about general security measures you can take if you are very strict about security.
Don't allow users to execute scripts that are part of the server.
![]() | Uniscript is a CGI-like wrapper. It will execute programs as if they were CGI scripts but unlike CGI, it does not require you to put these programs under a specific directory like /cgi-bin/. For example each user can have his or her CGI script in his or her directory. Moreover Caudium can execute them with the uid of the owner. |
Don't use anything you don't need. Remove any modules you don't need in your virtual server.
Global Variables -> Version numbers -> Show Caudium Version Number.
Global Variables -> Version numbers -> Show Pike Version Number.
Turn off any debug options specific to a module. These options are for developers, and they don't have security in mind when they debug output.
Actually, this is security through obscurity and doesn't increase the security of the server. | ||
--Grendel |
Output Caudium's log files to a separate partition. /var is a good choice for that purpose.
If your job relies on your web server security, check the Caudium source.
22:39:49 up 2:22, 5 users, load average: 0.01, 0.01, 0.00
And an extract from the top(1) man page:
So the lower your load average is, the better for the other programs on your machine.
To do this, increase the number of sockets you can have on your system. Under some systems it is 1024, which is too low, see Section 5.3 for more information. The next thing to do is to have a good client program written with threads and non-blocking sockets. If you use a multi-fork program on a single client, it will never cope with any web server. It is also good to have several clients stressing the server together.
Last, if you want to compare two web servers, be sure that they are on the same hardware, OS, and network. The same holds for the client(s).
o Increase your system max descriptors numbers : # echo 60000 > /proc/sys/fs/file-max # echo 180000 > /proc/sys/fs/inode-max # ulimit -n 60000 o mount your filesystems with the "noatime" option o make sure your disks holding the logs are "fast enough" o You can tweak a bit your TCP/IP stack : # echo 0 > /proc/sys/net/ipv4/tcp_syncookies # echo 0 > /proc/sys/net/ipv4/tcp_ecn # echo 0 > /proc/sys/net/ipv4/tcp_timestamps # echo 0 > /proc/sys/net/ipv4/tcp_window_scaling |
Finally don't forget to compile Pike with --with-max-fd=60000 (already done in Debian packages).
![]() | Warning from Caudium people |
---|---|
|
Here are the optimizations you can try on your servers. They are provided without any warranty.
![]() | All this is for FreeBSD 4.2 or more recent. |
First, check to see if your filesystems use Soft Updates:
# tunefs -p /dev/da0s1a tunefs: soft updates: (-n) disabled tunefs: maximum contiguous block count: (-a) 15 tunefs: rotational delay between contiguous blocks: (-d) 0 ms tunefs: maximum blocks per file in a cylinder group: (-e) 2048 tunefs: average file size: (-f) 16384 tunefs: average number of files in a directory: (-s) 64 tunefs: minimum percentage of free space: (-m) 8% tunefs: optimization preference: (-o) time |
# tunefs -n enable /dev/"whatever" |
# tunefs -n enable "filesystem" |
In /boot/loader.conf add the following:
kern.ipc.maxsockets="5000" kern.ipc.nmbclusters="65536" |
hw.ata.wc="1" |
vfs.vmiodirenable=1 kern.ipc.maxsockbuf=2097152 kern.ipc.somaxconn=8192 kern.ipc.maxsockets=16424 kern.maxfiles=65536 kern.maxfilesperproc=32768 net.inet.tcp.rfc1323=1 net.inet.tcp.delayed_ack=0 net.inet.tcp.sendspace=65535 net.inet.tcp.recvspace=65535 net.inet.udp.recvspace=65535 net.inet.udp.maxdgram=57344 net.local.stream.recvspace=65535 net.local.stream.sendspace=65535 |
options P1003_1B #Posix P1003_1B real-time extensions options _KPOSIX_PRIORITY_SCHEDULING |
* A comment is started by a star '*' * * 1 maxusers per mega of ram. This machine has 512M then maxusers = 512 set maxusers=512 set hires_tick=1 set rlim_fd_max=10000 set rlim_fd_cur=4096 *set tcp:tcp_conn_hash_size=8192 * Don't setup this if you don't have more than 256M of RAM set bufhwm=48000 * Folling are used to delay page reaping with databases. set fastscan = 32000 set slowscan = 200 set maxpgio = 280 set lotsfree = 1024 set desfree = 512 set minfree = 128 set autoup = 280 * Hash buffer sizes during Specweb testing set tcp:tcp_conn_hash_size = 2097152 * Nic Interface set hme:hme_adv_100fdx_cap=1 set hme:hme_adv_100hdx_cap=0 set hme:hme_adv_10fdx_cap=0 set hme:hme_adv_10hdx_cap=0 set hme:hme_adv_autoneg_cap=0 * To prevent buffer overflow set noexec_user_stack=1 set noexec_user_stack_log=1 |
Another good read is the well known document from Adrian Cockroft about tuning Solaris. Sunhelp.org has also a good section about tuning. Finally, you can read a network guide at http://www.sean.de/Solaris/tune.html.
You can try this code. This is a basic one with only four tags/containers. You should go to http://caudium.info/ and download the Roxen 1.3 documentation.
Example 6-1. Some simple RXML tags.
<html> <comment>You have to put bgcolor for gtext to work properly</comment> <body bgcolor="#FFFFFF"> <h1>Basic RXML examples</h1> <table border="1"> <tr> <td>This is a list of all RXML tags</td> <td><list-tags></td> </tr> </table> <table border="1"> <tr> <td>Gtext render text as graphic</td> <td><gtext scale=0.5>This is a gif/png graphic</gtext></td> </tr> <tr> <td>Last modification of this page</td> <td><modified></td> </tr> </table> </body> </html> |
For a complete tutorial and reference manual on Pike, see http://pike.oav.net/.
The Pike tag allows you to easily insert Pike code into your HTML page à la PHP. This is a good way of learning Pike if you have a PHP background or if you want to do things very easily and don't worry about perfect results.
To do this, you have to load a module in your server. Just select Load module in the CIF. and click the "Pike tag" image. Then hit save and create an .html file where your public web files are. Since everybody tells me that PHP is easy, which is why it's so popular, I took the PHP examples and converted them to Pike. Here is the result:
Example 6-2. The PHP documentation as a Pike tag.
<html> <body bgcolor="#FFFFFF"> <h2>Escaping from HTML</h2> <p> There is one way of escaping from HTML and entering "Pike code mode" <br /> <Pike> output("This is the simplest, and SGML processing instruction"); </Pike> </p> <h2>Instruction separation</h2> <p> Instructions are separated the same as in C or Perl: terminate each statement with a semicolon. The closing tag (container, in fact) also implies the end of the statement, so the following are equivalent: <br /> <Pike> output ("This is a test"); </Pike> <br /> <Pike> output ("This is a test"); </Pike> </p> <h2>Comments</h2> <p> Pike supports C, C++ but not Unix shell-style comments. For example: <Pike> string tests = "This is a test<br />"; // this is a one-line C++ style comment /* This is a multi line comment yet another line of comment */ tests += "Yet another test"; return tests; </Pike> </p> <h2>Melding RXML and Pike</h2> You will never see this in PHP. [2] This will create a .gif image of 1-2-...-255. This took 0.4s on my Duron 750 the first time and 0.1s after. <p> <gtext scale=0.5> <Pike> string output = ""; for(int I = 1; I < 255; I++) output += I + "-"; return output; </Pike> </gtext> </p> </body> </html> |
The problem with using this is that you will soon see it is not powerful:
You have two choices when doing this. You can execute Pike as a CGI script or internally within the server. If you don't know what CGI is, look up the Apache-Overview-HOWTO at http://www.tldp.org/.
Here, we will run Pike scripts internally within Caudium. To achieve this, you have to load another module in your server by selecting Load module in the CIF.. You now have the list of all modules available in Caudium. As you see, there are a lot of modules and reading this page should give you some ideas for future development. To select the Pike script module, just click on the image named "Pike script support" if you use a graphical browser.
You can now create a .pike file containing, for example,
Example 6-3. A basic Pike script.
// you have to inherit caudiumlib to have some basic things // like the id object and response mapping inherit "caudiumlib"; // the same as the main // if you modify this script and you see that Caudium don't take your // modification into account, reload the Pike script support module // This is because Caudium uses a cache for performance reasons string parse(object id) { string html = "<html><body>The id object contain some " "very useful information<br />"; html += sprintf("The id->variables contain a list of " "arguments given to this script %O\n", id->variables); return html; } |
Example 6-4. A real world script.
/* Here is a Pike script (not a Caudium module). This script is less than 20 lines (comments and blank lines excluded) and will randomly return one file to the web browser from a list of files. This script was kindly provided by Xavier Beaudouin */ // first we need to inherit from caudiumlib in order to get // the parse, http_redirect functions and id object // recognized. inherit "caudiumlib"; // we declare an array of files array (string)files; // an ASCII text containing the name of a file // on the real filesystem. // Each file name in this file will be // randomly return (the files name have to be on // a separate line). #define FILELIST "/list" #define BASEDIR "/thepath2yourfiles/" // this function is the constructor, it will be loaded first void create () { // the array of strings 'files' will contain // all the files we serve provided the file // FILELIST list each file name on one line. files = Stdio.read_bytes(FILELIST)/"\n"; } // if no_reload return 1, Caudium will cache the // result of this script for maximum performances // and will not execute it a second time. // As a result, If you give the argument // ?reload=1 to your script, Caudium will // reload it. // This is useful to use cache for average // content delivery unless you are doing // developpement int no_reload(object id) { if(!id->variables->reload) return 1; return 0; } // As this is a simple pike script (CGI like), this function // will be called by Caudium and should return a string that // will be display to the client's browser. // It can also return a mapping containing all the HTTP response // (headers + text) mapping parse(object id) { // We randomly return one of the file we list in the FILELIST file // (relative to BASEDIR directory). // http_redirect will send a HTTP 301 header telling the browser // where to get randomly selected file. return http_redirect(BASEDIR + files[random(sizeof(files))],id); } |
But you can also create some powerful scripts:
Example 6-5. A script for the power user.
inherit "caudiumlib"; string|mapping|object parse( object id ) { id->my_fd->write(id->clientprot + " 200 Ok\r\n"); id->my_fd->write("Server: Caudium !\r\n"); id->my_fd->write("Expires: 0\r\n"); id->my_fd->write("Content-Type: text/html\r\n"); id->my_fd->write("pragma: no-cache\r\n\r\n"); id->my_fd->set_id( ({ id->my_fd }) ); id->my_fd->set_nonblocking(0,send_data); return http_pipe_in_progress(); } void send_data(array (object) id) { id[0]->write("<pre>"); id[0]->write("test......................\n"); id[0]->write("test......................\n"); id[0]->write("test......................\n"); id[0]->write("sleep for 10 sec\n"); sleep(10); id[0]->write("Done</pre>"); id[0]->close(); destruct(id[0]); } |
![]() | The Caudium API is available at http://caudium.net/. You should also read the Roxen 1.3 PDF available at http://caudium.info/. Pike scripts are blocking, and allow your users to run scripts with the same privilege as the server. Blocking means that the server will be stalled if a socket from a pike script is stalled (usually waiting for something). This applies even if you use non-blocking sockets in your script. You don't have this problem with modules. |
With a custom module you can do all sorts of things:
You can create a professional quality administration center very easily.
You can also use per user variables, also known as session variables.
You'll get better performance since the module is part of the server.
There are different types of modules, for example:
Your code is called when Caudium parse a file containing the tags and/or containers you define.
Used to authenticate users with, for example, LDAP, shadow, or SQL.
There are other module types. For a complete reference see the Roxen 1.3 Programmer's Guide at http://caudium.info/.
For an example on how to write a container, see fnord.pike in /Caudium/sources. Because the location module is a must, here is another example:
Example 6-6. A sample module.
// It is intended to show a simple example of a location module. // This module output the result of the who(1) command. It is not meant to // be really useful since it would be better to do a <who /> tag thus // having data in the HTML files and code here // This variable is shown in the configuration interface as the // version of the module. string CVS_version = "$Id"; // Tell Caudium that this module is 'thread safe', that is, there is no // request-specific data in global variables. int thread_safe=1; #include <module.h> inherit "module"; // for the http_string_answer API inherit "caudiumlib"; // Documentation: constant module_type = MODULE_LOCATION; constant module_name = "Who"; constant module_doc = "Send the result of the who(1) command "; constant module_unique = 1; // The constructor of this module. // This function is called each time you/Caudium load the module void create() { defvar("location", "/who", "Mount point", TYPE_LOCATION, "The mount point of this module"); /* each string have to be on a single line, don't do: "The mount point of this module". You can however do "The mount point of " "this module"; */ defvar("path2who", "/usr/bin/who", "Path to the who command", TYPE_FILE); defvar("options2who", "-a", "Options given to who", TYPE_STRING); defvar("codebeforewho", "<html><body><p>", "The code to output before who", TYPE_STRING); defvar("codeafterwho", "</p></body></html>", "The code to output after who", TYPE_STRING); } // This function is called when a user access mount point // path is the path to the URL he used // id contains Caudium global variables such as browser name,... mixed find_file(string path, object id) { // get the contents of the CIF. variables path2who and options2who // and put a single space between it. string command = QUERY(path2who)+" "+QUERY(options2who); // this will write the result of command to the debug log file // very useful for debug write(sprintf("command=%s\n", command)); string result = Process.popen(command); // replacing \n by \n<br /> for better output result = replace(result, "\n","\n<br />"); return http_string_answer(QUERY(codebeforewho)+result+QUERY(codeafterwho)); } |
A backtrace is text that will show you where your program come before the error. This is very useful for developers when they debug. The best is to take an example. Did you try the who module at the end of Section 6.4? If so take it and check it works. Now change the line string command = QUERY(path2who)+" "+QUERY(options2who); to string command = 0;. This will create an error because we put an int into a string. If we want to do that, we have to cast it (for example, use (string) 0). If you have not done it yet, press the More options button in the CIF. and reload the module. Check that the Global Variables -> show_internals option is set to yes, and try your module. You will have an error which should look like this:
Caudium version: Caudium (Caudium/1.2.0) Requested URL: /who Error: Sprintf: Wrong type for argument 2: expected string, got int. ../local/modules/who.pike:76: CaudiumModule(Who,My first virtual server)->find_file("",object) base_server/configuration.pike (version 1.91):1587: Configuration(My first virtual server)->low_get_file(object,0) base_server/configuration.pike (version 1.91):1779: Configuration(My first virtual server)->get_file(object,0) base_server/configuration.pike (version 1.91):1760: Configuration(My first virtual server)->handle_request(object) protocols/http.pike (version 1.71):1549: unknown function() protocols/http.pike (version 1.71):1610: unknown function(0,"GET /who HTTP/1.1\r\nHost: localhost\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.8) Gecko/20020214\r\nAccept: text/xml,application/xml, application/xhtml+xml,text/html;q=0.9,text/plain"+[246]) /usr/local/pike/7.2.262/lib/modules/Stdio.pmod/module.pmod (version 1.114):683: Stdio.File("socket", "127.0.0.1 1260", 777 /* fd=-1 */) ->__stdio_read_callback() |
This seems awful but it is not. The first line is the error in itself:
"Error: Sprintf: Wrong type for argument 2: expected string, got int." The next line "../local/modules/who.pike:76: CaudiumModule(Who,My first virtual server)->find_file("",object)" is the program (../local/modules/who.pike at line 76) |
write("my message to log file\n"); |
int i = 2; write(sprintf("i=%d\n", i)); |
array a = ({ "test", "test2", 2 }); write(sprintf("a=%O\n", a)); |
a = ({ /* 2 elements */ "test", "test2" }) |
![]() | the %O format is very useful since it can output any type from int to mapping. The only type you can't format is object. |
The next paragraph is mainly for users who just want to help us without getting involved too much.
There are two types of documentation needed for Caudium:
You can write press articles about Caudium.
![]() | Note for French writers: |
---|---|
You can contact us for that. |
Documentation available from Internet.
This type of documentation is a must; Caudium can't exist without it. This documentation will help Caudium's newbies, and will also be useful for developers. One good way to start with Caudium is using the Roxen 1.3 documentation. The developers should also see the autodoc. These are in-line documents made in the sources, and available as formatted HTML output at http://caudium.net/.
There is also a lack for a more in-depth documentation for developer. Examples include how to code non-blocking sockets, how to use a backtrace, how to use the do_output_tag, and when should I put thread_safe=1. I remember spending hours trying to understand some of these things on IRC without any documentation available. This sort of documentation should be written by one of the top developers.
This documentation is written using XSLT, but if you don't know it, that's not a problem. Give us whatever format you want, we will translate it. It is the same for the language. If you don't speak English, you can write it in your own language and we will translate. We will also proof-read your work carefully in order to correct any typos or inaccuracies you might leave.
To write this type of documentation, contact the person in charge of the documentation project, ice at caudium dot net.
To get a CVS account, come on IRC or send a mail to kiwi at caudium dot net and explain your plan.
There is a test suite for Caudium written in Expect which uses TCL and DejaGNU. If you want to use it, fetch it from Caudium's CVS repository with the -P testsuite option (the information on this CVS repository is on http://caudium.net/.) Note that this test suite is not maintained, and needs some work.
To send a bug report, copy/paste the error from Caudium's log file (including backtrace, see Section 6.5), your configuration, and the context in which it happened.
Go to http://caudium.net/ and choose bug tracking on the left and follow the instructions.
Version 2.2 : September 20, 2002
Added images and icons. |
Better use of Docbook. |
Updates in the FreeBSD ports section. |
Few more fixes. |
Little language and cosmetic corrections. |
Added the script for image selection in the your first Pike script. |
Corrections in the FreeBSD ports section. |
The file is now well-formed XML. |
LDP Review of documentation. |
Added cross reference to full GFDL in Appendix A. |
Converted to Docbook XML 4.1.2. |
Removed editing notations that are corrected. |
Corrected links to LDP (Linux Documentation Project). |
Made sentence level corrections-spelling, grammar, etc. |
Initial Release |
Submitted to the LDP |
The SGML source is now the authoritative source |
The SGML source is now correctly indented |
Many little SGML changes in the document |
Added the Upgrading Caudium paragraph |
Added a note about the start script config-dir option |
Better HTML conformance to avoid Caudium crash on caudium.info. |
Inserting the notes from Kiwi, Grendel and other into the document. |
Removed all TODO and #define sections. |
Completed the test suite section. |
Added the contributors section. |
Now docbook2ps and docbook2pdf correctly parse the SGML file. |
Added Introduction and license. |
Added a note in "Your first pike script". |
Corrected typo in paragraph number. |
Re-organization of the document. |
How to get UltraLog working. |
How to benchmark a web server. |
How to use a backtrace. |
How to print something to debug log file. |
How to get CAMAS from cvs/source. |
Minor correction in other answers.
How to run Caudium as a non-privileged user. |
How to secure Caudium. |
How to tune Caudium for best performance. |
How to get packages for Debian GNU/Linux. |
How to get packages for FreeBSD. |
How to get packages for Solaris. |
How to use your own fonts. |
How to help Caudium Community. |
Here is the list of people that helped me in one way or another to get this HOWTO written:
Joe Follansbee <joef at compelinteractive dot com> |
Grammar, spelling and syntax cleanup. |
Bill Welliver <Bill.Welliver at fairchildsemi dot com> |
Minor changes. |
Chris Davies <mcd at daviesinc dot com> |
Major contribution to the Caudium's disadvantages, many little fixes and spelling corrections. |
Martin Friese <mf at bauko dot bv dot tu-berlin dot de> |
Update in the platform section. |
Xavier Beaudouin <kiwi at oav dot net> |
All tuning sections, cosmetics changes. |
Marek Habersack <grendel at caudium dot net> |
Minor fixes and latex conversion. |
Thomas Marteau <marteaut at tuxfamily dot org> |
Minor fixes and SGML conversion. |
John Wenger <JohnWenger at EarthLink dot Net> |
Editing, review and comments. |
Thanks for reading. I hope this HOWTO will help you discover Caudium's power. And remember this quotation:
Documentation is like sex: when it is good, it is very, very good; and when it is bad, it is better than nothing. | ||
--Dick Brandon |
If you have any questions about this documentation, contact me at <vida at caudium dot net> or the Caudium general mailing list at <general at oav dot net>
Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".
If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
[1] | To identify you can use lsof(8). If you want to know which programs listen on port 80 just issue the following command as root
Here is the result:
| ||||
[2] | In fact you can... just compile PHP for Caudium :) | ||||
[3] | Pike can't display contents of an object but can display any other types. |