How to log in in JSON or XML-RPC?

  1. try to not raise exception. in this event you can manually write server response into aResponseStream.
  2. 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:

  1. The streams are empty, i.e. aResponseStream.Size = 0 and aRequestStream.Size = 0

What should they contain!?

  1. 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! :wink: 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? :slight_smile:

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! :smiley: