Delphis Web Broker Technology

The CGI and ISAPI code snippets I've shown you so far demonstrate the plain, direct approach to the protocol and API. Extending these examples at that level is certainly possible, but what is interesting in Delphi is to use the WebBroker technology. This comprises a class hierarchy within VCL and CLX, built to simplify server-side development on the Web, and a specific type of data modules, called WebModules. Both the Enterprise and Professional editions of Delphi 5 include this framework (differently from the more advanced and newer WebSnap framework, which is available only in the Enterprise version of Delphi 6).

Using the WebBroker technology, you can begin developing an ISAPI or CGI application or an Apache module very easily. On the first page (New) of the New Items dialog box, select the Web Server Application icon. The subsequent dialog box will offer you options (two more than in Delphi 5). As you can see in Figure 22.2, you can choose ISAPI, CGI, WinCGI, Apache module, and the Web App Debugger.

FIGURE 22.2:

The alternative options for building a Web server application in Delphi

New Web Server Application

You may select from one of the following types of World Wide Web server applications.

CGI Stand-alone executable Win-CGI Stand-alone executable C Apache Shared Module [DLL] C Web App Debugger executable

CoClass Name: I

Cancel

Help

Tip As a starting point for your server-side application, you can also use the DB Web Application

Wizard, available in the Business page of the New Items dialog box. This wizard generates a program with a BDE table or query connected to a DataSetTableProducer. It can be helpful, but the generated code is really very limited and there is no support for Apache and the Web App Debugger.

For example, if you select the first option, Delphi will generate the basic structure of an ISAPI application for you. The application that Delphi generates (no matter which type you choose) is based on the TWebModule class, a container very similar to a data module. The WebModule code is similar to that of a data module, as we'll see in a moment, but the code of the library is worth looking at: library Projectl;

uses

WebBroker,

ISAPIThreadPool,

ISAPIApp,

Unitl in 'Unitl.pas' {WebModulel: TWebModule}; {$R *.RES}

exports

GetExtensionVersion,

HttpExtensionProc,

TerminateExtension;

begin

Application.Initialize; Application.CreateForm(TWebModulel, Application.Run; end.

WebModulel);

Warning This code changes slightly between Delphi versions. If you have older code around, you'll need to refer to the WebBroker unit instead of the previous HTTPApp unit. Delphi 6 adds the reference to the ISAPIThreadPool unit, which provides support for pooling threads under ISAPI (with a couple of classes not documented in the Help file).

Although this is a library that exports the ISAPI functions, the code looks similar to that of an application. However, it uses a trickā€”the Application object used by this program is not the typical global object of class TApplication but an object of a new class. This new Application object is of class TISAPIApplication (or TCGIApplication if you've built that type of application), which derives from TWebApplication.

Although these application classes provide the foundations, you won't use them very often (just as you don't use the Application object very often in a form-based Delphi application). The most important operations take place in the WebModule. This component derives from TCustomWebDispatcher, which provides support for all the input and output of our programs.

In fact, the TCustomWebDispatcher class defines Request and Response properties, which store the client request and the response we're going to send back to the client. Each of these properties is defined using a base abstract class (TWebRequest and TWebResponse), but an application initializes them using a specific object (such as the TISAPIRequest and TISAPIRe-sponse subclasses). These classes make available all the information passed to the server, so you have a single, simple approach to accessing all the information. The same is true of a response, which is very easy to manipulate. One advantage to this approach is that an ISAPI DLL written with this framework is very similar to a CGI application; in fact, they are frequently identical in the source code you write.

If this is the structure of Delphi's framework, how do you write the application code? Well, in the WebModule, you can use the Actions editor (shown in Figure 22.3) to define a series of actions (stored in the Actions array property) depending on the pathname of the request. This pathname is a portion of the CGI or ISAPI application's URL, which comes after the program name and before the parameters, such as path1 in the following URL:

http://www.example.com/scripts/cgitest.exe/path1?param1=date

By providing different actions, your application can easily respond to requests with different pathnames, and you can assign a different producer component or call a different OnAction event handler for every possible pathname. Of course, you can omit the pathname to handle a generic request. Consider also that, instead of basing your application on a WebModule, you can use a plain data module and add a WebDispatcher component to it. This is a good approach if you want to turn an existing Delphi application into a Web server extension.

FIGURE 22.3:

The Actions property editor of the WebModule, along with the properties of one of the actions in the Object Inspector

FIGURE 22.3:

The Actions property editor of the WebModule, along with the properties of one of the actions in the Object Inspector

Warning The WebModule incorporates the WebDispatcher and doesn't require it as a separate component. Unlike WebSnap applications, in fact, WebBroker programs cannot have multiple dispatchers or multiple Web modules. Notice also that the actions of the WebDispatcher have absolutely nothing to do with the actions stored in a TActionList component.

When you define the accompanying HTML pages that launch the application, the links will make page requests to the URLs for each of those paths. Having one single ISAPI DLL that can perform different operations depending on a parameter (in this case, the pathname) allows the server to keep a copy of this DLL in memory and respond much faster to user requests. The same is partially true for a CGI application: The server has to run several instances but can cache the file and make it available faster.

The OnAction event is where you put the code to specify the response to a given request, the two main parameters passed to the event handler. Here is a simple example:

procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin

Response.Content :=

'<html><head><title>Hello Page</title></head><body>' + '<h1>Hello</h1>' +

<hr><p><i>Page generated by Marco</i></p></body></html>';

end;

The Content property of the Response parameter is where you enter the HTML code that you want users to see. The only drawback of this code is that the output in a browser will be correctly displayed on multiple lines, but looking at the HTML source code, you'll see a single line corresponding with the entire string. To make the HTML source code more readable, by splitting it up onto multiple lines, you can insert the #13 newline character.

To let other actions handle this request, you'll set the last parameter, Hand1ed, to False. Otherwise, the default value is True, and once you've handled the request with your action, the WebModule assumes you're finished. Most of an ISAPI application's code will be in the OnAction event handlers for the actions defined in the WebModule container. These actions receive a request from the client and return a response using the Request and Response parameters.

When using the producer components, your OnAction event often returns, as Response.Content, the Content of the producer component, with a simple assignment. You can shortcut this code by assigning a producer component to the Producer property of the action itself, with no need to write these simple event handlers anymore (but don't do both things, as that might get you into trouble).

As an alternative to the Producer property, you can use the ProducerContent property introduced in Delphi 6. This new property allows you to connect custom producer classes that don't inherit from the TCustomContentProducer class but implement the IProduceContent interface. The ProducerContent property is almost an interface property: It behaves in the same way, but thanks to its property editor and not based on the new support for interfaced properties of Delphi 6.

Was this article helpful?

0 0
Self Publishing a Book The Easy Way

Self Publishing a Book The Easy Way

This comprehensive guide will present you with a variety of self-publishing options and explore their viability. Well take a look at all types of books and book-delivery systems.

Get My Free Ebook


Responses

  • clyde
    How to use webdispatcher component delphi?
    9 years ago
  • belladonna
    Can an android connect to delphi websnap server?
    7 years ago

Post a comment