Sei sulla pagina 1di 19

Tntnet users guide

Authors: Tommi Mkitalo, Andreas Welchlin

Tntnet users guide

Table of contents
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Concept....................................................................................................................................... 3 Installing Tntnet.......................................................................................................................... 3 Create a simple application with Tntnet......................................................................................3 C++-content (processing, expressions, conditional expressions)............................................... 4 Query-arguments (scalar/vector, untyped/typed, default-value).................................................4 Components................................................................................................................................ 5 Component-parameters............................................................................................................... 5 Returning from components........................................................................................................6 Calling components (dynamic/static)..........................................................................................6 Calling components from c++.....................................................................................................7 Include ecpp-files........................................................................................................................ 7 Declaring subcomponents........................................................................................................... 8 Passing parameters to components..............................................................................................8 Defining scoped variables........................................................................................................... 9 14.1 Lifetime.................................................................................................................................. 9 14.2 Scope.................................................................................................................................... 10 15 Cookies......................................................................................................................................11 16 Component attributes................................................................................................................ 12 17 Configuration............................................................................................................................ 12 18 Accessing configuration variables............................................................................................ 13 19 Logging..................................................................................................................................... 14 20 Exception handling................................................................................................................... 14 21 Savepoints................................................................................................................................. 14 22 Binary content........................................................................................................................... 15 23 Upload....................................................................................................................................... 15 24 HTTP-Auth............................................................................................................................... 16 25 Using c++-classes..................................................................................................................... 16 26 Creating stand alone web applications...................................................................................... 17 27 Some notes about multi threading.............................................................................................18

Tntnet users guide

1 Concept
Tntnet is a application server for web applications written in c++. A web application in tntnet is written with a template-language, which embeds c++processing-instructions in html-pages. You can use external classes or libraries in these pages. That wa programmers can concentrate on the htmlresult, when creating content and put processing in c++-classes. Applications written with the template-language called ecpp are compiled into c++-classes and lin!ed into a d namicall loaded shared librar . This is done at compile-time " not at runtime, li!e other template-s stems often do. #n runtime there is no compiler needed.

2 Installing Tntnet
Tntnet runs on $inux%&nix. You need a c++-compiler to compile Tntnet and also to compile our web applications. As a prere'uisite cxxtools (which is available through the Tntnet-homepage http)%%www.tntnet.org* is needed. +xxtools is a collection of useful c++-classes. To install tntnet ou have to) 1. install cxxtools 2. unpac! the sources with ,tar x-f tntnet-version.tar.g-. /. cd to the source-director ,cd tntnet-version.tar.g-. 0. run ,.%configure. 1. run ,ma!e. 2. run ,ma!e install. This installs) The application server and tools for 1. tntnet " the web application server 2. ecppc " the ecpp-compiler /. ecppl " the ecpp-language-extractor for internationali-ation 0. ecppll " the ecpp-language-lin!er for internationali-ation 1. some shared libraries 2. tntnet-config " a script, which gives ou information about the installed Tntnet and helps ou setting up a simple pro3ect.

3 Create a simple application with Tntnet


The simplest wa to create a tntnet-application is to use the tntnet-configscript. 4ust run ,tntnet-config "pro3ect5pro3ectname.. This creates a director with the name of the pro3ect and) 1. pro3ectname.ecpp " our first ecpp-file 2. 6a!efile " a simple ma!efile to build the application /. tntnet.conf " a basic configuration file for tntnet Tntnet users guide /

0. tntnet.properties " a basic configuration file for logging-configuration 7t used to be necessar to use a valid +++-class name as a pro3ect name, since it was used as a class name internall . This is not true for tntnet 2.8 an more. To build the pro3ect, change to the director and run ,ma!e.. This runs the necessar steps to create a running application. You get a shared librar pro3ectname.so, which contains the web application. To run it enter ,tntnet tntnet.conf. and navigate our browser to http)%%localhost)9888%pro3ectname. You get a simple :eb-page.

4 C++-content (processing, expressions, conditional expressions)


There are some simple tags, with which ou can embed c++-content into the page. The most important are processing-tags and output-tags. :ith processing-tags ou insert c++-code into the page, which is processed on runtime. There are / alternatives to insert code) The most verbose version is <%cpp>...some c++-code...</%cpp>. A newline after </%cpp> is ignored. <{ starts an inline-bloc!, which is terminated b }>. A newline after the closing tag is not ignored, but passed to the browser. The character ;<; in the first column starts also c++-code until the end of line. A bac!slash disables the interpretation of the next character. You can embed the result of a c++-expression with <$ expr $> into the htmlcode. 7t is printed into the page. The t pe of the expression needs to have a output-operator for std))ostream. The output is automaticall translated into html. +haracters with special meaning in html are printed as their html entit counterparts. #ften ou need to print something depending on a condition. You can put a ifstatement around it. As a shortcut there is a special tag <? cond ? output ?>. ,cond. is evaluated as a c++-expression. 7f the result of this expression is true, output is printed. The output is translated li!e <$...$>. Another useful tag is <# ... #>, which is 3ust a comment. The content is s!ipped b the ecpp-compiler. 7n +++-mode reply.out() returns a std::ostream, which writes text to the htmlpage. reply.sout() returns a std::ostream, which escapes characters with special meaning in html before writing to the page.

!uer"-arguments (scalar#$ector, unt"ped#t"ped, de%ault$alue)


:eb-applications need to interact with the user. Therefore the send a htmlform to the user. After the user submits the form, the application needs to Tntnet users guide 0

interpret the content of the form. To support this, ecpp has a tag) <%args>...</%args>. =etween this pair ou define the arguments of the form. >ach argument is terminated with ;?;. >cpp generates c++-variables of t pe std))string, containing the content of the form. You can precede arguments with a c++-t pe to convert the parameter automaticall into this t pe. This is done using the input-operator of std))istream. @ince tntnet 2.8 a parameter defined with the t pe bool is interpretation as true for all non empt strings. This ma!es it eas to chec!, if a specific submit button was pressed. >cpp supports multiple input-tags with the same name, e.g. multiple chec!boxes or select-tag with attribute multiple. = appending AB to our argument a std))vector and a t pedef will be generated. :riting name[] will be compiled to a t pedef name_type and a vector name. @ingle arguments can have a default value using the s ntax aria!le " de#ault_ alue$. >xamples)
<%args> name; street; city = New York; int age; // content of text-input is converte to int !oo" !utton#; // true$ if t%e su!mit !utton wit% name !utton# was use for // su!mission int sport&'; // mu"tip"e c%eck!oxes wit% t%e same name </%args> <( use t%e vector "ike t%is) (> % for *sport+type))const+iterator it = sport,!egin*-; it .= sport,en *-; //it- 0 <1 2it 1> % 3

& Components
>cpp-pages are called components. The are identified b their name. The name is composed of the local-name and the librar -name divided with ;C;. The local name is b default the filename of the ecpp file without path and extension, but ma be changed to whatever needed b passing a name using -n to the ecpp compiler ecppc. The -n switch can be used to pass full path names as component names. +omponents, which are called b Tntnet are called top-level-components. +omponents can contain internal subcomponents. The subcomponent-name is appended to the class-name divided b a dot. @ubcomponents can;t be called directl from tntnet but onl explicitl using a component call. >xamples are)
mycomp4app

Tntnet users guide

identifies a component with the name ,m comp. in the shared librar ,app.so.
mycomp,su!comp4app

identifies a subcomponent ,subcomp. of ,m compCapp.


foo/!ar/!a54we!app

identifies the component ,foo%bar%ba-. in the shared librar ,webapp.so.

