Using OnCustomResponseEvent in a ROSDK Server

example for plain HTTPServer.OnCustomResponseEvent.
This snippet shows how to handle unknown requests or requests with incomplete data.
TROPostMessage was used

procedure TServerMainForm.ROServerCustomResponseEvent(
  const aTransport: IROHTTPTransport; const aRequestStream,
  aResponseStream: TStream; const aResponse: IROHTTPResponse;
  var aHandled: Boolean);
var
  lMessage:  IROMessage;
  op: TROResponseOptions;
  s: AnsiString;
begin
  // handle all requests started with 'xxxx':
  if pos('/xxxx',aTransport.PathInfo) = 1 then begin  // "xxxx" shouldn't be defined in Server.Dispathers
    
   //1. Pre-processing data 
{ 
   // * extracting data if GET method was used
   s := aTransport.QueryString;
    
  // * extracting data if POST method was used
    SetLength(s, aRequestStream.Size);
    aResponseStream.Position := 0;
    aRequestStream.Read(Pointer(s)^, Length(s));

   // modify data in some way
    s := '__MessageType=Message&__InterfaceName=MyService&'+s;

   // write updated data back to stream
    aRequestStream.Size := 0;
    aRequestStream.Write(Pointer(s)^, Length(s));
}
    // 2. Invoke service method 
    lMessage:= (ROPOSTMessage as IROMessageCloneable).Clone;
    MainProcessMessage(lMessage,atransport,aRequestStream,aResponseStream,op);

    //3. Post-processing data
{    SetLength(s, aResponseStream.Size);
    aResponseStream.Read(Pointer(s)^, Length(s));

    // modify data again
    s := s + my_some_data;

    aResponseStream.Size := 0;
    aResponseStream.Write(Pointer(s)^, Length(s));
}
    aHandled := True;
  end;
end;
3 Likes

One question about this snippet above: If i get this right i have to use only a TROHTTPServer without TROHttpApiDispatcher and without any TROMessage?

If i try this an debug this event using my browser with url http://localhost:8443/lpr/ everything ist empty except PathInfo and ClientAddress. How could one get the other infos like is it a get/post request and so on?

Hi,

not yet. However this event is fired if request wasn’t processed by Messages or HttpApiDispatcher.

this is correct. your browser doesn’t fill another info. try to use CURL.
in CURL request you can provide another info
for example:

curl -X POST "http://localhost:8099/xxxx/readme" -H  "accept: application/json" -H  "content-type: application/json" -d "{    \"Address1\": \"123 Main St\",    \"Address2\": \"STE B\",    \"City\": \"New York\",    \"State\": \"NY\",    \"ZipCode\": \"10025\"  }"

Hi Evgeny,
could you please update your 7 years old code above. I can’t even compile it because of unknown ROPOSTMessage. Furthermore i don’t really understand what to do. I have mainly rest GET requests where i have to respond as XML. And also some POST pequests with i have to answer also with an XML Response.

I don’t understand why and in what case i have to modify the RequestStream? could you create a small example with a GET and a POST request please? I would highly appreciate it.
Thanks
Werner

Delphi 11.1 / RO 10.0.0.1537

this is component on form

ROPOSTMessage: TROPOSTMessage;

because this sample uses TROPostMessage.

check related threads. they contain examples for HttpApi and another types of messages.


some users want to update RequestStream and add extra data/parameter.
you can ignore Pre-processing data section if you don’t it.


above example already contains it.

   if (aTransport as IROHTTPRequest).GetMethod = 'GET' then begin
     // s: AnsiString;
     s := aTransport.QueryString;
     aRequestStream.Size := 0;
     aRequestStream.Write(Pointer(s)^, Length(s));
   end;
   if (aTransport as IROHTTPRequest).GetMethod = 'POST' then begin
     // no changed is needed, request stream is already in aRequestStream
   end;

Thanks Evgeny, last question. Where can i set the http request result error state? I have set it to 500 in any error case.

Hi,

use the IROHTTPResponse.Code property:

aResponse.Code := 500;