SQLData Server Components
Server Programming
Guide
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.