' Component-parameters
>ver component has / parameters called ,re'uest., ,repl . and ,'param.. The ,re'uest.-parameter contains information about the re'uest, received from the browser. This includes information about http-headers, the peer-ip, coo!ies or multipart-components. The parameter is an instance of the class ,tnt))httpDe'uest.. The ,repl .-parameter is used to build the answer to the re'uest. The repl ob3ect is an instance of the class ,tnt))httpDepl .. 7t contains methods to manipulate the http-headers and an output-stream for writing to the httpbod . ,'param. specifies the 'uer -parameters of the component. Eor top-levelcomponents it contains the 'uer -parameters of the form. As described above, the parameters are normall accessed using the F<argsG-bloc!.

( )eturning %rom components


Top-level-components return the http-response-code as an unsigned integer. 7f a explicit return-statement is not specified the constant HTTIJ#K is returned. +onstants, which define http-response-codes are defined in the header tnt%http.h. As a special case the web application ma return the constant L>+$7M>L. 7t tells Tntnet, that the current components is not interested in processing the repl further and Tntnet should continue in the url mapping table (see configuration section*. >xceptions ma be thrown if something goes wrong. All exceptions are catched b Tntnet and sent with an internal server error to the client. A exception of class tnt))Http>rror carr a http return code, which is used, when this t pe is thrown. Additional http headers can be set also. This is useful for generating special http responses li!e redirects. =ut to ma!e it even easier there are special methods for redirects and also authori-ation. =oth are handled using exceptions. To ma!e a redirect, ou ma call repl .redirect with the new location as a parameter) >xample)
<%cpp> return rep"y,re irect*/new/"ocation,%tm"-; </%cpp>

Tntnet users guide

sends a http-redirect message to the client Mote that that the redirect method never returns but throws a tnt))Http>rror. 7t is still defined as returning an unsigned, so that the return statement, although s ntacticall correct, ma be left out. 7t is 3ust for s ntactic sugar. Http-authori-ation is also implemented li!e redirects. This is explained in more detail later in this document.

* Calling components (d"namic#static)


Mormall ou don;t want to write a whole web-application in one file, but ou want to split it into pieces and glue them together, 3ust li!e ou would write normal applications. You don;t write a single function, but split it into smaller parts and call them from a ,main.-function. This paradigm is supported b using components. +omponents can be called from other components. You can write reusable components, which implement some specific parts of our page, e. g. a table or select-box. +omponents are called using <% ... >. =asicall there are several alternatives to call a component. 7n the simplest and ma be most common case the component-name without librar -part can be written inside these tags. +omponent-names without librar -part are searched in the local subcomponent first. 7f not found, the component is searched in the librar of the calling component. >xample)
<6 somecomp >

call the component ,somecomp. here. 7f there is a internal subcomponent, this is called, otherwise the component is loo!ed up in the librar of the calling component. @ubcomponents, which are defined in other components, are called b appending the subcomponent-name to the component-name separated b a dot. >xample)
<6 ot%ercomp,su!comp >

call the subcomponent ,subcomp. in the component ,othercomponent.. To call a component in another librar the librar -part is appended to the name. >xample)
<6 somecomp4some"i! 6>

inserts the component ,somecomp. from ,somelib.so. here +omponent-names can be computed at runtime. To call a computed component-name, the expression is put inside brac!ets. >xample) Tntnet users guide N

% st ))string comp = comp; <6 *comp / 4ot%er"i!- 6>

The component ,compCotherlib. is called.

1+ Calling components %rom c++


+omponents can be called directl from +++ using the method callComp. It ta!es the parameters

component-id (of t pe tnt::compident or tnt::subcompident or a std::string* re'uest repl 'uer -parameter-ob3ect (of t pe tnt::query_params*

7t returns a http-result-code. @ee the AI7-documentation for details. @ometimes it is useful not to send the output directl to the client. :ith the method scallComp() it is also possible to retrieve the output and e.g. modif it before sending. 7t ta!es the same parameters as callComp, but no reply. 7nstead a temporar repl -ob3ect is created when the component is called. The httpreturn-code of the called component is ignored. >xample)
st ))string resu"t = sca""7omp*re8uest$ 8param-;

