GNU MyServer is a powerful web server designed, to be easily executed on a personal computer by the average computer user. It is based on multi-threaded architecture, which makes it extremely scalable and usable in large scale sites, as well as in small networks. It has built-in supports for the HTTP, HTTPS and FTP protocols. Support for dynamic pages is made available trough CGI, ISAPI, WinCGI, SCGI and FastCGI protocols.
The MyServer configuration is done using three different XML files:
These files can exist in different locations, they are looked in the following order:
It is possible to specify a different directory where looks for
configuration files by the
--cfgdir argument to the myserver
process. In case a path is specified, then the configuration files
are looked exclusively in this directory.
Plugins are allowed to install new handlers to read the configuration
from other sources. It is done changing the value of the variables
respectively to use a different handler for the virtual hosts and for
the MIME types. If no value is specified then the value
CGI scripts can get the server administrator e-mail and show them to
the user (through the SERVER_ADMIN environment variable).
It is defined trought the
server.admin variable, that can be
set in the global configuration file or for virtual host.
There can be need for the server to save temporary files as a form of
It is possible to configure the directory where temporary files are
stored trought the
server.temp_directory variable inside the
main configuration file.
Operations on disk are much slower than read or write directly from
the primary memory. To solve this problem under GNU/Linux you can
think about use virtual memory instead of a persistent storage device
to store files.
It can be done, by the root user, as:
# mount -t tmpfs -o size=256m tmpfs /tmp/tmpfs
The previous command mount a portion of memory, 256M, on the
/tmp/tmpfs and it can be used as a normal file system.
At this point,
server.temp_directory shall be set to
/tmp/tmpfs to benefit from it.
Files saved on the primary memory are not persistent between reboots,
introducing another level of security as temporary data will not be
saved on the server.
Protocols like FTP or HTTP/1.1 support keep-alive connections, in
other words the connection is kept alive between requests to avoid a
different connection to the server on every request.
MyServer performances are not affected by the number of active
connections but if they are not controlled, they can reach the maximum
number of allowed connections without give the possibility to new
connections that really want to request a resource to be
Active connections are closed after a fixed amount of time has passed
without any activity.
The amount of time, before an inactive connection is closed, is
configured trought the
server.connection_timeout value defined
in the global configuration file. This value is specified in
Virtual hosts is a method to link more than a domain name to the same machine, even if they refer to the same network interface. Virtual hosts are supported by the HTTP and HTTPS protocols.
For example http://mypc.net is different from http://sub.mypc.net. Virtual hosts are defined in the file virtualhosts.xml. A sample virtual hosts configuration file looks like:
<VHOSTS> <VHOST> <NAME>Every connection</NAME> <PORT>80</PORT> <IP>192.168.0.0/24</IP> <PROTOCOL>HTTP</PROTOCOL> <DOCROOT>web</DOCROOT> <SYSROOT>system</SYSROOT> <HOST>foo.bar.com</HOST> <ACCESSLOG>logs/myServer.log</ACCESSLOG> <WARNINGLOG>logs/myServer.err</WARNINGLOG> <ALLOW_CGI>NO</ALLOW_CGI> </VHOST> </VHOSTS>
Log files can have extra options:
With this option, the logs will have two extra fields: HTTP Referrer and HTTP User Agent. Using cycle="yes" you will enable log cycler on the log file. When a log file with cycling enabled reaches the max size for log files it will write its content to a new file and recreate the original file. By default cycled log files uses the gzip compression to save space, if you don't want to use gzip specify cycle_gzip="no". Here is an example of a FTP virtual host:
<VHOSTS> <VHOST> <NAME>Ftp connection</NAME> <PORT>21</PORT> <IP>127.0.0.1/32</IP> <PROTOCOL>FTP</PROTOCOL> <DOCROOT>web</DOCROOT> <SYSROOT>system</SYSROOT> <HOST>ftp.foo.bar.com</HOST> <ACCESSLOG>logs/myServer.log</ACCESSLOG> <WARNINGLOG>logs/myServer.err</WARNINGLOG> </VHOST> </VHOSTS>
Tags semantics are identical with first example. Although FTP is used for public file sharing, restrictions may be imposed using security file.
It is possible to specify a throttling rate for the connection by the
connection.throttling value. It can be specified in any
configuration file, at a global level, in the virtual host definition
and in the local security file.
Its value is specified in bytes/second.
The following line, for example, set the maximum transfer rate to 1 KByte/second:
<DEFINE name="connection.throttling" value="1024"/>
To improve performances, the server can use a cache of connections,
this value can be configured trough the server global variable
server.connections_pool.size. If it is not specified, a
default value of 100 is used. Increase this value if more connections
can be active at the same time. Another effect of using a connections
cache is a less defragmented memory.
It may be necessary to register an entire location with a single
handler and it is done trought
Any other element passed after the location will be part of the
<LOCATION path="foo/bar" mime="text/html" handler="CGI" param="/usr/local/bin/handler" />
In the previous example, the CGI process /usr/local/bin/handler
is used to manage any request to the location foo/bar, this
location includes for example: foo/bar, foo/bar/baz,
foo/bar/a/file, everything that follows foo/bar will be
MyServer gives you the option to enable or disable HTTP methods
command for each virtual host. It can be done trought the
For example, the HTTP TRACE command can be disabled using:
<DEFINE name="http.trace.allow" value="NO" />
MIME types are used to specify the type of information a resource transmitted to or from the server contains. Some standard MIME types are already defined in the MIMEtypes.xml file. Using the same syntax you can define new MIME types or modify existing ones. For each MIME type it is possible to specify how the server will handle the files and which actions take before it can be sent to the client.
In this example two MIME types are defined:
<MIME mime="text/html" handler="SEND" param=""> <EXTENSION value="html"/> <FILTER value="gzip"/> </MIME> <MIME mime="text/html" handler="CGI" param="/usr/bin/perl" selfExecuted="NO"> <EXTENSION value="pl"/> <DEFINE name="http.error.file.404" value="404.html"/> </MIME>
The former defines to send any file with a
.html extension as
it is, in case it is supported by the client then the file content is
compressed using the gzip.
The latter specifies that every file with a
pl extension are
handled by the /usr/bin/perl CGI and the new process standard
output is redirected to the client. In addition, it defines which
resource use when a 404 HTTP file not found error happens.
Every MIME type is made of:
extensionitems can be specified for the same MIME type.
<FILTER> defines a filter for the MIME type. The data will
pass through the filter before being sent to the user.
In the example above, the data would be sent gzipped to the user.
It is possible to specify multiple filters for the same MIME type,
they will be applied in the specified order.
<DEFINE> It defines a new value for a variable, take a look
here Security files for more details on the
The same MIME type can have several extensions, you will need to
specify a different
<EXTENSION> element for each extension.
These are valid HTTP handlers:
param. This is not a real proxy, there is not caching and message is forwarded as it is without any change.
It is possible to match the file name against a regular expression instead of specifying only its extension.
It is done using the
PATH directive in the following way:
<?xml version ="1.0"?> <MIME mime="text/html" handler="SEND" param=""> <PATH regex="/foo/bar/.*" /> </MIME>
PATH regular expressions are checked before the file
extension, in the order they are specified in the configuration file.
MyServer offers the feature to follow symlinks where they are supported. You can configure MyServer to follow symbolic links specifying this line in the myserver.xml file.
<DEFINE name="symlinks.follow" value="YES" />
By default MyServer doesn't follow symbolic links.
It is possible to use different handlers to determine the file MIME type. Additional handlers can be supported by external plugins.
The definition of external handlers can be done per vhost or globally
in the main configuration file changing the value of the variable
<DEFINE name="mime.handler" value="mime_magic" />
Under POSIX it is possible to change the MyServer process user identifier and group identifier after it has bound the necessary ports (only the root user can bind ports < 1024).
To specify a different process user id (PID), you must specify it in the myserver.xml file as:
<DEFINE name="server.uid" value="UID" />
Differently, to change the process group id (GID), the configuration line to use is:
<DEFINE name="server.gid" value="GID" />
When one of these features is used, MyServer will not use the auto-reboot because it will not be possible to get back old permissions.
It is possible to run CGI processes using a different uid/gid. It can be done defining the “cgi.uid” and “cgi.gid” values in a configuration file. It can be specified at any configuration level.
These directives can be used in a security file to force the execution of the new process with both uid and gid to 1000.
<DEFINE name="cgi.uid" value="1000" /> <DEFINE name="cgi.gid" value="1000" />
It is also possible to specify a new root directory location using the cgi.chroot attribute:
<DEFINE name="cgi.chroot" value="/some/where" />
In a POSIX environment the
fork syscall is used to execute new
processes. It clones the caller process keeping any open file or
connection in the child process too. To avoid this problem a fork
server is present in MyServer.
The communication between the MyServer process and the
fork server is done trought a socket. When MyServer wants to execute
a new process two connections are opened to the fork server, for
the stdin and stdout streams, and the fork server will fork itself and
execute the process using these connections as its I/O streams.
It is not configurable in any configuration file as the MyServer process is forked to create it before any file or connection is active.
It is enabled passing the
-f switch to the myserver process.
If the MyServer main process is configured to change its uid/gid after its initialization, it is the only way to spawn new processes with uid/gid different than the MyServer process.
By default, FastCGI and SCGI servers are lazily initialized by
MyServer on the first request to a resource that is handled trought
these protocols. In this case MyServer will initialize it using a random TCP port.
There may be cases where a different configuration is needed and it is
done using the
PROCESS_SERVER directive inside the
PROCESS_SERVER entry makes it possible to access a specific
FastCGI/SCGI configuration inside MIME types by its name.
<!-- Inside myserver.xml. --> <DEFINE name="server.process_servers"> <DEFINE server="/opt/bin/fastcgi_server" domain="fastcgi" host="localhost" port="2010" local="yes" uid="1000" chroot="/chroot" gid="1000"/> </DEFINE>
In the previous example the FastCGI server
/opt/bin/fastcgi_server is created. The
domain must be
"fastcgi" or "scgi", depending on the specific protocol to use.
local specifies if the server is handled by myserver or it is
already running; in the former case, myserver will simply access and
If the server is not local then the
server is a simple label
that can be used by a MIME type trought
param to access it.
It is possible to specify a different uid/gid for the local server
process and don't maintain the original myserver process privileges.
It can be done using the
Also, it is possible to use a different root directory, mapping the
/ path to what is specied in the
Any file lookup can't go upper what is specied in the chroot. Pay
attention that any path specified in
server must be relative to
the new chroot.
The following code, declare an already running FastCGI server and
registers it on the
<DEFINE name="process_servers.list"> <DEFINE server="a_remote_server" domain="fastcgi" host="foo" port="2010" local="no"/> </DEFINE> <!-- Inside MIMEtypes.xml. --> <MIME mime="text/html" handler="RUNFASTCGI" param="a_remote_server"> <EXTENSION value="fcgi"/> </MIME>
The X-Sendfile directive can be used by FastCGI servers to instruct the web server to ignore any content but send the file specified in the X-Sendfile header. It is much faster to transfer static contents and avoid an additional step from the FastCGI server to the web server.
Since the FastCGI X-Sendfile can ask any file to be accessed
statically, this feature is not considered safe you must force it
manually, in can be done on a virtual hosts basis.
It is done trough the
fastcgi.sendfile.allow variable, to
enable X-Sendfile set its value to
It is possible to change almost any configuration for a single directory or a single resource trough the .security.xml. This file can be placed in any web directory and it will overwrite default configuration values. If the .security.xml file is not found in the directory where the requested resource is, then MyServer will look in the parents directory until the file is found. If .security.xml is not present in the virtual host root directory then the default one which is present in the system directory will be used.
Usually consider the first valid value found in this order:
Some values are not configurable in any .security.xml file and they are took directly from the Virtual host configuration and in some cases directly from the global configuration file.
In MyServer there are two different steps involved in the logging phase: user authentication and validation.
In the first step a permission mask is found given the username:password pair, no other information are used in this phase. In the second phase this value is refined using more information. The two phases are completely separated and it is possible to use different sources for any of them.
The .security.xml can be used for both phases and by default it is.
The anonymous user is matched inside MyServer with the “Guest” username and an empty password.
The name for the security file can be changed trought the
The maximum allowed size for a security file can be limited by the
security.max_size variable, by default there is no limit.
security.max_size can be
defined in the global configuration file or differently for every
The information used for the first phase of logging is a simple list of USER elements. Any permission is configured by an attribute, if the attribute value is equal to “YES” then the permission is granted.
The permissions that MyServer considers are:
In the following example we enable an anonymous user to access resources in READ/EXECUTE/BROWSE mode, DELETE and WRITE are both denied.
<SECURITY> <USER name="Guest" password="" READ="YES" EXECUTE="YES" BROWSE="YES" DELETE="NO" WRITE="NO"/> </SECURITY>
As no other information beside username:password is used, this first phase is the same for any protocol supported by MyServer.
To improve security it is possible to use in place of the clear-text
password a crypted version of it. It is done using the
algorithm variable. It specifies the function F to apply to
the client specified password before compare it with the
<SECURITY> <USER name="admin" password="8ee0f7b66d1ab05714573fc556fbd7ff" algorithm="md5" READ="YES" EXECUTE="YES" BROWSE="YES" DELETE="NO" WRITE="NO"/> </SECURITY>
If the HTTP digest authorization scheme is used, it is not possible to use any password hash but the original clear-text password. The only exception to this rule is to specify the A1 part in the Digest scheme.
It is computed by the function: MD5 (username:realm:password).
<DEFINE name="http.auth" value="digest" /> <USER name="user" algorithm="a1" password="c2deada0bcb64f99e65be0d33bb92d54" READ="YES" EXECUTE="YES" BROWSE="YES" WRITE="NO"/>
The realm value used by MyServer is the virtual host name, including
the port number, i.e.
The A1 password can be computed using the following shell command, be
sure to use the right user, realm and password values.
printf "%s:%s:%s" user realm password | md5sum
To allow the .security.xml re-use, the FTP “Anonymous” user is mapped internally by MyServer to the “Guest” user.
The second phase allows to define some rules that can overload the settings specified in the authorization phase.
The default validator used by MyServer is the .security.xml file.
The XML validation phase reads the tag contained in the order that they are specified. It works almost in the same way a programming language does, but differently the XML validator doesn't allow a loop structure, this is required to terminate the parsing in a finite time.
The XML validation is done using four commands:
CONDITION block allows to evaluate a condition and in case
it is satisfied then the inner XML is evaluated too, in case it is not
satisfied then the inner code is not considered. It works like the
if statement usually present in any programming language but
offering less syntactical freedom.
Here it is showed a simple use of
<CONDITION name="auth.user" value="Guest"> ... </CONDITION>
The inner XML code, omitted for clarity, is evaluated only when the
auth.user variable is equals to the value "Guest".
It may be necessary to specify the other case, evaluate the inner
block every time the condition is not satisfied. It is done using the
<CONDITION name="auth.user" value="Guest" not="yes"> ... </CONDITION>
In this case, the inner block is evaluated every time the
auth.user is different than "Guest".
It is possible to match a value against a regular expression, in this case you will need to declare it explicitly.
<CONDITION name="auth.user" value="admin.*" regex="yes" not="yes"> ... </CONDITION>
DEFINE block is used to specify a value for a variable that
later can be accessed by the server.
This is the way to specify variables that it is possible to specify in
the security file (not all variables are allowed to be defined here),
overloading the value specified in the virtual host or in the server
The syntax for the
DEFINE command is:
<DEFINE name="http.error.file.404" value="404.html"/>
In the previous example the HTTP 404 error page was replaced with a customized HTML page.
As the same configuration file can be used by different contexts, as
a web host or a FTP site, any variable has meaning only in its
original environment, define
http.error.file.404 in a FTP site
will not have any effect.
PERMISSION element has the same syntax used in the first
authorization phase, the only difference is that username and password
are not specified.
<PERMISSION READ="NO" EXECUTE="NO" BROWSE="NO" DELETE="NO" WRITE="NO">
The previous example denies any access to the resource, replacing any value found previously.
RETURN element allows to exit immediately from the XML flow
without consider any other command specified in the file.
It has an additional attribute
value that must be set to the
ALLOW to keep the previous found attribute mask.
To immediately return from the XML file and at the same time deny any access, without care of the previous found permission mask, you must do:
<RETURN value="DENY" />
Differently, to return from the flow keeping the found permission mask there is need to do like:
<RETURN value="ALLOW" />
Pay attention, if at the same time you want to change the permissions
then you will need to specify them explicitly by the
It is possible to specify a page when a HTTP error happens using the option:
<DEFINE name="http.use_error_file" value="YES" />
So, if you set the value to
NO, like in the line below,
<DEFINE name="http.use_error_file" value="NO" />
If an error page is not used MyServer will (by default) just send a header to your browser with the error code. It is possible to include a HTTP body in the error page, using:
<DEFINE name="http.error_body" value="YES" />
When a resource mapped to a local directory is requested, MyServer shows its content like an usual file manager does.
In the myserver.xml main configuration or in the virtualhosts.xml file, it is possible to set a list of default file names to use instead of the directory content.
Default file names are defined using a list called
http.default_file and they are checked in the specified order
until one is found. If the file can't be found in the directory then
the directory content is listed.
<DEFINE name="http.default_file"> <DEFINE value="default.html"/> <DEFINE value="default.htm"/> <DEFINE value="index.html"/> <DEFINE value="index.htm"/> </DEFINE>
The previous lines define the order of files that are checked by the web server when a directory is requested. For example, given the previous configuration and a request to the http://foo/bar/ resource, where bar/ is mapped to a local directory, the server will look for these files in order:
http://foo/bar/default.htm http://foo/bar/index.htm http://foo/bar/default.html http://foo/bar/index.html
If that resources don't exist then the content of bar/ is listed.
When the directory content is listed, by default MyServer shows the
file name, last modified time and file size. This default bahaviour
can be changed redefining the
It can be redefined in the local security file, in the virtual host or in the global server configuration. Its value is a formatting string, columns are showed in the same order that they are specified.
For example, the
%f%s value displays the file name followed
by its size, while
%f%t displays the file name and its last
You can change the layout of the directory browsing page. The line below, in myserver.xml, points to the CSS file used to configure the layout for the browsing directory pages:
<DEFINE name="http.dir.css" value="/sys/css/browsestyle.css" />
It is possible to ignore some files to be listed from the final
output. It is done using the
expression that can be specified at any level.
Pay attention, this directive does not change the file visibility, so a direct request to the entries that are part of the mask will have the same effect as if this directive is not specified.
In the following example, the file hidden is not included in the directory listing.
<DEFINE name="http.dir.ignore" value="hidden" />
The data encryption is used to protect the data that is sent between the client and the server. There are two types of algorithm: symmetric and asymmetric data encryption algorithms. The difference between the two types of algorithm is that for the symmetric algorithms the same key is used both for encryption and decryption. These algorithms are not used by servers with a potentially large number of clients because the data captured can be decrypted by any client that know the key and because the key needs to be distribute in a safe manner not distributing it on a large network like Internet. The asymmetric algorithms work in a different way, the data encrypted with a key can be decrypted only with the other key and vice-versa. Anyone know the public key but only the owner knows the private one. In this way the key owner do not have to distribute the key only to know clients but he can distributes it to a large scale network.
A certificate is needed to certify your identity through a CA (Certification Authority). You can use a certificate without register it to third party CA, it is called self-signed certificate. You can find all the necessary tools to create certificates in the GNU TLS command line tools. Look here for more information: http://www.gnu.org/software/gnutls/.
To generate a private key/self signed certificate couple you will need to execute these two commands:
certtool --generate-privkey --outfile cert.key certtool --generate-self-signed --load-privkey cert.key \ --outfile cert.pem
To configure certificates in MyServer you have to put the two files:
cert.pem in the MyServer certificates
To configure a HTTPS host that will use the created certificate, add the following lines in the virtualhosts.xml file:
<VHOST> <NAME>Every connection</NAME> <PORT>443</PORT> <SSL_PRIVATEKEY>certificates/cert.key</SSL_PRIVATEKEY> <SSL_CERTIFICATE>certificates/cert.pem</SSL_CERTIFICATE> <PROTOCOL>HTTPS</PROTOCOL> <DOCROOT>web</DOCROOT> <SYSROOT>system</SYSROOT> <ACCESSLOG>logs/myServer.log</ACCESSLOG> <WARNINGLOG>logs/myServer.err</WARNINGLOG> </VHOST>
Take a look at the see Virtual hosts documentation to get more information about other tags.
The MyServer's log management system was designed to support logging over different targets. At the moment, these targets are made out of files, sockets and, of course, consoles. Each target, must be referred through its location string. In addition, it is possible to provide a list of filters (e.g. the Gzip filter) to improve the logging capabilities.
This section will introduce you to the use of the log management features.
A location string can be provided as an URI; the basic schema is in
protocol can be chosen
resourcecan be either a valid filename or an hostname according to its
consoleprotocol, can take as its
Note the extra '/' needed to refer an absolute path.
You can set the MyServer's main log location through the switch
--loglocation argument is a valid location string.
Each virtual host needs two main log targets, one for the access
messages and the other one for the error messages, whose entries in the
configuration file, are respectively
WARNINGLOG. Each of these targets, can in turn write its
messages over different streams. To tell MyServer about all that, you
can edit the virtualhosts.xml file, and apply the information
found in this section, to each
VHOST entry of that file. As we
can see in the following example, the
ACCESSLOG root entry for
the accesses log configuration, contains some
STREAM nodes, and
STREAM contains two attributes, the mandatory
location and the optional
STREAM node, can
also contain optional
FILTER sub-nodes, one for each filter that
we want to add to the
<ACCESSLOG type="combined"> <STREAM location="file://logs/MyServerHTTP.log" cycle="1048576"> <FILTER>gzip</FILTER> </STREAM> <STREAM location="console://stderr"/> </ACCESSLOG>
Above we have two streams attached to the
ACCESSLOG entry. The
first one, is a file. This file will grow up to 1048576 bytes, over that
limit it will be cycled. Also, this target will take advantage of the
gzip compression, since it will write to the file through the gzip
filter. The second one is the standard error stream over the console.
The next example, shows instead the
WARNINGLOG entry. In that
example, we still have two streams where warning messages will be
sent. The first one is a socket, while the second one is a file that
will grow with no limit over its size. No filters will be applied to
that stream. Note that if we don't specify the
it is assumed to be zero by default, which means to never cycle the
<WARNINGLOG> <STREAM location="socket://192.168.1.13:8080"/> <STREAM location="file://MyServerHTTP.err"/> </WARNINGLOG>
If a wrong filter is specified, its relative
STREAM will not
It is possible to set color attributes for the text written over the console. In this way, messages can look different according to the logging level which they belong to. For example, you may wish to write error messages with a red text over a black background, info messages with a white text over a black background and warning messages with a yellow text over a black background. You can easily tell MyServer about that information by editing the myserver.xml configuration file and adding the following code:
<DEFINE name="log_color.info_fg" value="white"> <DEFINE name="log_color.info_bg" value="black"> <DEFINE name="log_color.warning_fg" value="yellow"> <DEFINE name="log_color.warning_bg" value="black"> <DEFINE name="log_color.error_fg" value="red"> <DEFINE name="log_color.error_bg" value="black">
Allowed values for colors are
white. The two common suffixes
respectively the foreground attribute and the background one, while the
kinds of logging messages managed by MyServer.
If the console colours information is missing or it is partially
provided, MyServer will use default values.