Tntnet is a web application server for C++. The user can use C++ for developing web applications.
Tntnet has a template language called ecpp, which allows the user to add C++
code into html pages. Those pages are preprocessed using the ecpp compiler
ecppc
. The output are C++ classes, which are then compiled and linked into a
binary.
There are 2 modes of operation: standalone or module.
In standalone mode the user writes a main
function, which instantiates a
tntnet instance, configures and runs it. The web server is so embedded into a
own application.
In module mode the templates are linked into a shared library, which is dynamically loaded by the tntnet application.
Both modes can actually also be mixed since the tntnet instance can load those modules also. It is just a matter of how it is configured.
We assume that you have installed tntnet and for the build system a c++ compiler, autoconf, automake and libtool, since we those autotools are used to build the projects. Other build tools can of course be used but for now lets stay on autotools since the project templates use it.
Lets start to create a very simple web application. For a quick start we use a
script provided by tntnet called tntnet-project
. This is a helper which
creates a tntnet project from a template.
So on the command line call:
tntnet-project hello
This creates a project hello in a directory hello and initializes it. Change to the directory and run:
./configure
make
This will configure and build a program called hello. Run it with the command:
./hello
When you navigate with your browser to http://localhost:8000/ you see a simple web page with a short greeting.
So lets look, what we have done. If you look at the directory there are quite many files. Most of them are generated.
Look at the file hello.ecpp first. It is our web page. It contains html code
with some additional tags, which are interpreted by the ecppc
preprocessor.
Those tags are empty for now. They are just placeholders to give you an idea,
what you can do.
The next important file is main.cpp. This defines a main
function as needed
in a C++ application. You can see, that it reads a configuration file
hello.xml and instantiates a application object of type tnt::Tntnet
with
that configuration. Next it adds some mappings to tell tntnet, what to do when a
request arrives.
The configuration file hello.xml contains the settings for tntnet. The most important and only mandatory part is the definition of the listeners. You have to tell tntnet, on which port it should listen for incoming requests.
The build system needs a configure.ac and Makefile.am. The configure.ac is
the source for the configure
script. The Makefile.am tells the build system,
what to build. There you can find a reference to our hello.ecpp and
main.cpp. Also there is a section for static resources. hello.css can be
found there.
A single web page is fine, but not really useful. We want to add another page. So lets create a second ecpp file. Create a file page2.ecpp with some html content.
To include the new page to the application we add it to our Makefile.am. There is a variable called ecppSources. Add it there. Note that you can put it just after the hello.ecpp separated by space or add a backslash at the end of the line to continue on the next. See a autotools tutorial for more details if you want.
When you now build the application with make, and run it, there is a new page, which can be found under the url http://localhost:8000/page2. If you want, you can add a link to that page into the hello.ecpp and on page2 a link back to hello. And note that you can find the hello page also under the url http://localhost:8000/hello.
I think it is time to find out, why it is so. I already mentioned the mappings. They tell tntnet, which page to call when a request arrives. Of course the url is the key here.
Our pages are compiled with the ecppc compiler. It gives all pages a name. By default it is just the basename of the file, so that our hello.ecpp is named hello. It is the component id of the page. And similar page2.ecpp is named page2.
Now we look at the main.cpp. There we find calls to the method mapUrl
of the
tnt::Tntnet
object. It takes 2 parameters. A regular expression, which is
executed against a incoming url of a request and a component name, which to call
if the expression matches.
There are currently 3 mappings. We skip the first for now. The second has a regular expression ^/$. That matches exactly one slash. The url of a http request start always with a slash. This is mapped to the component with the name hello, which is our page generated from hello.ecpp.
The third mapping is a little more sophisticated. The expression is ^/(.*), which actually matches everything. But the part after the first slash is collected since it is in brackets. The component id, is $1, which is a back reference to the first bracketed expression. So the url /hello matches the expression and $1 is set to hello so that again our hello.ecpp is called. And /page1 calls page1.ecpp.
Now we come back to the first mapping. It maps static resources.
If you look at Makefile.am you can find a rule to generate a component called resources. The flag -bb tells ecppc to build a so called multi binary component. It creates on component from many static source files. In those source files no tags are interpreted. This is useful for all static files like css or images. It would be fatal if ecppc would interpret a graphics image and by chance find something, which looks like a ecpp tag and tries to do something with it.
Since now all static files have a single name resources we somehow have to
tell tntnet, which file to fetch from those. If you look again at main.cpp and
the first mapping you can see a call to the method setPathInfo
. The method
mapUrl
returns a mapping object, which can be modified.
The expression /(.*) is the same as in the third mapping and hence matches
everything. This time the component to call is always resources but the
mapping gets a additional information using this setPathInfo
. In our case the
path is then resources/$1. So that the url /hello.css sets the path info to
resources/hello.css. And indeed you can find such a file in our project and
also in our Makefile.am under staticSources.
Note that ecppc automatically sets a proper content type depending on the extension of the file to make the browser happy.