11 Include ecpp-%iles
>cpp-files can be included using the tag F<includeGfilenameF%<includeG. The content is included at compile-time. 7t is similar to the Oinclude-directive in +++. 7ncluding >cpp-files can be useful for)

global declarations initiali-ation, which is needed in multiple components it is strongl recommended for global-scope (explained below* variables.

7t should not be used for including content. +omponent-calling is better for that, because the content is not duplicated.

12 ,eclaring su-components
@ubcomponents are declared using <%def compname>...</%def>. The s ntax of subcomponents is the same as in top-level-components. The onl exception is, that it is not possible to define other subcomponents there. >xample)
9e""o <6 w%o > <% ef w%o> :or" </% ef>

Tntnet users guide

Irints ,Hello :orld..

13 .assing parameters to components


@ubcomponents receive named 'uer -parameter 3ust li!e top-levelcomponents. The parameters are passed inside the FP...G-tags. The called component defines the parameters using an F<argsG-bloc!. >xample)
<6 greeting name=;inus "astname=<orva" s> <% ef greeting> <%args> "astname; name; </%args> 9i <1 name 1> <1 "astname 1> </% ef>

Irints)
9i ;inus <orva" s

>xpressions are enclosed in brac!ets. The parameter t pe can also be numeric or an other t pe, which is seriali-able and deseriali-able using std))ostream and std))istream. >xample)
<0 st ))string name=a"ue = ;inus; st ))string "astname=a"ue = <orva" s; unsigne repeatNum = >; 3> <6 greeting name=*name=a"ue- "astname=*"astname=a"uerepeat=*repeatNum-> <% ef greeting> <%args> "astname; name; unsigne repeatNum = #; </%args> % for *unsigne n = ?; n < repeatNum; //n- 0 9i <1 name 1> <1 "astname 1> % 3 </% ef>

Irints)
9i ;inus <orva" s 9i ;inus <orva" s 9i ;inus <orva" s

A component can pass all its parameters to a subcomponent using its own 'param-ob3ect. 7n the example below the parameters of the subcomponent greeting are forwarded to printname. Tntnet users guide Q

>xample)
<6 greeting name=;inus "astname=<orva" s> <% ef greeting> <%#>greeting</%#> <6printname 8param> </% ef> <% ef printname> <%args> "astname; name; </%args> 9i <1 name 1> <1 "astname 1> <% ef>

Irints)
<%#>greeting</%#> 9i ;inus <orva" s

14 ,e%ining scoped $aria-les


Rariables are defined in normal c++-s ntax b specif ing t pe and name of the variable and the termination character ;?;. These variables are instantiated automaticall on first use. +onstructor-parameters are specified b adding them in brac!ets after the name.

14.1

Lifetime

Rariables are defined in a lifetime-area. The lifetime can be session, re'uest, application or thread. @ession-variables are valid for the current user session. @essions are identified b coo!ies. >xample
<%session> st ))string current@ser; </%session>

De'uest-variables are valid while the current re'uest is processed. This is the shortest possible lifetime. >xample
<%re8uest> unsigne nextA *?-; </%re8uest>

Application-variables are valid as long as tntnet runs. The are shared between users. >xample Tntnet users guide 18

<%app"ication> B!7onnection my7onnection*customer !-; </%app"ication>

To use the application-lifetime correctl it is necessar to !now, that our application is one shared librar . Application-variables are onl accessible within the same shared librar . Thread-variables are valid, as long as the thread is running. These variables are not shared between threads, but each thread has its own cop . >xample
<%t%rea > tnt !))7onnection my7onnection*s8"ite)customer, !-; </%t%rea >

14.2

Scope

@tate-variables are b default valid onl in the component, where the are specified. The same name can be used in different components without conflicts. @ometimes it us useful to widen this scope. You could e.g. define a sessionvariable ,current&ser., which is accessible throughout our application. The scopes are specified b adding the scope-attribute to the tag. Ralid scopes are) component (the default*, page (inside the current component and its internal subcomponents* and global. The application is a shared librar with our components. >xamples)
<%session scope=g"o!a"> st ))string current@ser; </%session> <%re8uest scope=page> int num!er*#-; </%re8uest> <% ef> <%re8uest scope=page> int num!er; // t%is references t%e varia!"e num!er // outsi e t%is su!component </%re8uest> </% ef>

