Table of Contents
WebtoB provides new APIs that help enhance CGI application program functionality.
This chapter describes the APIs provided by WebtoB.
In the existing CGI process, when a user request comes in, a new process starts to handle the request. If a user makes a new request, the operating system forks the process corresponding to the program. When a process is forked, a copy of the process is created and made into a child process of the original process. Forking can affect system performance. The burden on the system that forking creates caused existing CGI users to seek new applications, resulting in appearance of Servlet, PHP, ASP, and JSP.
These programs are not written in C but in Java or Script language. While these programs may be easy for programming, discarding existing C programs and developing a new program is also a burden.
CGI developers must consider whether to discard their existing CGIs and introduce new programs, or to continue operating existing programs and increase the number of servers to reduce CGI burden. WebtoB introduces new APIs to resolve the developers' problems.
As an API for C programs, WBAPI reduces CGI program burden and minimizes CGI program modifications. Through these APIs, many users who use existing CGI programs can increase system performance.
As previously mentioned, when a new request comes in, the new program is forked and the request is handled and returned to the web server. The forking process becomes a burden when a system has to process many jobs.
The following figure shows how the CGI mechanism works in the Apache web server.
In the figure, the structure creates a CGI forking load whenever the web server has a new request.
WBAPI helps resolve the forking problem. In WebtoB, a process is not forked whenever a user sends a request. Instead, WebtoB forks these programs in advance (when web server boots up) and puts these programs into memory. It doesn't exit the process after the user request is processed but waits in the memory for future requests. By not exiting the process and not forking, WebtoB decreases the burden on the system.
WebtoB not only reduces burden but also manages programs designed by WBAPI. Thus, if the program terminates abnormally due to user or design error, a new program is started immediately. WebtoB can also adjust the number of programs. If the number of requests for a specific program is high, the program is executed more frequently in advance to reduce load.
The mechanism of WebtoB's WBAPI call is as follows.
WBAPI is different from general functions that start with main(). A program written with WBAPI is generated as an independent process and works as a WebtoB internal process. Thus, the function does not start with main() but with Service Name. Service Name must be the starting name of the function and must be registered in the WebtoB environment file. Refer to "9.3. Environment Configuration" for more information.
In order to use WBAPI in WebtoB, WebtoB environment configuration and some programming are required. I.e., In the WebtoB environment configuration file, register the program's development by using WBAPI and how the program will be used.
The following is an example of the WebtoB environment file. The bolded sections are the basic configuration needed to use WBAPI.
*DOMAIN webtob1 *NODE webmain WebtoBDir = "/usr/local/webtob", SHMKEY = 99000, Docroot = "/usr/local/webtob/docs", AppDir = "/usr/local/webtob/ap", Hostname = "webmain.tmax.co.kr", Port = "8080", JsvPort = 9099 *SVRGROUP cgig NodeName = webmain, SvrType = CGI jsvg NodeName = webmain, SvrType = JSV ssig NodeName = webmain, SvrType = SSI wbapg NodeName = webmain, SvrType = WEBSTD *SERVER cgi SvgName = cgig, MinProc = 10, MaxProc = 10 ssi SvgName = ssig, MinProc = 2, MaxProc =2 jsv1 SvgName = jsvg, MinProc = 10, MAXProc = 10 webaps SvgName = wbapg, MinProc = 5, MAXProc = 5 *SERVICE write_board SvrName = webaps *URI uri1 Uri ="/svct/", SvrType = WEBSTD, SvrName = webaps
SVRGROUP section
Configure a server group named wbapg in the host machine named webmain. The following example specifies the WEBSTD server type to use WBAPI.
wbapg NodeName = webmain, SvrType = WEBSTD
SERVER section
The webaps server is defined as wbapg, which was defined in the SVRGROUP section.
webaps SvgName = wbapg, MinProc = 5, MaxProc = 5
The SVRGROUP and SERVER sections must have the same basic configuration. In most environments, the configuration is the same except for the host machine name. In order to use an actual service, each service must be configured.
SERVICE section
Register the program developed by WBAPI. The program name is same as the function name. Different from the C language style, the program developed by WBAPI generally starts with write_board(). Because the function starting name becomes the service name, the service name is used to register. Add the SERVICE section after the SERVER section.
*SERVICE write_board SvrName = webaps
URI section
Configure the URI section when using the service made by WBAPI. If a request begins with the specified URI, such as "/svct/", the request will be executed as a WBAPI service.
*URI uri1 Uri =”/svct/”, SvrType = WEBSTD, SvrName = webaps
In order to start WebtoB, compilation through wscfl is usually required. After compiling with wscfl, a service table must be created in order to use WBAPI. Create a table by using the wsgst command in the bin/ directory. If wsgst is executed, WebtoB creates a service table that has the _svctab.c extension in the specified path.
The following are description of how to use a service table by using the wsgst command.
Usage
$ wsgst [ -f binary WebtoB environment file name ]
Option | Description |
---|---|
[ -f binary WebtoB environment file name ] | WebtoB environment file used to create a service table. The default environment file is wsconfig. |
Example
The following is an example of using wsgst.
$ wsgst (References wsconfig by default) $ wsgst -f wsconfig2 (When using wscfl -o)
This completes the preparations necessary to use WBAPI. Compile the program implemented with WBAPI to generate an executable file and register it as shown in the previous example.
Programs developed by WBAPI use special libraries, service tables provided by WebtoB, and a C language library. During compilation, the libraries and service tables must be linked.
The following is an example of a makefile for compilation in UNIX/LINX.
#Makefile.common TARGET= webaps APOBJS= ap.o #hp 32bit CFLAGS = -Ae +DA1.1 +DD32 -O -I$(WEBTOBDIR) #hp 64bit #CFLAGS = -Ae +DA2.0W +DD64 +DS2.0 -O -I$(WEBTOBDIR) #sun 32bit #CFLAGS = -O -I$(WEBTOBDIR) #sun 64bit #CFLAGS = -xarch=v9 -O -I$(WEBTOBDIR) #Linux #CFLAGS = -O -I$(WEBTOBDIR) #ibm 32bit #CFLAGS = -q32 -O -I$(WEBTOBDIR) -brtl #ibm 64bit #CFLAGS = -q64 -O -I$(WEBTOBDIR) -brtl WEBTOB_INCDIR = $(WEBTOBDIR)/usrinc WEBTOB_BINDIR = $(WEBTOBDIR)/bin WEBTOB_LIBDIR = $(WEBTOBDIR)/lib OBJS = $(APOBJS) $(SVCTOBJ) SVCTOBJ = $(TARGET)_svctab.o .SUFFIXES : .v .c.o: $(CC) $(CFLAGS) -c $< wbaps: $(APOBJS) svct $(CC) $(CFLAGS) -L$(WEBTOB_LIBDIR) -o $(TARGET) $(OBJS) $(LIBS) $(USERLIBS) svct: cp $(WEBTOBDIR)/svct/$(TARGET)_svctab.c . $(CC) $(CFLAGS) -I$(WEBTOB_INCDIR) –c $(TARGET)_svctab.c
The following is example of a makefile for Windows.
#Makefile for Windows TARGET = webaps.exe LIBS = /link $(WEBTOBDIR)\lib\aps.lib ws2_32.lib CFLAGS = /D _DEBUG /I $(WEBTOBDIR) /Gd /MD /nologo APOBJ = $(TARGET:.exe=.obj) SVCTSRC = $(TARGET:.exe=_svctab.c) SVCTOBJ = $(TARGET:.exe=_svctab.obj) OBJS = $(APOBJ) $(SVCTOBJ) $(TARGET): svct $(OBJS) cl $(CFLAGS) -o $@ $(OBJS) $(LIBS) copy $@ $(WEBTOBDIR)\ap svct: copy $(WEBTOBDIR)\svct\$(SVCTSRC) clean: -del $(OBJS) $(TARGET)
After preparations for WBAPI have been completed, WebtoB and the programs developed by WBAPI start up and load into memory as process type.
CGI conversion is a function of WBAPI. WBAPI can be used to convert existing CGIs, to develop new applications, and may prove useful for developers accustomed to C programming. WebtoB will continue to support and improve WBAPI to eliminate scalability or compatibility problems.
In addition, It is possible to use service functions provided by an existing TP-Monitor through WBAPI.
WBAPI consists of INIT/DONE, ALLOC, GET, PUT/SET, SEND, COOKIE, SESSION, and ETC. This section gives a simple description of each API and its functions.
Functions in the INIT/DONE API execute the initialization/termination routines that must be called before starting/terminating a service process.
The following is a list of INIT/DONE functions.
Function name | Description |
---|---|
wbSvrInit() | Initializes the server. |
wbSvrDone() | Notifies WebtoB that the service is complete. |
Functions in the ALLOC API allocate and deallocate user memory.
The following is a list of ALLOC functions.
Function name | Description |
---|---|
wbMalloc() | Allocates the user specified amount of memory. |
wbFree() | Deallocates the memory allocated by wbMalloc(). |
Functions in the GET API read user information from a user request such as request data and method values.
The following is a list of GET API functions.
Function name | Description |
---|---|
wbGetAuthType() | Extracts user authentication type. |
wbGetContentLength() | Extracts the size of the content sent by the client. |
wbGetDocumentRoot() | Extracts the WebtoB Home directory. |
wbGetHdr() | Extracts the value of a specific key from the request header. |
wbGetDateHdr() | Extracts the data header. |
wbGetIntHdr() | Extracts the specified header value as an integer. |
wbGetNthHdr() | Extracts the nth header value. |
wbGetHdrCount() | Extracts the total number of headers of the request sent by the user. |
wbGetData() | Extracts the value of the key from the request data field. |
wbGetNthKey() | Extracts the nth key data from the request. |
wbGetNthData() | Extracts the nth piece of data from the request data. |
wbGetDataCount() | Extracts the number of pieces of data entered from the request. |
wbGetValue() | Extracts the nth piece of data of a specific key value from the request. |
wbKeyOccur() | Extracts the number of key values from the request data. |
wbGetMethod() | Reads the HTTP method as an integer from the request. |
wbGetParsedURI() | Extracts the URI information of the request from the client. |
wbGetPathInfo() | Extracts the relative path information from the request. |
wbGetPathTranslated() | Extracts the absolute path information from the request. |
wbGetQueryString() | Extracts a query string from the request URL. |
wbGetProtocol() | Extracts the protocol information from the request. |
wbGetRemoteUser() | Extracts the user name who sent the request. |
wbGetRequestURI() | Extracts the request URI. |
wbGetRemoteAddr() | Extracts the remote host IP of the requestor. |
wbGetRemoteHost() | Extracts the remote host name of the requestor. |
wbGetRemoteIdent() | Extracts the user names found from the server. |
wbGetReqLine() | Extracts the first line pointer of the request. |
wbGetFileName() | Extracts the file name. |
wbGetFileLen() | Extracts the file size. |
wbGetScheme() | Extracts the protocol information of the requested service. |
wbGetScriptFileName() | Extracts the absolute path where the requested WBAPI service is executed. |
wbGetScriptName() | Extracts the path where the requested service is executed. |
wbGetServerName() | Extracts the server’s host name. |
wbGetServerPort() | Extracts the server’s port number. |
wbGetServerSoftware() | Extracts the server's software information. |
wbGetTranslatedURI() | Extracts the actual path by analyzing the requested service URI. |
wbGetRequestURL() | Extracts the request URL value. |
Functions in the PUT/SET API are used to respond to user requests. The functions, similar to printf in C or print script in Perl, output data processed by WBAPI.
In WBAPI, once a request is processed, the results are stored in a structure called WBSVCINFO. The structure is then returned to the web browser. PUT/SET API functions store the data in WBSVCINFO.
The call order of PUT API must be followed for WBAPI to run properly.
There are the functions that must be called prior to other PUT functions.
wbSetStatus (WBSVCINFO *rqst, int status, char *status_msg) must be called prior to calling any function so a response header can be generated.
Likewise, PUT API functions that create headers must be called before functions that create data fields.
The following is a list of PUT/SET functions.
Function name | Description |
---|---|
wbPutHdr() | Sets a response header. |
wbPutIntHdr() | Adds a response header. |
wbSetStatus() | Sets the status value of the request. |
wbPutStr() | Outputs a string value. |
wbPut() | Outputs user specified sized data. |
wbPrint() | Outputs user specified content. |
wbPutFile() | Function for downloading files. Reads a file and sends it to the web browser. |
wbPutPartialFile() | Function for downloading files. Reads a part of a file and sends it to the browser. File is read starting from offset up to the specified size. If specified size is 0, the entire file is read. |
Functions in the SEND API respond to user requests. Service processing results that are stored in WBSVCINFO structure using PUT API functions. The results are then returned to the browser using SEND API functions.
The following is a list of SEND functions.
Function name | Description |
---|---|
wbFlush() | Writes everything in the buffer. |
wbSendError() | Checks for errors in the status code. |
wbSendRedirect() | Returns the response to the specified address. |
wbReturn() | Notifies whether WebtoB is returned. |
Functions in the COOKIE API create, read, and process HTTP style cookies.
The following is a list of COOKIE functions.
Function name | Description |
---|---|
wbCreateCookie () | Creates a new cookie. |
wbGetCookie() | Returns a cookie from a list of cookies sent by the web browser. |
wbPutCookie() | Adds a response to the specified cookie. |
wbCookieGetDomain () | Returns a domain from the specified cookie. |
wbCookieGetName() | Returns the specified cookie name. |
wbCookieGetPath() | Returns the cookie path. |
wbCookieGetValue() | Returns the cookie value. |
wbCookieGetVersion() | Returns the cookie version. |
wbCookieSetComment() | Configures the cookie comment field. |
wbCookieSetDomain() | Configures a cookie's domain. |
wbCookieSetMaxAge() | Configures a cookie's lifespan. |
wbCookieSetPath() | Configures a path for the cookie. |
wbCookieSetSecure() | Decides whether the cookie should be sent in a secure protocol such as SSL. |
wbCookieSetValue() | Configures a new value in the cookie. |
wbCookieSetVersion() | Configures a new version of the cookie. |
Functions in the SESSION API create sessions and retrieve session data.
The following is a list of SESSION functions.
Function name | Description |
---|---|
wbGetRequestedSessionId() | Extracts the session ID from a user request |
wbGetSession() | Creates a session and retrieves the session value, if no session was created. |
wbIsRequestedSessionIdValid() | If the requested session is valid and is currently being used, extracts the true value. |
wbSessionGetId() | Extracts the unique ID allocated to the session. |
wbSessionGetValueNames() | Extracts the array that includes all object names bound to the session. |
wbSessionGetCreationTime() | Extracts the session creation time. |
wbSessionGetValue() | Extracts the object value and name bound to the session. |
wbSessionSetValue() | Binds the object value and name specified in the session. |
wbSessionIsNew() | Extracts the value that shows whether the session is new or not. |
wbSessionRemoveValue() | Deletes the object bound to the specified name. |
WbSessionInvalidate() | Invalidates the session. |
wbSessionGetMaxInactiveInterval() | Extracts the session maintenance time specified in the session. |
wbSessionSetMaxInactiveInterval() | Configures the session maintenance time for the specified session. |
wbSessionGetLastAccessTime() | Extracts the time when client sent the last request. |
WBAPI will provide multi-thread functions in the future. For this, a specific data structure must be declared in each function. If a WBAPI program is written first, the service name is registered. At the time the program is registered, the structure WBSVCINFO is declared. WBSVCINFO must be declared in the head of each WBAPI function. All WBAPI functions in a program must have a structure with the service name declared as the first argument.
This section describes how WBAPI is used to convert existing CGI programs.
The following is an example of implementing a simple bulletin board with CGI.
#include "qDecoder.h" int strcheck(char *str) { if (str == NULL) return 0; if (strlen(str) == 0) return 0; return 1; } int main(void) { char *name, *title, *doc; char *email, *homepage; /* Get input values */ name = qValue("writer"); title = qValue("title"); doc = qValue("doc"); email = qValue("email"); homepage = qValue("homepage"); /* Check if input values are valid */ if (!strcheck(name)) qError("Enter a name."); if (!strcheck(title)) qError("Enter a title."); if (!strcheck(doc)) qError("Enter a body."); if (strcheck(email)) if (!qCheckEmail(email)) qError("Enter a valid E-Mail address."); if (strcheck(homepage)) if (!qCheckURL(homepage)) qError("Enter a valid Homepage URL."); /* Output result – Input check */ qContentType("text/html"); printf("<HTML>\n\n"); printf("<HEAD><TITLE>Bestbook bulletin board – Post check</TITLE></HEAD>\n\n"); printf("<BODY>\n"); printf("<H2> Bestbook bulletin board - Post check </H2>\n"); printf("<HR WIDTH=600 ALIGN=left>\n<BR>"); if (strcheck(email)) printf("<A HREF=\"mailto:%s\">%s</A>", email, name); else printf("%s", name); if (strcheck(homepage)) printf("<SMALL>(<A HREF=\"%s\">%s</A>)</SMALL>", homepage, homepage); printf("You posted as follows.<BR><BR>\n"); printf("<TABLE WIDTH=600 BORDER=1>\n"); printf("<TR><TD><B>Title</B> : %s</TD></TR>\n", title); printf("<TR><TD>%s</TD></TR>\n", doc); printf("</TABLE>\n\n<BR>Posted in the board succssfuly.\n"); printf("</BODY>\n\n</HTML>"); qFree(); }
Most CGI program structures are simple. After performing a specific job based on the user input value sent through QUERY_STRING, the program returns the result via HTML. Making an HTML document is done through the printf function.
By default, several functions in the program are provided by C. The qValue function reads input values while the strcheck function checks the validity of a variable value. These functions are also supported by a simple library type.
The previous CGI program is analyzed as follows.
The CGI program uses variables named writer, title, doc, email, and homepage. These variables are user specified values. In the following program, the writer, title, doc, email, and homepage values are extracted from a request using the qValue function and set their respective CGI variables.
name = qValue("writer"); title = qValue("title"); doc = qValue("doc"); email = qValue("email"); homepage = qValue("homepage");
After extracting each variable value, verify the values were inputted to each variable by using the strcheck function.
if (!strcheck(name)) qError("Enter a name."); if (!strcheck(title)) qError("Enter a title."); if (!strcheck(doc)) qError("Enter a body."); if (strcheck(email)) if (!qCheckEmail(email)) qError("Enter a valid E-Mail address."); if (strcheck(homepage)) if (!qCheckURL(homepage)) qError("Enter a valid Homepage URL.");
If all the user variables sent to CGI are valid, all functions can be called successfully. Afterwards, the values must be posted onto the bulletin board and the output type must be made.
The following function shows that the output format supported by this CGI program is HTML.
qContentType("text/html");
Use the printf function to output the resulting value. This process similar to editing an HTML document.
The following example outputs HTML tags by using the printf function.
printf("<HTML>\n\n"); printf("<HEAD><TITLE>Bestbook bulletin board – Post check</TITLE></HEAD>\n\n"); printf("<BODY>\n"); printf("<H2> Bestbook bulletin board – Post check</H2>\n"); printf("<HR WIDTH=600 ALIGN=left>\n<BR>"); if (strcheck(email)) printf("<A HREF=\"mailto:%s\">%s</A>", email, name); else printf("%s", name); if (strcheck(homepage)) printf("<SMALL>(<A HREF=\"%s\">%s</A>)</SMALL>", homepage, homepage); printf("You posted as follows.<BR><BR>\n"); printf("<TABLE WIDTH=600 BORDER=1>\n"); printf("<TR><TD><B>Title</B> : %s</TD></TR>\n", title); printf("<TR><TD>%s</TD></TR>\n", doc); printf("</TABLE>\n\n<BR>Posted in the board succssfuly.\n"); printf("</BODY>\n\n</HTML>");
The following is a WBAPI program that has the same functionality and structure as a CGI program.
Values for each variable must be extracted.
A CGI program uses the qValue function but WBAPI uses the wbGetData function. wbGetData extracts each variable value.
writer = wbGetData(rqst, "writer"); title = wbGetData(rqst, "title"); doc = wbGetData(rqst, "doc"); email = wbGetData(rqst, "email"); homepage = wbGetData(rqst, "homepage");
Use strcheck to check the read values. The process is same as that of a CGI program.
WBAPI can read values from a header as well as read user environment variables. The following is done using the wbGetHdr function.
The following example reads the Content-Length value.
hd = wbGetHdr(rqst, "Content-Length");
After variable value extraction is complete, an output document must be made.
CGI programs use the printf function while WBAPI uses the wbPrint function. Each instance of the printf function in the CGI program can be replaced with wbPrint. While the resulting format may differ slightly, the differences are limited to HTML tags. There are no differences when making a bulletin board.
The header information made by printf in CGI program is made by using wbPutHdr in WBAPI. Use wbPrint for HTML content but use wbPutHdr for header content.
The following is an example of creating a header.
wbPutHdr(“ContentType”, text/html");
The following is an example of creating HTML tags.
wbPrint(rqst, "<HTML>\n\n"); wbPrint(rqst, "<HEAD> <TITLE> webtob Write Board </TITLE> </HEAD>\n\n"); wbPrint(rqst, "<BODY>\n"); wbPrint(rqst, "<H2> Bestbook</H2>\n"); wbPrint(rqst, "<H3>Writer is%s </H3> \n",writer); wbPrint(rqst, "<H3>Title is%s </H3> \n",title); wbPrint(rqst, "<HR>\n"); wbPrint(rqst, "<H2> %s </H2> \n",doc); wbPrint(rqst, "<H3> newvalue :%s%d</H3> \n",hd,rt); wbPrint(rqst, "<HR ALIGN=left>\n<BR>"); wbPrint(rqst, ".<BR><BR>\n"); wbPrint(rqst, "<TABLE WIDTH=600 BORDER=1>\n"); wbPrint(rqst, "</TABLE>\n\n<BR>.\n"); wbPrint(rqst, "</BODY>\n\n</HTML>");
After completing the HTML and header sections, instead of using return, use wbReturn to send the results to WebtoB.
wbReturn(rqst, WBSUCCESS);
WBSUCCESS within a parenthesis means the result was successful.