Programming C Server Pages. V2.1



What's new at release 2.1

See the user quide( doc.html).

Introduction


With C Server Pages you can follow two different approaches to dinamize your site :

The Dynamics Elements: with this approach you insert in your html page Dynamics Elements which you or others have developed and compiled into a shared library (.so ) previously. C Server Pages provides the skeleton to create new Dynamics Elements easily. Those shared libraries are loaded by the TO_imanager processes when they start.

The C Server Pages : with this approach you can insert C or C++ code in the html page, converting it into a C Server Page ".csp". After that you compile the page into a shared library (.so). The TO_imanager processed load those shared libraries when start.

Your application can use both approaches at the same time.

There are also four standard objects you can use inside C Server Pages or Dynamic Elements : Session, Request, Response and Params.

Standard Objects

The Session Object

This object is to maintain data values trough different pages. You can have access to those data any time during the session is on. So it would be useful for example to keep the shopping cart in an e-commerce application.

You can reach the Session trough the session pointer "Session" available inside every C Server Page or Dynamic Element.

When you puts void values inside the session area, you have to take the memory from the global heap with the new operator, malloc function etc., because the Session object when destroyed frees all the values it contains. When you put char * values you don't have to make duplicates, the own function make a duplicate in order to keep global memory. Please use this characteristic when you want to free your own objects at the end of the user session.


The methods you can use are the following :



Method

Description

char * getValue(char * var)

Get a char * value from the session area. This value is valid while the session is.


char * cpUserName;

Session->appendValue("UserName","Peter");

cpUserName = Session->getValue("UserName");

//Now cpUserName points to "Peter", and it is valid all the session live


void * getVoid(char * var)

Get a void * value from the session area. This value is valid while the session is.

// In a previous page you can do:

vImage=malloc(sizeof(Image_struct))

memcpy(vImage,Image,sizeof(Image_struct));

Session->appendValue("Image 100",(void*)vImage);


// In a following page you can do this

void * RecuperedImage;

RecuperedImage=(Image_stgruct *) Session->getVoid("Image 100");

//And now RecuperdImage points to the vImage space



int setValue(char * var, char * value)

Updates a char * value in the session area.

int setValue(char * var, void * value)

Updates a void * value in the session area Frees the old value.

int appendValue(char * var, char * value)

Adds a char * value to the session area.

int appendValue(char * var, void * value)

Adds a void * value to the session area. When the session dies, it frees this value. So you have to take the memory with the new operator, the malloc function or similar.

int deleteValue(char * var, int mode=1)

Deletes a value from the session area. When mode is true, the function frees the

value.

void PrintSession(ostream & cout)

Print the session values to the streams you give as parameters. It only works for char * values and would produce a core file if you have void * values in your session.






You can also use the following resources

Resource

Description

char * cpSessionId;

This resource contains the session identifier.

so you can do things like

<# Response << Session->cpSessionId << endl ; #>

in your server page in order to write the session identifier to the output HTMLpage.


It is possible to use the Session object in both Dynamic Elements and C Server Pages.

The Request Object

This object is to access the query request coming from the browser. You can use the Request methods trough the Request pointer accessible from any C Server Page or Dynamic Element.

The pointer you obtain to variable names or values are valid only for the template or C Server Page requested. If you want to keep them across different pages you have to use the Session object.

See the following table also for examples:

Method

Description

char * getName(int index);

Get the name of the field in the position index from the requested query. Return NULL when the index makes no sense:


With this query request: "Param1=ONE&Param2=TWO"


Request->getName(0) points to "Param1 and Request->getName(1) points to "Param2".


char * getValue(char * fieldname);

Get a pointer to the value which field name matches the parameter. The function returns NULL if no field matches the parameter.

Following the example :

getValue("Param1") would point to "ONE".

char * FieldAsString(char *);

Works similar to getValue, but returns a pointer to "" when the argument does not match any parameter in the query request.

char * getValue(int index);

Get a pointer to the value at the position given for index. Following the example :

Request->getValue(0) would point to "ONE"

int appendValue(char * EntryName,char * EntryValue);

Adds a new variable to the request.

int setValue(char * EntryName,char * NewValue);

Updates a variable in the request.

void Print(ostream & c=cout);

Print the request query names and values

void Serialize(ostream &ct=cout);

Generates the query string again

char * Escape(char * cpq);

Escape one string to introduce it in a query.



The Response Object

This object is an ostream where you can write directly what you want in the HTML page.

Example from hello_world.csp :

<HTML>

<# Response << "Hello world" ; #>

</HTML>


In the Dynamics Elements approach this object comes as parameter in the SO_Expand virtual method and you can call it what you like.


