This chapter introduces the NetWare® Web Server environment and describes how you can create dynamic web pages for execution in this environment. It also describes the directory structure for the NetWare Web Server and explains how to configure the Web Server to access web pages.
The Common Gateway Interface (CGI) standard defines the interface between Web servers and other programs, such as applications and scripts, collectively called server extensions. CGI enables a web server to run such programs, which perform tasks in response to a user's request, enabling a Web server to interact with the user. Typically, CGI programs are used to create dynamic Web pages for a Web server to serve to a client. Such pages are dynamic because their contents may vary with each client request. Static web pages usually contain the same information each time a client requests them.
The NetWare Web Server supports two versions of CGI: the Remote Common Gateway Interface (RCGI) and the Local Common Gateway Interface (LCGI). Both are tailored to the NetWare operating system. RCGI scripts and applications can run on other platforms, in addition to the NetWare operating system. However, RCGI scripts and applications require dedicated sockets. In comparison LCGI applications, which must always be written as NLM programs, run more quickly, since they eliminate the need for sockets by executing as threads directly from the NetWare Web Server. However, LCGI applications are not portable.
When the NetWare Web Server receives a request from a client for a dynamic Web page, it uses server extensions to generate the requested pages. In addition, the server can also access CGI programs stored on a remote UnixWare®, SunOS*, or Solaris* host. For the NetWare Web Server to execute a remote CGI application or script the RCGI daemon must be installed and running on the remote host.
When you want your dynamic web page to run most efficiently on the NetWare operating system, you should write it as an LCGI NLM. The easiest way to explain why is by comparing how LCGI works on NetWare to how CGI works with a UNIX* HTTP server.
A UNIX HTTP server processes external requests by spawning the CGI program as a child process. A new process is spawned each time a client requests the CGI program. This system works efficiently in a UNIX environment, because UNIX caches file system access (even executables) based on use. If a CGI program has been used recently, it is likely to be loaded from cache rather than disk.
In the NetWare environment, LCGI NLMs are installed as Web Server parser/processor libraries. When the Web Server loads, it initializes and obtains a group of threads. When it receives a request for an LCGI NLM, it uses one of these pre-established threads to perform the required processing. It also loads the LCGI NLM if necessary. These installable NLMs behave as libraries to the Web Server.
Because of the overhead required to load a module in the NetWare environment, LCGI NLMs are loaded only once for many requests and not unloaded until the NetWare Web Server unloads. In addition, NetWare threads work more efficiently as reentrant functions than as multiload processes. When functions can remain resident in memory and be used in a reentrant fashion by many simultaneous requests, they can be literally twice as fast as their UNIX heavy-weight thread or process-oriented counterparts.
UNIX servers make client network file descriptors available to CGI programs by redirecting their standard I/O redirection facility for spawned processes. In the NetWare environment, there are no parent/child relationships between NLMs. The requesting client network file descriptors are available to the NLM because the requesting client's code is executing in the NLM context of the NetWare Web Server. This scheme does not require a complex method of passing file descriptors from process to process. Also, since parameter block memory is owned by the Web Server rather than the NLM, the Web Server can clean up resources and close client connections, rather than rely on the NLM to perform these critical tasks.
You can create dynamic web pages for publication on the NetWare Web Server by writing scripts or applications. RCGI supports applications (including NLMs) and BASIC and Perl scripts. LCGI supports only applications written as NLMs. You can use scripts and applications to perform any function supported by the platform on which they reside, such as searching a database, collecting and storing data submitted by users, displaying information about the server, or publishing data that changes frequently.
Click here to see a figure you can use to decide the best way to create your dynamic web page.
You can use a script to create dynamic web pages when the task your web page performs can be accomplished by simple programming statements. Scripts can retrieve data, perform operations, and create HTML documents. Scripts are executed by interpreters. The NetWare Web Server includes a Perl interpreter, a BASIC interpreter, and a NetBasic interpreter which are all NLMs.
The Perl and BASIC NLMs support most of the functions available in the standard Perl and BASIC scripting languages. These interpreters are RCGI NLMs. In addition to the NetWare operating system, RCGI scripts can execute on any platform that supports CGI using the RCGI daemon.
The NetBasic NLM supports most of the standard BASIC functions and provides many additional functions to support the creation of dynamic Web pages. The NetBasic interpreter is an LCGI NLM and therefore runs only on the local NetWare server.
For information on creating scripts in NetBasic, see NetBasic for Internet.
For more information about writing scripts in BASIC, see Creating BASIC Scripts.
For more information about writing scripts in Perl, see Creating Perl Scripts.
LCGI NLMs and RCGI applications can also create dynamic web pages. Such programs can be very useful when web pages require more complex operations than are feasible with scripting languages.
For more information about writing LCGI NLMs, see LCGI Functions, and Writing an LCGI NLM. For information on writing RCGI applications, see Writing an RCGI Application.
Every web page is identified by a Uniform Resource Locator (URL). A URL identifies the protocol, address, port number, and resource location of a file. If no port number is specified in the URL, the default port for Web activity is used. Click here to view a figure that shows a sample URL and its components.
Since many types of browsers exist for many types of platforms, a script or application needs information about the client in order to return data in the format the client can read. This information is contained in environment variables. Some variables are set by default, while others are set only when the client and server interact in particular ways. All information sent in a client request is assigned to an environment variable.
Before invoking a script or application, the Web Server initializes the environment variables. The script or application can then access any variables that are relevant to the operations it is performing. Refer to Using Environment Variable Names in Scripts for details about how scripts pass environment variables. Unlike RCGI, which accesses environment variables directly, LCGI passes environment variables in the Cgi_t data structure. Refer to LCGI Functions for details. Click here to view a complete list of server-specific environment variables.
When the NetWare Web Server is installed, most related files are placed into the WEB directory at the root level on the server. Click here to view a figure that shows the default directory structure used by the NetWare Web Server, beginning with the WEB directory. If you add subdirectories to the WEB directory or restructure the directory, you must set up new access controls and inform the server program about the new directory structure. For more information, consult the NetWare Web Server administration utility Windows help system.
The contents of each subdirectory in the WEB directory are as follows:
NetBasic scripts are stored outside the \WEB directory in the SYS:\NETBASIC\WEB directory with a .BAS file extension to indicate that the file contains a BASIC script. For example, a NetBasic script might have the name SEARCHDB.BAS.
When a NetWare Web Server receives a request, it checks its resource configuration file, SRM.CFG, to determine how to handle the request. Directives within the file map the URL in a request to the appropriate resource. If the resource is a script or an RCGI application, you must use the RemoteScriptAlias directive to map the URL to the appropriate script or application. If the requested resource is an LCGI NLM, use the LoadableModule directive.
SRM.CFG is located in the \WEB\CONFIG directory. The file can contain any number of RemoteScriptAlias and LoadableModule directive entries. If there are no LCGI NLMs to be invoked on the server, then no LoadableModule directive entry is required in the file. The same goes for scripts and RCGI applications, and the RemoteScriptAlias directive. Within this file, blank lines and comments (lines beginning with #) are ignored, and all other lines are treated as directives. All pathnames in this file are relative to the \WEB directory.
The RemoteScriptAlias directive enables Web Server to access a script or RCGI application. The syntax of the RemoteScriptAlias directive is as follows:
RemoteScriptAlias virtualpath host:port[directory]
virtualpath-the virtual path in the request URL.
host-the name for the host on which the RCGI script, application, daemon, or NLM resides.
port-the number of the port at which the RCGI server is expected to be listening on the host.
directory- the root directory of the script, application, daemon, or NLM to be executed by the RCGI server.
The following directive configures the BASIC interpreter on port 8001:
RemoteScriptAlias /scripts/ localhost:8001/scripts/
The BASIC interpreter must also be loaded on port 8001 on the local NetWare machine before a script can be executed.
The following URL requests that the BASIC interpreter execute the card.bas script.
http://www.webserver/scripts/card.bas
The following directive configures the Perl interpreter on port 8002:
RemoteScriptAlias /perl/ localhost:8002/sys:web/scripts/perl/
A user might type the following URL to request that the Perl interpreter execute the script cardSAMP.pl.
http://www.webserver/perl/cardsamp.pl
The following directive configures an NLM named cgiapp at port 8003 on the local host:
RemoteScriptAlias /cgiproc/ localhost:8003/sys:web/samples/cgiapp/
A user might type this URL to execute CGIPROC:
http://www.webserver/cgiproc/
The RCGI daemon is a service that enables you to run existing applications on a UNIX machine. Use the following directive to configure the daemon on port 8003:
RemoteScriptAlias /rcgid/ unixbox:8003
A user might type this URL to request the STOCKQ script on the UNIX machine:
http://www.webserver/rcgid/stockq?stock=novell
The syntax of the LoadableModule directive, used to specify an LCGI NLM, is
LoadableModule template result
where template is the logical path of the file or alias of the file and result is the physical path of the file. Some examples of LoadableModule directive entries are presented below.
LoadableModule /lcgi/ sys:web/lcgi/
In this example, URLs matching /lcgi/ become external process requests for NLMs in the sys:web/lcgi directory. A sample URL is
http://server_name/lcgi/testcgi.nlm
LoadableModule /test1/ sys:web/lcgi/cgisdk
In this example, cgisdk is the file name with or without the .nlm extension. The file name is not specified in the URL, and the URL will look like this
http://server_name/test1
LoadableModule /test2/ sys:web/lcgi/cgisdk.nlm
In this example, cgisdk.nlm is the file name with a .nlm extension. The file name is not specified in the URL, which looks like this
http://server_name/test2
LoadableModule /test3/ sys:web/lcgi
In this example, the file name is not specified in the LoadableModule directive. Therefore, the URL itself needs to specify the file name with or without the .nlm extension. The NLM is located in the SYS:/WEB/LCGI directory. The corresponding URL can have the following forms:
http://server_name/test3/cgisdk.nlm http://server_name/test3/cgisdk http://server_name/test3/cgisdk1.nlm/path_info http://server_name/test3/cgisdk1/path_info
As scripts allow users to run processes on your server, it is important to control access to the script directories and implement proper security measures for all scripts on your server. Implement the following measures to ensure security:
RCGI and LCGI have two different request processes. When a client, such as a web browser, requests a dynamic Web page, the server uses RCGI to call a server extension. The RCGI extension is always loaded on a socket and awaiting a request from the Web Server. The extension creates the HTML page, which sends its output to the server, which in turn sends it to the client.
When the server receives a request from a client that invokes a Perl or a BASIC script, it sends the accompanying data to the Perl or BASIC NLM. Perl and BASIC reference request data differently. Click here to view a table that lists the four types of request data that can be sent by the client and the corresponding references in Perl and BASIC.
When the NetWare Web Server receives an HTTP request for an LCGI server extension, it processes the request as follows:
The remainder of this section discusses the parts of this process that are unique to LCGI.
The NetWare Web Server provides a special method to restrict access to LCGI programs, such as NetBasic and NDS Object Browser. To restrict access to LCGI programs, create an ACCESS.WWW file in the directory where the LCGI program resides. When a user requests an LCGI server extension in this directory, he will be prompted for a userid and password.
It is important to note, once a user is authenticated to use the NetBasic LCGI extension, full access to all available NetBasic scripts is allowed. You cannot selectively place access control on different NetBasic scripts.
Refer to the User Access Control section of the RELEASE.HTM file for details on how to set up the ACCESS.WWW file.
Once the Web Server determines that the request is for an extension NLM and identifies the NLM, it checks to see if the NLM is already registered. If the module is not registered, the Web Server gets a thread and loads the NLM. The NLM begins executing its main routine. The main routine
Once the main routine performs these functions, it suspends itself.
When the Web Server calls an unregistered extension NLM, it loads the NLM which calls its main routine. One function of the main routine is to register the extension NLM with the Web Server. When an extension NLM registers, it provides the Web Server with the RequestHandler and UnloadHandler function addresses. The RequestHandler address defines the entry point for processing requests. The UnloadHandler address defines the entry point for the unload routine.
There are various phases and methods of passing data to an NLM from a client.
A typical URL referencing an LCGI NLM might look like this:
http://some.company.com/lcgi/process.nlm/other/path/info?query_data
The Web Server recognizes the first component of the path lcgi as a configured location for external processes because it was defined this way in the corresponding LoadableModule directive in SRM.CFG. It creates the appropriate path and scans the list of previously loaded and registered external processes. If it doesn't find the NLM by its search key (the full path of the external process in the NetWare file system), it loads the NLM and waits for a configurable timeout for the NLM to register itself with the Web Server. The registration process installs a callback function address into the Web Server along with a search key. The callback function is prototyped as follows:
int RequestHandler (struct Cgi_t *cgiInfo)
The address of this callback function is passed to the Web Server by registration and deregistration functions exported by the Web Server:
LONG CgiExtReg(CgiRequest fpReqHndlr, CgiUnload fpUnloadHndlr, LONG flag, LONG *cgiHandle)
LONG CgiExtDeReg(LONG cgiHandle)
CgiExtReg takes a function pointer of type CgiRequest, defined by
typedef LONG (*CgiRequest) (struct Cgi_t * cgiInfo);
The parameter flag contains bitmapped flags for specifying various options supported by the server, such as a non-parsed header. The CgiExtReg returns a cgiHandle parameter that is used by CgiExtDeReg to unregister the function. The same cgiHandle is also used by CgiMutexLock/CgiMutexUnlock to lock/unlock all threads running in the same LCGI NLM.
The Web Server uses the Cgi_t data structure to pass information to an LCGI NLM. The Cgi_t structure contains the following important information:
In a traditional UNIX-based HTTP server, the other/path/info component of the URL is passed as a name =value pair in an environment variable created by the server before spawning the child process. In the LCGI environment, the queue head of environment variables are defined in Cgi_t, and they can be expanded easily by the LCGI NLM by calling the CgiEnvPut function.
The LCGI NLM must return information to the Web Server. This interface handles parsed-header, as well as, non-parsed-header style external processes. The Web Server's registration function accepts a flag that indicates whether an NLM is using a parsed or non-parsed header. The Web Server stores this information with a callback function for the NLM, noting this stream handling requirement each time it calls the NLM's callback function.