THTTPServer Last Updated: 01/27/2007 |
Frequently Asked Questions for THTTPServer:
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; |
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 ... |
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. |
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 |
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. |
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> |
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/ |
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; |
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. |
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. |