Lesson 3: Programming the Web Server

In Lesson 2, you were introduced to Microsoft's Web server applications: IIS 4.0 and PWS. You learned how to use these applications to organize and deploy content such as HTML pages and ActiveX documents on a Web site.

In this lesson you will learn how to write programs that extend the functionality of a Microsoft Web server using ISAPI. You will learn about two types of programs: ISAPI server extensions and ISAPI filters, both of which are implemented as DLLs. ISAPI server extensions are programs that run within the Internet server process. ISAPI filters intercept data travelling to and from the server, and thus can perform specialized logging, encryption and other tasks.

After this lesson, you will be able to:

  • Describe how to create an ISAPI server extension using MFC.
  • Describe how to make an ISAPI server extension generate customized content based on parameters submitted from an HTML form.
  • Describe how to create an ISAPI filter using MFC.
  • Describe how to install an ISAPI filter.
Estimated lesson time: 30 minutes

ISAPI Server Extensions

An ISAPI server extension is a server-side program that runs in response to requests from a Web browser. A server extension is implemented as a DLL, which is loaded by IIS. The browser can run the program by specifying the name of the .dll file in a URL like this:

http://myserver/apps/charts.dll

The ISAPI server extension implements functions that can be called by the browser. To call a function, you append the function name to the URL as follows:

http://myserver/apps/charts.dll?GetChart

This example references the charts.dll server extension and calls the GetChart() function. All ISAPI server extensions must define a default function that is called if the client does not specify a function. Server extension functions can take parameters, which can be specified in the URL as follows:

http://myserver/apps/charts.dll?GetChart?Fund=ARSC

An ISAPI server extension can be linked to an HTML form by assigning the extension's URL to the action attribute inside a <FORM> tag, as follows:

<FORM action="myextension.dll?GetColor" method=POST> <!— form controls go here —> </FORM>

Values that the user enters into the form's controls are automatically passed as parameters to the ISAPI server extension when the user submits the form. ISAPI server extension functions typically send back customized HTML code based on these parameter values.

ISAPI server extensions are based on the Common Gateway Interface (CGI) standard. CGI is part of the HTTP, which was developed as a way to allow browser programs to interact with scripts or separate executable programs running on a Web server. Without altering the HTTP/CGI specifications, Microsoft developed IIS to allow any browser to load and run a server extension DLL. Because DLLs run as part of the process that loads them, server extensions are faster than scripts that might need to load separate executable programs.

CGI shifts the programming burden to the server. Using CGI parameters, the browser sends small amounts of information to the server. The server can do absolutely anything with this information, including access a database, generate images, and control peripheral devices. The server sends a file (HTML or otherwise) back to the browser, which can be read from the server's disk or generated by the program.

Creating an ISAPI Server Extension Using MFC

