Server Programming Guide

SQLData Server Components

 

Server Programming Guide

Introduction

This document is for web application developers who want to develop special components for SQLData servers, or to build server extension to handle business specific needs.

C/C++ Programming is required for developing such components.

SQLData server provides very simple server application programming interface (API) that gives developers opportunities to further customize the server. Using the server API, you can:

o        Write message handlers to processing user requests.

o        Create message filters to enhance server security.

o        Build new template tokens to be used in your HTML files.

o        Implement logic processors to deal with your special business logic.

Server API

SQLData server API consists three functions: Open, Execute and Close. They must reside in a DLL with the following signature:

void * Open(void * pContext)

This is the first function in your DLL the server calls. It gives your server an opportunity to initialize and to create an object to deal with a request. The returned void pointer will be passed to Execute and Close functions. You may return NULL if no special object needed for the request. The server doesn't check the status of the function.

The pContext is a pointer to the server context (defined in the following sections). This function is optional.

int Execute(void * pObject, void * pContext)

This is the main function for handling a request. The server passes an object pointer, returned from the Open function, and the server context pointer, pContext to the function.

The function should return nonzero if successful, 0 otherwise.

void Close(void * pObject)

This is the last function the server calls. You may use the function to clean up allocated resources for the request. The function is optional.

The only function required in your component is the Execute function.

 

The Server Context

In order to process a request, a server component needs access to the request object, the server configuration, and the response object for sending data back to users. These are all provided by the server context object.

The server context is a C++ class defined as:

class CDBContext

{

public:

CDBContext(const void * pContext, bool bClone=false);

virtual ~CDBContext();

public:

char* GetValue(const char* key);

char* GetHeader(const char* key);

void SetValue(const char* key, const char* value, int nSetType=SV_OVERWRITE);

void RemoveValue(int nIndex);

void RemoveValue(const char* szKey);

int WriteClient(const char* buffer, int nSize);

int WriteClient(const char* buffer);

void Logging(char* format, ...);

// debug logging

void Debugging(char* format, ...);

public:

void SetResponseHeader(const char* szName, const char* szValue);

StrPtr GetEnvSetting(const char*szName);

void SetEnvSetting(const char* szName, const char* szValue);

void SetStatus(int nStatus, const char* szReason);

int GetStatus();

protected:

void * m_pContext;

};

 

 

 

 

The server context contains three major interfaces:

o        Accessing Requests: It allows you to get values associated with user requests through GetValue, GetHeader functions.

o        Retrieving Environment Settings: The GetEnvSetting function can be used for getting both server configuration information and user session variables.

o        Sending Response: You use the WriteClient function to send data to users.

At the time your component is called, the server has already created a server context object. This context object is passed to the Execute function as the second parameter.

char* GetValue(const char* szName);

Description:

This function returns a value in the request object. A null pointer is return if the specified name doesn't exist. It can also be uses for getting values after the '?' mark in the URL. For example, if the URL contains

http://www.yourhost.com/file.html?DataSource=MyData

Then GetValue("DataSource") will return "MyData". You may use the function to get a cookie, for instance, to get the value of a session ID cookie, you can call

char * UserSessionId=GetValue("cookie:SessionId");

char* GetHeader(const char* szName);

Description:

This function returns a header value from an HTTP request. To get user browser name, you may use

char * szUserAgent=GetHeader("User-Agent");

char* GetEnvSetting(const char* szName);

Description:

This function returns a value from the server configuration file or the session object of the current user.

char * szDefaultPage=GetEnvSetting("DefaultPage");

void SetEnvSetting(const char* szName, const char * szValue);

Description:

The function adds a name-value pair into the session object of current user, it can then be retrieved using the GetEnvSetting function. The value is not written to the server configuration file. There is a session associated with each user. You may add temporary data into the session object using the function. The following example sets the current user id

SetEnvSetting("UserId", "12345");

int WriteClient(const char* szBuffer, int nSize);

Description:

The function sends the content in the buffer to clients. The size of the content is specified by the nSize parameter. The function returns the number of bytes sent. The following code sends a very simple HTML page to users:

char * szMsg="<HTML> Hello World </HTML>

WriteClient(szMsg, strlen(szMsg));

The szBuffer parameter may contain binary data and may not be '\0' terminated.

int WriteClient(const char* szBuffer);

Description:

The function has the same function as the one above except the buffer contain '\0' terminated string data.

void Logging(char* format, ...);

Description:

The function put a formatted string into the server log file. The format parameter may contain any format specifies defined in the printf function. The following write an error message into the log file.

Logging("My component error : %d", GetLastError());

Building Server Components

To use the server API and context object, you need to include the context.h file in your project and link to the INET.LIB library. Both files are under the ServerAPI directory.

Creating Message Handlers

A message handler is a component that deals with a particular user request. The server reads user requests and then invokes your message handlers. It is your handler's responsibility to send well-formed documents to users.

The following is a procedure for associating your message handler with a particular action requested from users

1.        Add one entry in the configuration file under the MsgHandler section:
$ActionName=MyCom.DLL
where ActionName is the name user request, and MyCom.DLL is the name of your component DLL.

2.        Put your DLL into the BIN subdirectory.

For example, suppose your component, UserReg.DLL, is dealing with user registrations and you want to handle the REGISTER message, you would add

$Register=UserReg.DLL

in the server configuration file. The server will dispatch messages to your component if

o        There is an explicit reference to Register in the URL, for instance,
http://www.yourhost.com/Register?User=foo

o        The action in a HTML form is Register like the following:
<form method=POST action=Register>

</form>

o        The DLL is used explicitly in the URL,
http://www.yourhost.com/UserReg.DLL?User=foo

Building Logic Pipeline Component

The SQLData server uses external logic pipeline components when they are specified in the Processors column of a stage (refer to http://www.sqldata.com/documents/logic.htm for the definition of the Logic Processing Pipeline). You can build pipeline components that are called by the pipeline processor during a stage of logic processing.

The pipeline component should have exact the same interface as the message handlers, and it must contains the three functions defined in the Server API section of the document.