Example from the Date Dynamics Element :


int CLASS_NAME::SO_Expand(ostream & Response){

time_t ti;

time (&ti);

Response <<ctime(&ti);

return 0;

}


The Params Object

This object is to gain access to the parameters given to the dynamic elements in the templates. When you invoke a Dynamic Element from a template you have to use the following syntax :


<# Class_name param1=value param2=value param3=value ...... #>


The public methods for this Object are specified in the following table :


Method

Description

char * getValue(char * ParamName);

Get a pointer to the value of the parameter ParamName passed as parameter.

char * getName(int index);

Get a pointer to the value of the name of the parameters at the position index.

char * getValue(int index);

Get a pointer to the value of the value of the parameter at position index.

int setParam(char * ParamName, char *cpNewValue);

Updates the value of the parameter which name is passed as parameter.

int appendParam(char * ParamName, char * cpValor);

Adds a new parameter

void Print(ostream & os=cout);

Print the parameters names and values to the ostream passed as parameter.


The Process Object

This object is to maintain data values and variables with a process scope. You can have access to those data and variables any time from any C page or dynamic elements. It would be useful for keeping data or variables which have to be accesses for all the sessions at any time. For example to keep open the database conections: you can open those connection in the startup page, when the TO_imanager process starts and access them any time you need database access.

You can reach the Process object trough the Process pointer "Process" available inside every C Server Page or Dynamic Element.

When you put values inside the process area, you have to take the memory from the global heap with the new operator, malloc function etc., because the Process object does not alloc or duplicate these data.


The methods you can use are the following :



Method

Description

void * getValue(char * var)

Get a char * value from the Process area.


char * cpGatewayName;

cpGatewayName =Process->getValue("GATEWAY");

//Now cpGatewayName points to a value like "/cgi-bin/TOCgi"


int setValue(char * var, void * value)

Updates a void * value in the Proccess area and frees the old value. If the entry does not exist this methods does nothing.

int appendValue(char * var, void * value)

Adds a void * value to the Process area. You have to take the memory for value with the new operator, the malloc function or similar, in order to be accessed from any page.

int deleteValue(char * var, int mode=1)

Deletes a value from the Process area. When mode is true, the function frees the

value.




Two Programming Approaches

The Dynamics Elements Approach

Templates are ".html" pages renamed into ".tmpl" files. These templates can include Dynamics Elements which the C Server Pages parses and executes at run time.

you can have a template file containing the following:

<HTML>
Today date is : <# Dyn_Date #>
</HTML>

When Dyn_Date is a dynamic element which evaluates the present date from the system at the moment a user asks for this template. You can build as many Dyn Elements as you can imagine ! And use them in your templates. Those Dynamics elements can access anything you can reach with C++: from databases to device drivers.

In order to execute a template from your browser, you have to use a URL calling the C Server Pages cgi and putting in the query one parameter specifying which template you want to execute. This parameters is TODestination. For example to execute the date.tmpl template use:

http://myserver/cgi-bin/TOCgi?TODestination=date.tmpl

and the result page in your browser is :

Today's date is : Sun April 26 22:57:32 2000

The source code for the Dynamic Element Dyn_Date is :

int Dyn_Date::SO_Expand(ostream & Response){
time_t ti;
time(&ti);
os << ctime(&ti);
return 0;
}


The method SO_Expand(ostream & so) is the only method you have to implement. In order to write any text to the HTML page is enough to write it to the ostream parameter.

The dynamic elements can have parameters, and the Dynamic Elements developer can reach them using the Params object pointer :

For example let's take a look at the Href Dynamic Element. It takes a parameter called Destination. So you can write in a template :


<# Dyn_Href Destination=new.tmpl #>


and you can get access to the parameter inside the SO_Expand method of the Href Dynamic Element as follow :


char * cpDestination;
cpDestination=Params->getValue("Destination");


now cpDestination point to the string "new.html". That way you can get access to every parameter you put in the tmpl invocation for
that Dynamic Element.

Look at the Params object reference for other methods you can use.

Creating new dynamic elements

To create new dynamic element follow these steps :


  1. Choose the name for the new dynamic elements (for example "Element").

  2. Move to the objects directory

  3. Run the skeleton generator : newobject Element. It creates two files Element.cc and Element.hh

  4. Implement the SO_Expand method at Element.cc

  5. Insert the new target in the Makefile file: Look for the variable OBJS and add Element.o

  6. Run make to build the object

  7. Stop and restart the application, in order to load the new object. The TO_imanager processes has to write this message when start: Registering Dynamic Class Dyn_Element. If you see that you can be sure your new dynamic element is loaded.


From this point you can use <# Dyn_Element params #> in your templates.

When using external libraries you have to include them in the Makefile in order to link with them.

Creating new Templates

Templates are HTML pages with Dynamic Elements embedded. To create new templates you can follow the following steps :

  1. If starting from one HTML page, copy it to the templates directory and rename it to have the tmpl extension. For example if the HTML page is adressed.html you can rename it adressed.tmpl .

  2. Include the dynamics elements you want to use

  3. Test it from your browser using this URL : http://yourserver:yourport/cgi-bin/TOCgi?TODestination=addressed.tmpl


The templates have to be in the templates directory in order to be reached by the engines. You can configure this directory in the servers configuration file.

It is not necessary to restart the engines when you change a template. Only change it and test it.

You can use in your templates the already implemented dynamic elements.

When passing multiple word parameters use simple quotes to delimit the value :


<# Dyn_Sql Sentence='SELECT * FROM PEOPLE ORDER BY NAME' #>


Useful Dynamic Elements

Included in the C Server Pages distribution you will find some Dynamics Elements already implemented that you can use in your templates. The source code for them is also included, so you can use them to learn in building new Elements or modify them to meet your needs :


Class Name

Description

<# Dyn_Date #>

Displays the current date. Do not take any parameters

<# Dyn_GetSession Name=variable_name #>

Takes variable values from the session area. Name say it the variable name.

<# Dyn_SetSession Name=Address Value='Althon Street' #>

Put variable values into the session area. Name say it the variable name and value is the value.

<# Dyn_Href Destination=other_tmpl.tmpl #>

Use this element to generate the correct url to invoke another template. For example you can insert links to templates as follow

<A HREF=<# Dyn_Href Destination=mytemplate.tmpl #>Jump to mytemplate </A>

It included the required fields to maintain the session between requests.

<# Dyn_PrintAll #>

print to the HTML page the values from the Params, Session and Request objects.

<# Dyn_Session #>

Print to the HTML page the current session identifier.




The C Server Pages Approach

This approach lets you embed C++ code in your HTML pages. In order to compose one application you can use the Response, Session and Request standard objects and of course any C C++ library / application you want to launch to Internet.

You can access any data base which has a C / C++ interface in the same way your client/server applications do it now : linking your pages with the database libraries.

For example you can use Oracle, Informix, Sybase, ODBC, mysql, postgres, ingres, Codebase, Unix dbm .... and in general any RDBMS or file manager which has a C/C++ interface.

In the same way, you can access any Corba server using C/C++, you only have to use it and link your pages with the right library for that Corba implementation.

Keep in mind that virtual java machines or java script interpreters are written with C/C++. So, there is no technical problem integrating those virtual machines and execute Java or java script code inside your C Server Pages. You also can use C Server Pages as a platform to build more complex application servers which load and execute java, javascript etc.

The include section has to be delimited with the symbols <#! and #> and has to appear (if exists) at the beginning. Any other C/C++ fragment inside the C Server Page must to be delimited by the symbols <# and #>. It is possible to have any number of C/C++ fragment in each page.

Example :

<#!

#include <stdio.h>

#>

<HTML>

HTML TEXT

<#

//Here you write C / C++

char Message[5000];

sprintf(Message,"Hello, this is write numbers");

Response << Message << "<BR>" << endl;

#>

</HTML>


You can use the standard objects Session, Response and Request to build your application.

After writing a csp page, you have to precompile it with cspc (C Server Pages Compiler) to obtain C++ code and after that you have to compile it ot obtain a shared library which the Session Manager can load.

Please look at the Makefile file in the cspages directory. You can use this Makefile to precompile and compile your C Server Pages, only adding the new page as target.

There are a couple of utility macros you can use in your CSP to carry out some routine jobs. These are defined in the file cspages_util.hh and you can find it in the include/cspages directory of the distribution.

Macro

Description

GoLocal(X)

Redirect the execution to another C Server Page locally. See the if.csp example

HRef(X)

Generate the correct URL to jump to a C Server Page

HRefTemplate(X)

Generate the correct URL to jump to a template



Tracking the Session

When you request a C Server Page or template without giving the Session Identifier, C Server Pages give you a new one. It is necessary to include this Session Identifier in following requests to identify the right session. The session identifier is a random number plus a timestamp, so is very difficult (almost impossible) to guess the session identifier of a different user.

The needed parameter for tracking the session in every request is TOSessionId, and its value must be the actual session identifier.

When you use the macros Href, HrefTemplate and the Href Dynamic Elements, they insert this parameters in the request to track the session.

Look at the form.tmpl example template for details about forms.


Privacy of Data and Applications

C Server Pages works with Secure Socket Layer and any other technology used between the web server and the user browser.