To see a basic ISAPI server extension in action, you will now use the MFC ISAPI Extension Wizard to create one of your own.

  • To create the MyExtension ISAPI server extension DLL
    1. On the File menu in Visual C++, click New. On the Projects page of the New dialog box, click ISAPI Extension Wizard. Enter MyExtension as a project name and click OK.
    2. The ISAPI Extension Wizard appears as shown in Figure 12.19.
    3. click to view at full size.

      Figure 12.19 The ISAPI Extension Wizard

    4. Click Finish to accept the default settings, and then click OK to create the project.
    5. Build the project to create the MyExtension.dll ISAPI server extension.
    6. Using Windows Explorer, create a new folder under the \InetPub\WWWRoot folder named MyISExtensions. Place a copy of the MyExtension.dll file in this folder.
    7. Using your Web server management program, create a virtual directory beneath your Web site's home directory, and name it apps. Specify that the content from this directory will be placed in the C:\INetPub\WWWRoot\MyISExtensions folder. Make sure that you allow Execute access to this directory.
    8. Start Internet Explorer and enter the following URL into the Address box:
    9. http://[your computer name]/apps/myextension.dll

      This request will call the default function of MyExtension.dll. The output of this should appear in the browser as shown in Figure 12.20.

      click to view at full size.

      Figure 12.20 Internet Explorer 5 displaying output from MyExtension.dll

    Examining the MyExtension Code

    If you look at the source code in the MyExtension project, you will see that the ISAPI Extension Wizard has created a single class for you named CMyExtensionExtension. This class is derived from the MFC base class CHttpServer. You can add member functions to this class to implement the functions exported by the DLL.

    MFC provides a code construct called a parse map to define the DLL functions and map them to member functions of your CHttpServer-derived class. The parse map is declared in the header file with the DECLARE_PARSE_MAP macro, and implemented with BEGIN_PARSE_MAP and END_PARSE_MAP macros, as shown in the following example from your MyExtension.cpp file:

    BEGIN_PARSE_MAP(CMyExtensionExtension, CHttpServer)      // TODO: insert your ON_PARSE_COMMAND() and      // ON_PARSE_COMMAND_PARAMS() here to hook up your commands.      // For example:      ON_PARSE_COMMAND(Default, CMyExtensionExtension, ITS_EMPTY)      DEFAULT_PARSE_COMMAND(Default, CMyExtensionExtension) END_PARSE_MAP(CMyExtensionExtension)

    You can see that the ISAPI Extension Wizard has added the DEFAULT_PARSE COMMAND macro to specify the name of the default function as Default(). The Wizard provides a simple implementation of this function that can be found further down the file:

    void CMyExtensionExtension::Default(CHttpServerContext* pCtxt) {      StartContent(pCtxt);      WriteTitle(pCtxt);      *pCtxt << _T("This default message was produced by the Internet");      *pCtxt << _T("            Server DLL Wizard. Edit your CMyExtensionExtension::Default()");      *pCtxt << _T(" implementation to change it.\r\n");      EndContent(pCtxt); }

    The output from this function is shown in Figure 12.20.

    The Default() function, like all ISAPI extension functions, takes a pointer to a CHttpServerContext object. One CHttpServerContext object is created by CHttpServer for each HTTP client/server transaction. As the server extension DLL processes requests, it uses CHttpServerContext member functions to perform tasks such as retrieving details contained in the header of the HTTP client request (using CHttpServerContext::GetServerVariable()), or inserting HTML text into the response file that is sent back to the client (using the overloaded << operator).

    The server extension's CHttpServer object creates a CHttpServerContext object for each client request. Each object is created on a separate thread to allow multiple simultaneous calls to the CHttpServer object by different client connections. You must be careful to perform synchronization for global variables, or for any data members of your CHttpServer class.

    Adding a Function to Your Server Extension

    You will now add a simple function named GetColor() to your ISAPI server extension. GetColor() takes any one of the HTML color names as a parameter and generates a page with an appropriately colored background.

  • To add the GetColor() function
    1. Add the following lines to the Parse Map in the MyExtension.cpp file:
    2. ON_PARSE_COMMAND(GetColor, CMyExtensionExtension, ITS_PSTR) ON_PARSE_COMMAND_PARAMS("color")

      The ON_PARSE_COMMAND macro specifies the name of the function—the class name to map the function to. The parameters received by the function are specified as the third (and subsequent) parameters of the ON_PARSE_COMMAND macro. The parameter types are specified by the ON_PARSE_COMMAND_PARAMS macro. The lines in the example just shown specify that the GetColor() function will have a single string parameter named color.

    3. Use the ClassView Add Member Function feature to add a function with the following signature to the CMyExtensionExtension class:
    4. void GetColor(CHttpServerContext *pCtxt, LPCTSTR pstrColor)

    5. Implement the function as follows:
    6. void CMyExtensionExtension::GetColor(CHttpServerContext *pCtxt, LPCTSTR pstrColor) {      StartContent(pCtxt);      WriteTitle(pCtxt);      *pCtxt << _T("You have chosen the ");      *pCtxt << pstrColor << _T(" page.\r\n");      *pCtxt << _T("<SCRIPT language=\"JavaScript\">            document.bgColor = \"");      *pCtxt << pstrColor << _T("\" </SCRIPT>\r\n");      EndContent(pCtxt); }

    7. Build and run the MyExtension project. You will need to copy the new DLL to the \INetPub\WWWRoot\MyISExtensions folder so that it replaces the previous version. Before you can do this, you will have to stop the Web (WWW) service on your computer. This is because ISAPI server extension DLLs are loaded into the IIS process when a client first requests them, and stay loaded until the WWW service is stopped. The easiest way to stop the WWW service on a computer using IIS is to open a system command prompt and type the following:
    8. net stop w3svc

    9. After you have copied the DLL, restart the service by typing the following:
    10. net start w3svc

      The revised DLL will be loaded at the first client request.

      On a computer running Windows 95 or Windows 98, you can stop and start the Web service from the Properties menu of the Personal Web Manager. To gain access to the DLL, you might have to restart your computer after stopping the service.

      The following HTML document called Form.htm allows you to test your new extension function. This document implements a simple form that allows the user to pick a color from a drop-down list box. The user clicks a Submit button to retrieve a page of the chosen color from the server.

      <!-- Form.htm --> <HTML> <HEAD>      <TITLE>           Color Form      </TITLE> </HEAD> <BODY>      <H3> Choose a color from the list box and click SUBMIT</H3>      <FORM action="myextension.dll?GetColor" method=POST>      <SELECT name="color">           <option> pink           <option> green           <option> yellow           <option> blue      </SELECT>      <P>      <input type="submit">      </FORM> </BODY> </HTML>

      Form.htm can be found in the Chapter 12\Exercises folder. Place a copy of Form.htm in the \INetPub\WWWRoot\MyISExtensions folder.

    11. Start Internet Explorer and enter the following URL into the address box:
    12. http://[your computer name]/apps/form.htm

      You will see the page appear as shown in Figure 12.21.

      click to view at full size.

      Figure 12.21 Form.htm displayed in Internet Explorer 5

    13. Select a color from the list box and click Submit Query. A page with the background color you have chosen will be returned to your browser.

    ISAPI Filters

    ISAPI filters sit between the network connection to the clients and the HTTP server. They can be used to enhance Internet servers with custom features such as the enhanced logging of HTTP requests or custom encryption and compression schemes, or to implement alternative authentication methods. Filters are implemented as DLLs that are loaded when the WWW service is started. You can use the Internet Service Manager to assign filters to your IIS 4.0 Web sites. Personal Web Server does not support ISAPI filters.

    Filters can be set to receive notification when selected server events occur. For example, the server might notify the filter that it is processing raw data from a client request, or that it is sending data to the client, or that it has just written to the log or closed a transaction. As the filter processes these notifications, it has access to the server data related to the notification event. For example, a filter that is notified that the server is sending raw data to the client has access to the data being sent so that the filter can modify the data, perhaps applying a compression or encryption algorithm.

    The following exercises demonstrate a simple ISAPI filter that is built using the ISAPI Extension Wizard.

  • To create the MyFilter ISAPI filter
    1. On the Projects tab of the New dialog box, click ISAPI Extension Wizard. Enter MyFilter as a project name and click OK.
    2. On the first screen of the ISAPI Extension Wizard, clear the Generate a Sever Extension object option and select the Generate a Filter object option.
    3. In Step 2 of the ISAPI Extension Wizard, select Incoming raw data and headers. Leave End of connection selected so that the dialog box looks as shown in Figure 12.22.
    4. click to view at full size.

      Figure 12.22 Creating an ISAPI filter

    5. Click Finish, and then click OK to create the MyFilter project.

    If you examine the generated code, you will see that the ISAPI Extension Wizard has created a single class CMyFilterFilter that is derived from the MFC class CHttpFilter. A handler function has been added to this class for each notification that you specified in Step 2 of the ISAPI Extension Wizard, as shown in this extract from the CMyFilterFilter class definition:

    virtual DWORD OnReadRawData(CHttpFilterContext* pCtxt,       PHTTP_FILTER_RAW_DATA pRawData); virtual DWORD OnEndOfNetSession(CHttpFilterContext* pCtxt);

    These functions are overloaded versions of CHttpFilter member functions. The Wizard provides stub functions in the .cpp file. You define your filter behavior by implementing these functions.

    Note that another overloaded function, GetFilterVersion(), is implemented for your class. This function is called by the server to learn which notifications the filter will handle. To make the filtering process more efficient, the server sends notifications only for the events specified in this function. The following line from the MyFilter::GetFilterVersion() function shows how to specify the events:

    pVer->dwFlags |= SF_NOTIFY_ORDER_LOW | SF_NOTIFY_SECURE_PORT |       SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_READ_RAW_DATA |       SF_NOTIFY_END_OF_NET_SESSION;

    Be aware that if you add handler functions for additional notification events, you must also add the corresponding flags to this line. Although you can use ClassWizard to add notification event handler functions, ClassWizard does not update the GetFilterVersion() function for you, so you must remember to do this manually.

    Notification handler functions receive data structures that contain information about the event they are handling. They also receive a pointer to a CHttpFilterContext object, which like the CHttpServerContext object, contains information about the current client connection and provides methods to retrieve information about the connection or to write data into the client response.

    In the following exercises, you will provide a simple implementation of the MyFilter::OnReadRawData() function. This will use the CHttpFilterContext:: GetServerData() function to retrieve the IP address of the remote server that is currently connected, and then write it to a log file.

  • To implement the MyFilter::OnReadRawData() function
    1. Locate the MyFilter::OnReadRawData() function and replace it with the following implementation:
    2. DWORD CMyFilterFilter::OnReadRawData(CHttpFilterContext* pCtxt, PHTTP_FILTER_RAW_DATA pRawData) {      char pchVar[64];      DWORD dwSize = 64;      CStdioFile logfile("C:\\iislog.txt",           CFile::modeCreate | CFile::modeWrite);      BOOL bRet = pCtxt->GetServerVariable(           "     REMOTE_HOST", pchVar, &dwSize);      if(bRet)           logfile.Write(pchVar, dwSize);      logfile.Close();      return SF_STATUS_REQ_NEXT_NOTIFICATION; }

    3. Build the MyFilter project. Copy the MyFilter.dll file to the c:\Winnt\System32\inetsrv folder.

  • To install the filter on an IIS 4.0 Server
    1. Open the Internet Service Manager. Right-click your local server icon (the icon is labeled with the name of your computer) and select Properties.
    2. In the Master Properties box, make sure the WWW Service option is selected and click Edit.
    3. In the WWW Service Master Properties dialog box, click the ISAPI Filters tab. This tab is shown in Figure 12.23.
    4. click to view at full size.

      Figure 12.23 Installing ISAPI filters on a Web server

    5. Click Add. Type MyFilter as the filter name. Use the Browse button to locate the MyFilter.dll file in the c:\Winnt\System32\inetsrv folder and enter the full path to the file into the Executable box.
    6. Click OK to close the WWW Service Master Properties dialog box, and then click OK again to close the Server Properties.
    7. Open a system command prompt and type:
    8. net stop w3svc

      followed by:

      net start w3svc

    9. Open Internet Explorer and browse to a page on your local server Web site—for example, the http://[your computer name]/apps/form.htm page from the previous exercises.
    10. Close Internet Explorer. If you look in the root directory of your c:\ drive you will find the iislog.txt file has been created. Double-click this file to view it in Notepad. You will see that the IP address of your computer has been added to the log file.

    Lesson Summary

    ISAPI allows you to write programs that extend the functionality of IIS 4.0 and its desktop counterpart, PWS.

    There are two types of ISAPI programs: server extensions and filters, both of which are implemented as DLLs. ISAPI server extensions are compiled server-side programs that can be launched by an Internet client request. ISAPI filters intercept data travelling to and from the server and thus can perform specialized logging, encryption and other tasks.

    ISAPI server extensions are based on the CGI standard and can be invoked from a URL by specifying the name of the DLL. Server extensions expose functions that can take parameters. You can specify the function name and parameter values as part of a URL, or you can connect the extension to an HTML form so that it receives parameters from the form controls. You use the ISAPI Extension Wizard to create a server extension project based around the CHttpServer and CHttpServerContext classes.

    ISAPI filters sit between the network connection to the clients and the HTTP server, and they add custom features such as enhanced logging or encryption and compression to your Internet server. The filter is implemented as a DLL that is loaded when the WWW service is started. You can use the Internet Service Manager to assign filters to your IIS 4.0 Web sites. PWS does not support ISAPI filters. Filters receive notification when selected server events occur. As the filter processes these notifications, it has access to the server data related to the notification event. You use the ISAPI Extension Wizard to create an ISAPI filter project based around the CHttpFilter and CHttpFilterContext classes.



    Microsoft Press - Desktop Applications with Microsoft Visual C++ 6. 0. MCSD Training Kit
    Desktop Applications with Microsoft Visual C++ 6.0 MCSD Training Kit
    ISBN: 0735607958
    EAN: 2147483647
    Year: 1999
    Pages: 95

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net