- try to not raise exception. in this event you can manually write server response into
aResponseStream
. - have you saw that snippet? you need to put your error into
aResponseStream
.
Hi Evgeny,
so, I have tried to change the stream, but I have following issues:
- The streams are empty, i.e.
aResponseStream.Size = 0
andaRequestStream.Size = 0
What should they contain!?
- I have tried to write on this way:
> procedure TMyROIndyHTTPServer.OnCustomResponseEvent(const aTransport: IROHTTPTransport; const aRequestStream, > aResponseStream: TStream; const aResponse: IROHTTPResponse; var aHandled: Boolean); > var > lMessage: IROMessage; > op: TROResponseOptions; > s: AnsiString; > begin > // * 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 := 'Status: 401 '+HTTP_401_status+s; // <---- I DON'T THINK THIS IS CORECCT. COULD YOU HELP ME HERE WITH THE CODE?
> // write updated data back to stream > aRequestStream.Size := 0; > aRequestStream.Write(Pointer(s)^, Length(s));
> // lMessage:= (FJSONMessage as IROMessageCloneable).Clone; // <--- WHAT KIND OF MESSAGE SHOULD I PROVIDE HERE?! I am working in my server with BIN, JSON and XML. How do I find out which message is triggered by client?! > // MainProcessMessage(lMessage,atransport,aRequestStream,aResponseStream,op);
> aHandled := True; > end;
Please see my questions in the formatted code!
you can use something like
procedure TMyROIndyHTTPServer.OnCustomResponseEvent(const aTransport: IROHTTPTransport; const aRequestStream,
aResponseStream: TStream; const aResponse: IROHTTPResponse; var aHandled: Boolean);
const
sJsonError: AnsiString = '{"version":"1.1","error":{"name":"JsonRPCError","code":"401","message":"Error"}}';
var
lMessage: IROMessage;
op: TROResponseOptions;
s: AnsiString;
lMyMessage: TROMessage;
begin
if pos('/xjson',aTransport.PathInfo) = 1 then lMyMessage := ROJSONMessage1
else if pos('/xbin',aTransport.PathInfo) = 1 then lMyMessage := ROBinMessage1
else ....
lMessage:= (lMyMessage as IROMessageCloneable).Clone;
try
MainProcessMessage(lMessage,atransport,aRequestStream,aResponseStream,op);
except
on E: MyError do begin
aResponse.Code := HTTP_401_code;
aResponse.Status := HTTP_401_status;
if lMyMessage = ROJSONMessage1 then
aResponseStream.Write(sJsonError[1], Length(sJsonError) * SizeOf(AnsiChar));
else
.....
end;
on E: Exception do raise;
end;
aHandled := True;
end;
Note: may contains typo
Your code works almost perfect! The problem is that my custom exception from a Service-RODataModule is catched and handled somewhere in MainProcessMessage(…). So, on E: MyError do begin
can’t be reached, it goes directly to aHandled := True;
Some workaround for that?
you can create a replica of MainProcessMessage
and handle exception in OnCustomResponseEvent
instead of
Okay, I will try it out!
But! Evgeny, thanks a lot for your prompt and helpful answers!
I know now much more then I wanted to know originally!