Creating Custom Content Handlers
Using content handlers you can redirect a request to a TContentBase descendant class. This class is responsible for providing the actual content of the response. Content handlers are not components. They are lightweight classes and should be created at runtime.
Creating a new TContentHandler
Creating a new TContentHandler class is very simple. This how-to will show you how to create a new content handler to respond with a XML document.
1) Create a new IntraWeb Stand Alone server using the IntraWeb project wizard. Then create a new unit, name it IW.Content.XML and add this code to it:
unit IW.Content.XML; interface uses Classes, IW.Content.Base, HTTPApp, IWApplication, IW.HTTP.Request, IW.HTTP.Reply; type TContentXML = class(TContentBase) protected function Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication): boolean; override; public constructor Create; override; end; implementation uses IW.Content.Handlers, IWMimeTypes; constructor TContentXML.Create; begin inherited; mFileMustExist := False; end; function TContentXML.Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication): boolean; begin Result := True; if Assigned(aReply) then begin aReply.ContentType := MIME_XML; aReply.WriteString('<xml>My xml content here</xml>'); end; end; initialization end.
3) Still in your ServerController unit, add this code to the initialization section:
initialization THandlers.Add('', 'GiveMeSomeXML', TContentXML.Create);
4) Now build and run your application. Open your browser and type this URL: http://127.0.0.1:8888/GiveMeSomeXML (note that the port may differ). You will see something like that:
First, we created a new TContentBase descendant class. Every custom content handler must descend from this class. Inside the Create() method, we must set mFileMustExist to FALSE. When TRUE, the TContentBase.Execute() method will search for this file and if it is not found, will reply with HTTP code 404.
Then, all we have to do here is override the TContentBase.Execute() method, and write directly to the aReply object instance. The first thing we did was setting the aReply.ContentType property. This actually changes the Content-Type HTTP header field in our response. In this case, we want to reply with a real XML (and not a XML string inside a HTML), so we use one of the predefined constants in IWMimeTypes unit.
Then, we write a XML directly to the aReply instance, using one of its methods, and we are done.
How powerful is that? You can create TContentBase descendants to handle any kind of request. You can also create an Indy client to post requests to your IntraWeb application implementing a custom protocol and messaging system. The possibilities are infinite.
Starting in IntraWeb 14.0.13, you can also use content handlers to respond to Search Engine requests. If you have an IntraWeb application visible to the internet, web crawlers like googlebot will certainly visit your application. When a web crawler posts a request to your IntraWeb application, you may use a content handler to respond with the content you want to be indexed. In this case, you should set the following ServerController properties:
procedure TIWServerController.IWServerControllerBaseConfig(Sender: TObject); begin // Tell IntraWeb to redirect SearchEngine requests to some ContentHandler SearchEngineOptions.RedirectToContentHandler := True; // in this case, you must create a TContentBase descendant and add it to THandlers // using 'SearchEngineRequest' as the document path SearchEngineOptions.ContentHandlerPath := 'SearchEngineRequest'; end;
A fully functional demo containing this code can be found in our GitHub repository.