efine

A special case is parameter scope. This is a techni'ue, where we can pass almost an class we need as a parameter to subcomponents. The scoping techni'ue is used here. 7n components we can define parameter scope variables) >xample
<%param> tnt !))7onnection my7onnection*s8"ite)customer, !-; </%param>

Tntnet users guide

11

As with other variables, we can pass constructor parameters for default construction, when the parameter is not set. :e can not define a scope, since parameters are alwa s local to the current component. :hen we call these components, we pass the variable as name value pairs divided b ;5; in brac!ets 3ust after the component name) >xample
<%cpp> tnt !))7onnection conn* !ur"-; </%cpp> <6 mysu!comp*my7onnection = conn- 6>

Here we define a connection ob3ect and pass it as a named parameter. Mote that the ob3ect is passed b value, which means, that the ob3ect is copied once. 7f ou want to pass the ob3ect b reference without cop ing, ou ma pass a pointer to it. The F<paramG-bloc! needs to specif the pointer t pe also. T pes are not chec!ed at compile time. 7f ou pass a wrong t pe, the behavior is undefined. You should reall be careful, what to pass.

Coo/ies

+oo!ies are supported b tntnet with a simple api. A coo!ie consists of a name, a value and optionall attributes. To set a coo!ie a ecpp-application call ,repl .set+oo!ie.. The simplest form is to call it with 2 parameters) a name and a coo!ie. You can pass 3ust a std))string or a character-string as name and value of the coo!ie. :hen the browser does its next re'uest, ou can read the coo!ie with ,repl .get+oo!ie(*.. This returns a coo!ie-ob3ect, which is directl convertible to a std))string. >xample) To set a coo!ie)
<0 rep"y,set7ookie*mycookie$ myva"ue-; 3>

At next re'uest retrieve the value)


<0 st ))string v = re8uest,get7ookie*mycookie-; // v %as t%e va"ue myva"ue now 3>

To clear the coo!ie)


<0 rep"y,c"ear7ookie*mycookie-; 3>

Tntnet users guide

12

1& Component attri-utes


@ometimes it is useful to 'uer attributes of a component. Attributes are 3ust string-values, which are defined inside a component. Attributes are defined within a F<attrG-bloc!. A attribute consists of a name, the character ;5; and a string terminated b ;?;. To 'uer attributes of a component ou need to fetch a reference to it with fetch+omp. Iass a component identifier to fetch+omp and use the method getAttribute with a name-parameter to retrieve the value. >xample) Lefine a attribute)
<%attr> myattri!ute = myva"ue; </%attr>

To 'uer the attribute)


<0 st ))string v = fetc%7omp*component4"i!rary-,getCttri!ute*myattri!ute-; // v contains t%e va"ue myva"ue now, 3>

1' Con%iguration
Tntnet needs a configuration file to run. = default this is read from ,%etc%tntnet%tntnet.conf., but ou can pass a different file as a parameter to tntnet, as was done at the first example. The file is a text file and contains configuration variables. >ver line starts with a variable name followed b 8 or more parameters separated b whitespace. 7f a parameter contains itself whitespace, enclose the parameter in single or double 'uotation mar!s. 7f ou need the 'uotation mar! in the value, ou must precede it with ;S; to escape its special meaning. $ines starting with ;O; and empt lines are ignored. There are variables, which are read b tntnet. &n!nown variables are ignored. +omponents might use them, so the need not be un!nown if the are un!nown to tntnet. The most important variable is ,6ap&rl.. 7t tells tntnet, what to do with re'uests. :ithout this variable tntnet answers ever re'uest with 080 " HTTIJM#TJE#&ML. ,6ap&rl. ta!es at least 2 parameters) a regular expression, which is matched against the url, sent from the client and a component name, which to call, if the expression matches. The component name might contain bac! references to the regular expression. To define bac! references, enclose the interesting part in brac!ets and reference them in the mapping using the dollar sign with a digit. The digit specifies, which brac!eted part is replaced. The brac!ets are numbered from 1. Tntnet users guide 1/

