1. Computing
Send to a Friend via Email
RTL reference|Glossary|Tips/Tricks|FREE App/VCL|Best'O'Net|Books|Link To

ISAPI tutorial for Delphi developers
Page 14: Database enabled applications - Part 2
More of this Feature
Pg 1: Intro to web-broker
Pg 2: Using this tutorial
Pg 3: Getting started
Pg 4: Web Actions
Pg 5: The first ISAPI app
Pg 6: TWebRequestObject
Pg 7: Request-responding
Pg 8: TPageProducers
Pg 9: Cookies made easy
Pg 10: Stateless HTTP
Pg 11: DB enabled apps
Pg 12: FAQ
Pg 13: DB apps - Part 1
Pg 15: DB apps - Part 3
Join the Discussion
"Post your questions, concerns, views and comments to this article..."
Related Resources
Internet programming
CGI and ISAPI with Delphi

This is going to be a client database over the Internet. This means that any one with a browser and an Internet connection, with no need for additional software can add, delete, modify and view information. This gives great power and it brings with it some security issues. I am going to explain a way so that only certain people that have access can do this. Of course, the security I am going to employ is quite simple, you can extend it as much as you want to provide additional security (restrict by IP, SSL, etc).

As we've seen in the chapter covering PageProducers, the HTMLFile property assigns an HTML file to the PageProducer. This file can be located anywhere on your machine as long as the IUSR_MACHINENAME user has read access to the file at NTFS level (considering you are using NT as your server. If you are not, then you shouldn't really worry about security issues with your ISAPI application as Windows 95, 98 doesn't have any other means of security anyway....so just open yourself up to the whole world ).

We are going to make use of this feature combined with the use of cookies to restrict access to certain parts of the application. First of all, let's start with the boring part of making the HTML pages. These pages are located (by default) in the source directory of this chapter. On deployment, you could move these to any directory on your server that is not in a public location (e.g. inetpub\wwwroot) and somewhere where IUSR_MACHINENAME has read access to.

The files you should be looking at up to this point are: menu.htm

This last one (login.htm) on the contrary, should be located in the public directory where your web-server points to. This page will be used for the user to input his/her login information so that we can verify his credential. Your directory structure should look something like this: C:\ApplicationPrivateFiles: (only with read permission for IUSR_MACHINENAME).

and contains:


C:\inetpub\wwwroot: (public location for web-server)

and contains:


In the BeforeDispatch, we are going to examine the PathInfo to see what petition is being made (action requested). Depending on whether this value is public access or restricted we take the appropriate action. If it is a restricted action we check to see if the cookie we set when the user has logged in is present. If not we know that the user has not yet logged in. Since there is only one public action (login), we check to see if it is this, if not then we respond indicating that there was an invalid request (thus "over-riding" the default action we made in part 1).

 Check to see what action is asked for.
 If it is a restricted action then check
 for credential (cookie is present)

if ( Request.PathInfo = '/action' ) or
   (Request.PathInfo = '/page')
    then begin
        // Restricted-access
  if (Request.CookieFields.Values['Cookie'] =
      'CLIENT_DATABASE') then // has access 
    // We Set handled to false and let
        // the appropriate action take it's course 
    Handled := False 
  else begin
   Response.Content := 'Unauthorized access'; 
   Handled := True ;
end else
 if (Request.PathInfo = '/login') then 
  Handled := False // Login page. Public. Allow user in. 
 else begin 
  // This will over-ride the default 
  // action. DEFAULT will never be used 
  Response.Content := 'Invalid Request'; 
  Handled := True ; 
end ;

This action verifies that the user has introduced his/her correct login information. If so, it then places a cookie that will be later verified by the BeforeDispatch event. The cookie also holds the ID entry of the user. In this example we might not need this ID at all, but I'm placing it so that if you ever need information regarding the user, all you need to do is query the USER_LIST table given the ID and retrieve the necessary information.

Since most of the code has been explained in previous chapters, I won't go into details. The only really new thing is the Stored Procedure that checks to see if the user is valid. If the username/password is correct it then responds with the user's ID. All user ID's are greater or equal to zero, so if the user does not exist or the combination is incorrect it will return -1.

The "Page" action
Since the pages to access the application are in a private location (as intended), we need some way to access them. This is why we are going to create an action that returns a page requested. For example, before we can add a new record to the database we need to see the html form where we can fill in the information.

The BeforeDispatch event takes care of the security issues, so in our "Page" action all we need to do is to return the requested page that will be indicated by the "target" parameter (look at the source code for the menu.htm file). If you look at the code for this action you will see that it is very simple:

Note that the path to the private files is hard-coded. Other ways to do it is either using constants (but still would be coded) or use a INI file of some sort that would read the values from a the file in the OnCreate and store them in a global variable (remember, it would be ok since it would be a read-only variable). You could then easily change the paths without the need to re-compile.

Try calling this action without logging in first and see the result:. If you debug, you will see that it doesn't even get to the Page action. The BeforeDispatch takes care of it.

As you can see also, the errors and pages i've generating aren't what you could say the best or nicest. This is all for demonstration purposes and the error messages could be replaced with something more friendlier and less explicit!

The "Action" action
This is where it all takes place. First I want to start off by saying that normally I don't use strings as the target of the actions (i.e. AddRecord, DeleteRecord, etc). I prefer to use number in which case the whole lot of "if's" could be replaced by a much faster "case" sentence. However, so as not to be confused by numbers I thought it best to be explicit and use text to indicate exactly what action is going to be performed. In this part of Chapter 11 we will only focus on the "addrecord" target.

We call the function "AddRecord", which reads the contents of the form, creates an SQL instruction and executes it. If no exception is raised then it returns an 'OK' , otherwise it returns the message of the exception. Notice that there is no need to pass the Request.ContentFIelds as a parameter to the function since the current Request property of the web-module is instantiated with the current contents of the current request.

This was very easy. Examine the code carefully and make sure you understand everything before you proceed to the next part of this chapter.

Next page > Database enabled applications - Part 3 > Page 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

All graphics (if any) in this feature created by Zarko Gajic.

More Delphi
· Learn another routine every day - RTL Quick Reference.
· Download free source code applications and components.
· Talk about Delphi Programming, real time.
· Link to the Delphi Programming site from your Web pages.
· Tutorials, articles, tech. tips by date: 2001|2000|1999|1998 or by TOPIC.
· NEXT ARTICLE: ADO Cursors - DB/10.
Chapter ten of the free Delphi Database Course for beginners. How ADO uses cursors as a storage and access mechanism, and what you should do to choose the best cursor for your Delphi ADO application.
Stay informed with all new and interesting things about Delphi (for free).
Subscribe to the Newsletter

Got some code to share? Got a question? Need some help?

©2014 About.com. All rights reserved.