Skip to content

maekitalo/tnttutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

Introduction to Tntnet

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.

First web application

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.

Adding more content

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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published