>xamples)
( maps every %tm"-fi"e to t%e component wit% t%e same !asename e,g, ( /in ex,%tm" in ex4myapp Dap@r" /*,2-,%tm" 1#4myapp ( maps re8uests$ w%ic% en wit% ,Epg to components wit% +Epg-suffix e,g, ( /myimg,Epg => myimg+Epg4myapp Dap@r" /*,2-,Epg 1#+Epg4myapp ( makes every component avai"a!"e t%roug% %ttp !y mapping t%e part !efore ( first F/F to t%e app"icationname *s%are -"i!rary-name- an t%e part after ( t%e app Dap@r" /*,2-/*,2- 1G41#

1( 0ccessing con%iguration $aria-les


@ometimes web applications need some configuration e.g. a database-url. 7nstead of hard coding it, the application can put it into the configuration file of tntnet. +onfiguration variables read this wa can contain onl a single value. To specif a variable, put a F<configG-bloc! into our component. 7nside define a variable m putting the name and optionall a default value separated with ;5; and terminate the definition with ;?;. >xample)
<%config> !ur" = ata!ase=my !; </%config>

To set the dburl-parameter put a line)


!ur" ata!ase=anot%er !

into tntnet.conf. 7f ou don;t specif a default value, the variable is set to an empt string, when not set in tntnet.conf.

1* 1ogging
$ogging is done through the cxxtools-meta-logging-librar . This uses log0cplus, log0cxx or a simple builtin-logging depending on configuration of cxxtools. You don;t have to bother too much about the used librar , when developing tntnet-applications. The AI7 sta s the same. 7f ou use 3ust the cxxtools-provided macros, ou can switch later to another librar without changing the source of our application. >ver logging-librar cxxtools supports, support logging categories and severities. Tntnet defines for each component a categor Tntnet users guide 10

,component.componentname.. :hen ou need to log something, 3ust use one of the macros logJfatal, logJerror, logJwarn, logJinfo or logJdebug. The parameter is passed to a output stream and ou can put multiple outputitems separated b ;FF;. :hat is logged where is specified in ,tntnet.properties. (but this can be changed in tntnet.conf*. 4ust loo! into the example tntnet.properties for some details about configuration and loo! at the documentation of the underl ing logging-librar .

2+ 2xception handling
>xceptions derived from std))exception thrown b components are catched b tntnet. The usuall generate a 188 " HTTIJ7MT>DMA$J@>DR>DJ>DD#D, but there is a exception class tnt))http>rror, which ta!es a error code and a message. The code is used as a http-error-code. You should use the tnt))HTTIJT-constants for it.

21 3a$epoints
@ometimes ou might want to catch exceptions generated b lower level classes or subcomponents and generate a nicel formatted error-message. 7n this case ou might want to close all open html-tags before starting our error-message. This is often a almost impossible tas!, because ou don;t !now, where the exception occurred. $uc!il ou get help from tntnet%ecpp to solve this open-html-tag problem) savepoints. A savepoint is a simple class, which acts li!e a transaction for html-output. You instantiate a savepoint as a local variable at the start of our tr -bloc! and pass the re'uest-ob3ect to it. =efore catch call savepoint))commit(*. 7f the commit is not reached, because a exception happened, the savepoint-ob3ect rolls bac! the output to the point, where it was instantiated. >xample)
<0 try 0 tnt))Havepoint mysavepoint*rep"y-; 3> <form> <input type=text name=va"ue va"ue=<1 o!Eect,get=a"ue*- 1>> </form> <0 mysavepoint,commit*-; 3 catc% *const your+ !exception6 e0 3> <p c"ass=error>C ata!ase-error occure ) <1e,w%at1></p> <0 3 3>

7n case ob3ect.getRalue(* throws a , ourJdbexception. the form-tag is Tntnet users guide 11

discarded from the output of the component and a nice error-message is printed. :ithout the savepoint the output ends at ,value5... This results in a badl formatted html-page. Mote, that ou have to include Ftnt%savepoint.hG somewhere in a F<preGsection to get the definition of tnt))@avepoint.

22 4inar" content
:eb applications ma contain logos and other images or binar content. The often have static content. Eor web applications to be complete, ou need a wa to include our images. 7n Tntnet%ecpp ou can generate components out of binar files, e.g. 3pegimages. The ecpp-compiler ecppc has a special switch -b, which generates c+ +-classes out of these files, without interpreting tags, which might appear in binar files. :ith the switch -m ou can specif the mimet pe, but if ou don;t do that, ecppc will use our mime-database (normall %etc%mime.t pes*. >xample) To generate a component out of a 3peg-file logo.3pg)
ecppc -! "ogo,Epg

will generate a logo.h and logo.cpp, which ou can compile an lin! into our application librar . The downside is, that for small binaries li!e small graphics there is a relative large overhead (7 measured a increase of the web application of about 9! per image*. Therefore starting with version 1.1 of tntnet the ecpp-compiler is able to pac! multiple binaries into a single component. This is done with the switch -bb. To address a image in a multi-image-component, ou have to pass the name of our image as pathinfo to 6ap&rl in our tntnet.conf)
Dap@r" /images/*2,Epgmymu"tiimagecomponent4mywe!app 1#

23 5pload
&ploading files is supported b html with the input-tag with t pe5.file.. To use it, ou have to specif the enct pe ,multipart%form-data. in our form-tag. :hen the form is submitted, the values comes in a special format, which supports large ob3ects. This is supported b tntnet and it has a simple api to access the uploaded file. =ecause files might be somewhat larger than other form-content, the are not passed through the 'param-parameter and not accessible in F<argsG-bloc!s. You have to fetch a const reference to a tnt))multipart-ob3ect with re'uest.get6ultipart(*. This ob3ect is a container of ob3ects of t pe tnt))part. You can either iterate through the parts or use the find-method to directl find the part, which contains the uploaded file. The tnt))part-ob3ect gives ou access to the content either through constant iterators or 3ust as a string. The iterator-interface is more efficient, because it does not need to instantiate a temporar string. You should consider alwa s to use the iterator-interface. Tntnet users guide 12

>xample) To create a form with a upload-field)


<form enctype=mu"tipart/form- ata> <input type=fi"e name=up"oa > <input type=su!mit> </form>

To save the uploaded file)


<0 const tnt))mu"tipart6 mp = re8uest,getDu"tipart*-; tnt))mu"tipart))const+iterator it = mp,fin *Iup"oa I-; if *it .= mp,en *-0 st ))ofstream f*resu"t, at-; st ))copy*it->getJo yJegin*-$ it->getJo yKn *-$ st ))ostream!uf+iterator<c%ar>*f--; 3 3>

24 6TT.-0uth
Tntnet supports HTTI basic authentication. Eor HTTI authentication the server needs to chec! the sent user name and password and if invalid, send a HTTI-error-code 081 with a realm. The realm is presented to the user in a login dialog. There are / methods in tntnet, to support this)

re'uest.get&sername(* returns returns the user name sent b the client as a std))string or an empt string, if nothing set re'uest.verif Iassword(std))string password* returns true, if the password, which is sent b the client, matches the passwort passed as a parameter. Alternativel ou can use re'uest.getIassword(*, which returns the password as sent from the client. repl .notAuthori-ed(std))string realm* throws a http-exception, which sets the proper HTTI-header for basic authentication.
<0 if *re8uest,get@sername*- .= IC"a inI // user name wrongL MM .re8uest,verifyNasswor *Iopen sesameI-- // passwor wrongL 0 rep"y,notCut%ori5e *Iw%o says w%at to open t%e sesameLI-; 3 3>

This ma!es using HTTI basic authentication simple)

5sing c++-classes

As mentioned earlier it is desirable to separate content and processing. +ontent is the view, which is created using ecpp. Irocessing are some c++classes. :hat ou need is a wa to access c++-classes from our ecpp-files. $uc!il this is eas done. Tntnet users guide 1N

A c++-class consists generall of a interface in a header-file and a implementation in a implementation-file. You can lin! our application with the implementation, but ou need a wa to include the interface into our ecpp-file. This is done in the F<preG-bloc!. +ontents of this bloc! is copied unmodified to the start of the generated header. You can place Oincludedirectives here. >xample)
<%pre> (inc"u e yourc"ass,% // inc"u e t%e c"ass- efinition %ere </%pre> <0 yourc"ass c; // e,g, instantiate your c"ass 3> <p><1 c,getCttri!ute#*- 1></p> <( inc"u e a attri!ute-va"ue into your page (>

You might as well lin! our shared librar to a external librar and use it this wa .

2& Creating stand alone we- applications


7nstead of compiling our application into a shared librar ou ma create a stand alone web application. You do not need the tntnet application server and no configuration file. All is handled in the tntnet-librar libtntnet. All ou have to do in addition to creating ou application itself is to create a mainfunction, which instantiates a tntnet-instance, configures and runs the server. The actual application server is represented b the class tnt))Tntnet in the include file Ftnt%tntnet.hG. You need to call tnt))Tntnet))listen (or tnt))Tntnet))ssl$isten* with an ip-address as a std))string and a port as an unsigned short to tell tntnet, where to accept connections from. To tell, tntnet how to find our application ou need to add url-mappings with the method tnt))Tntnet))map&rl. This ta!es 2 parameters) a url (or a regular expression* and a component name. The component name do not have a librar part as before, since the components are compiled into the binar , although it is possible to add a librar part, in which case tntnet loads the component librar as before. The method returns a reference to a new tnt))6aptargetob3ect, where ou ma add additional parameters li!e a custom path info. To run the application, call the method tnt))Tntnet))run(*. >xample) +reate a file main.cpp)
(inc"u e <tnt/tntnet,%> int main*int argc$ c%ar2 argv&'0 try 0 tnt))<ntnet app; app,"isten*I?,?,?,?I$ O???-;

Tntnet users guide

19

app,map@r"*IP/1I$ I%e""oI,setNat%Anfo*I/%e""oI-; app,map@r"*IP/*,2-1I$ I1#I-; st ))cout << It%e %e""o app"ication is foun %ttp)//"oca"%ost)O?O?/I << st ))en "; app,run*-; 3 catc% *const st ))exception6 e0 st ))cerr << e,w%at*- << st ))en "; 3 3 at

+reate a web application hello.ecpp. :e put a simple greeting into the application here)
<%tm"> <!o y> <%#>9e""o</%#> </!o y> </%tm">

+ompile and lin! the main application and the component)


g// -c main,cpp ecppc %e""o,ecpp g// -c %e""o,cpp g// -o %e""o main,o %e""o,o -"tntnet

Dun the new binar hello and navigate our browser to http)%%localhost)9888% and ou will see a greeting from our application.

2' 3ome notes a-out multi threading


:hen developing ecpp-components ou have to bear in mind, that Tntnet is multithreaded, so our code have to be thread-safe. $uc!il Tntnet does it;s best to encapsulate most of it, but if ou use our own classes this must be considered. You can use cxxtools))6utex and cxxtool))6utex$oc! to protect our ob3ects. @coped variables are automaticall protected. 7f ou use a application-scoped variable the current re'uest loc!s the application-scope-ob3ect and prevents other concurrent threads accessing the application-scope until the re'uest is finished. &sing session-scope loc!s the application-scope-ob3ect first and then session-scope-ob3ect to prevent deadloc!s, where one re'uest waits for the session-scope and the other wait for the application-scope.

Tntnet users guide

1Q

Potrebbero piacerti anche