THTTPServer
Last Updated: 01/27/2007

Frequently Asked Questions for THTTPServer:

     
  1. 401 Message string 
  2. Authorisation 
  3. Cookies 
  4. Cookies 
  5. Performance degrades if using threads 
  6. Refresh a page 
  7. Reusing sockets 
  8. Security vulnerability 
  9. Threads 
  10. THTTPServer Upload Progress 

[Back to Main]













  
401 Message string
Gabi Slonto buffne01@gmx.net    
21/04/2003

How to define the message string in a 401 (logon) dialog which restrict the directory

You have to add "This string (eg.: private server)" (the quotation marks have to be there) into the dialog.

example:

procedure TMain.Answer401(Remote: TClient);
var
   BodyStr : String;
   Stream : TMemoryStream;
begin
   BodyStr := '<html><head><title>Unauthorized</title></head>' +
              '<font size="2" face="Arial, Helvetica, sans-serif">' +
              '<body><B>Error 401</B><br><br>' +
              'You are not authorized to use this resource.' +
              '</font></body></html>';
   BodyStr := Remote.Version +
              ' 401 Unauthorized'#13#10 +
              'Content-Type: text/html'#13#10 +
              'Content-Length: ' + IntToStr(Length(BodyStr)) + #13#10 +
              'WWW-Authenticate: Basic Realm=' + cYourRestrictionArea
              + #13#10#13#10 + BodyStr;
              //Remote.Path + #13#10#13#10 + BodyStr;

   Stream := TMemoryStream.Create;
   Stream.Write(BodyStr[1], Length(BodyStr));
   Stream.Seek(0, 0);
   Remote.DocStream := Stream;
   Remote.SendStream;
end;



 
[Return to Top]

  
Authorisation
DZ dz@caribe.net    
27/10/2004

1. Browser submits a GET request for the document to the server.

2. Server checks checks the permissions of the document and if access is restricted, it returns with an HTTP error of "401 Authorization Required", along with some information on the credentials required, i.e. the authentication type and the "realm" to which it belongs.  This last one is useful so that the browser can continue issuing the same username/password for documents belonging to the same realm instead of having to request them from the user every time.

3. When the browser receives this error, it does not fail, but pops up a dialog box requesting the username and password from the user.  The browser then uses these to generate an authentication hash and resubmits the request -- this time with a new header, "Authorization:" containing the hash.

4. The server validates this hash and decides weather to grant access or not.  If access is granted, the server returns the document requested.  If not, an HTTP error of "403 Access Denied" is returned.

5. From then on, every time that the user requests a document within the same realm, it will automatically submit the hash instead of asking the user for a username and password -- at least until the session is ended (the browser is closed).

Below is a brief excerpt of a server/client communication, requesting a protected document from a web site:

--- Client said...
GET /protected.html HTTP/1.1
Host: techunlimited.net
User-Agent: ...
...

--- Server said...
HTTP/1.x 401 Authorization Required
WWW-Authenticate: Basic realm="Protected Area"
...

*** AT THIS POINT THE BROWSER ASKS FOR USERNAME/PASSWORD
*** WITHOUT DISPLAYING THE ERROR RETURNED FROM THE SERVER.

--- Client said...
GET /protected.html HTTP/1.1
Host: techunlimited.net
Authorization: Basic ZHo6Zm9va2E=
...

--- Server said...
HTTP/1.x 200 OK
Content-Type: text/html
...

 
[Return to Top]

  
Cookies
Francois PIETTE francois.piette@overbyte.be    
26/10/2001

> Can I use cookies using THttpServer ?
> I need to get password from user and send cookie to him.
> If I can't, is there are some other user recognition methods ?


Cookies are just ordinary header lines. Handle them as any other header.

 
[Return to Top]

  
Cookies
Francois Piette francois.piette@overbyte.be    
22/12/2002


To send a cookie from server side, you just add a "Set-cookie:" line to the header answer like this:

Set-Cookie: FastreamCookie=123; path=/; expires=Sun, 13-Oct-2002 18:45:13 GMT

When server receive a cookie back from a client, it is in a "Cookie:" line like this:

Cookie: FastreamCookie=123; OtherCookie=Hello

 
[Return to Top]

  
Performance degrades if using threads
Francois Piette francois.piette@overbyte.be    
17/02/2004


 If I use the example provided in ICS, and I up the number of threads to 16 (instead of 6), I can only get a fairly low number of hits per second (about 21 hits/sec) even against very fast web servers (such as google.com).  Seamingly, it makes no difference if I use 8 or 16 threads--there's no improvement.  And when I go higher, 32 threads, the performance actually DEGRADES.


 Using a thread for each connection is defenitely _NOT_ the right way to achieve the best performance/thruput. Use asynchronous programming (events) within a thread for 10-100 connections depending on your CPU and RAM.

Microsoft recommand having less than 16 threads per application. Too much threads mean the system spend more time switching between thread that doing actual processing.

 
[Return to Top]

  
Refresh a page
Wilfried Mestdagh wilfried@mestdagh.biz    
29/07/2001

> I want to refresh a page at certain time intervals

 I found this on http://wsabstract.com

 Description: This script (perceptually) refreshes a webpage, after the specified amount of time. "Why use JavaScript to do that, when I could accomplish the same thing using the <meta http-equi='refresh'> tag?", you ask. Simple. Because that tag certainly won't display in the scroll bar the time remaining until the page refreshes, as with this script!

 <script> <!--

 /*
    Auto Refresh Page with Time script
    By Website Abstraction (wsabstract.com)
    Over 200+ free scripts here!
 */

 // enter refresh time in "minutes:seconds" Minutes should range from 0 to
 // inifinity. Seconds should range from 0 to 59
 var limit="0:30"


 if (document.images)
 {
    var parselimit = limit.split(":")
    parselimit = parselimit[0] * 60 + parselimit[1] * 1 
 }

 function beginrefresh()
 {
    if (!document.images)
       return
    if (parselimit == 1)
       window.location.reload()
    else
    {
       parselimit -= 1
       curmin=Math.floor(parselimit / 60)
       cursec = parselimit % 60
       if (curmin != 0)
          curtime = curmin + " minutes and " + cursec + " seconds left until page refresh!"
       else
          curtime = cursec + " seconds left until page refresh!"
       window.status = curtime
       setTimeout("beginrefresh()", 1000)
    }
 }

 window.onload = beginrefresh
 //-->
 </script>


 
[Return to Top]

  
Reusing sockets
Francois Piette francois.piette@overbyte.be    
12/05/2005

My HTTP server is getting lots of connections because clients do a real time updating of database every 5 seconds, but I notice there are many TIME_WAIT sockets.

This is how sockets are working.
If you use Windows, have a look at this article: 
http://www.winguides.com/registry/display.php/878/

 
[Return to Top]

  
Security vulnerability
Francois Piette francois.piette@overbyte.be    
22/12/2002

I have just noticed that the ICS web server demo and all unpathced software based on THttpServer are subject to a path security exploit. Here it is:

1) Setup ICS web server to a non-root document root like d:\fastream
2) Put a file called index.htm to d:\
3) Run the server
4) Enter http://localhost/../index.htm and you break the document root!


This is by design, not a bug. It is a feature you can easily disable. Here some suggested code (to put in the OnGetDocument) which absolutize a path to get rid of '..\' and '.\' in path names and make sure the resulting path point the a directory below DocDir:

    SetLength(DocPath, 256);
    DocPathLen := GetFullPathName(PChar(ClientCnx.Document), 255,
                                  PChar(DocPath), FilePart);
    SetLength(DocPath, DocPathLen);
    Display('DocPath = "' + DocPath + '"');
    DocDir := Copy(DocPath, 1, Length(HttpServer1.DocDir) + 1);

    if CompareText(DocDir, HttpServer1.DocDir + '\') <> 0 then begin
        Flags := hg404;
        Display(Who + 'Permission denied to "' + DocPath + '"');
        Exit;
    end;



 
[Return to Top]

  
Threads
Francois Piette francois.piette@overbyte.be    
22/12/2002

Can I set threads for HTTPServ

Yes, you can. The principle is to create a class derived from THttpConnection (let's call it TMyHttpConnection) and give this class to the Http server component thru his ClientClass property. Then HTTP server component will instanciate YOUR class for each client which connect.

In your TMyHttpConnection, you can start a thread to execute the client requests. Do that for example in OnGetDocument event by calling a method in your TMyHttpConnection. Let's call this method CreateVirtualDoc. You must set Flags  := hgWillSendMySelf; so that the HTTP comopnet will not do anything else to send the answer to client.

CreateVirtualDoc will just start a thread. The thread's Execute method will prepare a TMemoryStream with the dynamic page content. When done, the thread gives the stream to TMyHttpConnection.DocStream (don't destroy the stream !) and post a custom message using PostMessage to TMyHttpConnection class. In the handler your this custom message, you just call SendStream.  After posting the message, your thread simply terminate.

The custom message is necessary to make sending the dynamic page content by HttpServer thread instead of the worker thread you created.

You must use a TCriticalSection to access common data between thread and TMyHttpConnection. And be aware that by the time the thread terminate, it is well possible that TMyHttpConnection is destroyed because client disconnected without waiting for the reply ! So take care in the destructor to clear the thread. And take care from the thread to not use a reference to a destroyed component.

 
[Return to Top]

  
THTTPServer Upload Progress
Fastream Technologies fastream@fastream.com    
14/01/2006

I'm developing a program which allows files to be downloaded from client to client. This is achieved by using a THttpCli and a THttpServer. I can track the download progress of the THttpCli fine - but how can I track the *uploading* of a file from the THttpServer?

To see the progress of uploads in HTTP server, you need to override
ConnectionDataSent in THttpConnection class.

 
[Return to Top]

   

The ICS FAQ is created and maintained by the ICS VIP Documentation Effort Group.
For more information on how to join our efforts, send email to:
[ICS FAQ]